xref: /dflybsd-src/contrib/gdb-7/bfd/elf.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* ELF executable support for BFD.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright 1993-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of BFD, the Binary File Descriptor library.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program; if not, write to the Free Software
195796c8dcSSimon Schubert    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
205796c8dcSSimon Schubert    MA 02110-1301, USA.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert 
235796c8dcSSimon Schubert /*
245796c8dcSSimon Schubert SECTION
255796c8dcSSimon Schubert 	ELF backends
265796c8dcSSimon Schubert 
275796c8dcSSimon Schubert 	BFD support for ELF formats is being worked on.
285796c8dcSSimon Schubert 	Currently, the best supported back ends are for sparc and i386
295796c8dcSSimon Schubert 	(running svr4 or Solaris 2).
305796c8dcSSimon Schubert 
315796c8dcSSimon Schubert 	Documentation of the internals of the support code still needs
325796c8dcSSimon Schubert 	to be written.  The code is changing quickly enough that we
335796c8dcSSimon Schubert 	haven't bothered yet.  */
345796c8dcSSimon Schubert 
355796c8dcSSimon Schubert /* For sparc64-cross-sparc32.  */
365796c8dcSSimon Schubert #define _SYSCALL32
375796c8dcSSimon Schubert #include "sysdep.h"
385796c8dcSSimon Schubert #include "bfd.h"
395796c8dcSSimon Schubert #include "bfdlink.h"
405796c8dcSSimon Schubert #include "libbfd.h"
415796c8dcSSimon Schubert #define ARCH_SIZE 0
425796c8dcSSimon Schubert #include "elf-bfd.h"
435796c8dcSSimon Schubert #include "libiberty.h"
445796c8dcSSimon Schubert #include "safe-ctype.h"
45*ef5ccd6cSJohn Marino #include "elf-linux-psinfo.h"
465796c8dcSSimon Schubert 
47cf7f2e2dSJohn Marino #ifdef CORE_HEADER
48cf7f2e2dSJohn Marino #include CORE_HEADER
49cf7f2e2dSJohn Marino #endif
50cf7f2e2dSJohn Marino 
515796c8dcSSimon Schubert static int elf_sort_sections (const void *, const void *);
525796c8dcSSimon Schubert static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
535796c8dcSSimon Schubert static bfd_boolean prep_headers (bfd *);
545796c8dcSSimon Schubert static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
555796c8dcSSimon Schubert static bfd_boolean elf_read_notes (bfd *, file_ptr, bfd_size_type) ;
565796c8dcSSimon Schubert static bfd_boolean elf_parse_notes (bfd *abfd, char *buf, size_t size,
575796c8dcSSimon Schubert 				    file_ptr offset);
585796c8dcSSimon Schubert 
595796c8dcSSimon Schubert /* Swap version information in and out.  The version information is
605796c8dcSSimon Schubert    currently size independent.  If that ever changes, this code will
615796c8dcSSimon Schubert    need to move into elfcode.h.  */
625796c8dcSSimon Schubert 
635796c8dcSSimon Schubert /* Swap in a Verdef structure.  */
645796c8dcSSimon Schubert 
655796c8dcSSimon Schubert void
_bfd_elf_swap_verdef_in(bfd * abfd,const Elf_External_Verdef * src,Elf_Internal_Verdef * dst)665796c8dcSSimon Schubert _bfd_elf_swap_verdef_in (bfd *abfd,
675796c8dcSSimon Schubert 			 const Elf_External_Verdef *src,
685796c8dcSSimon Schubert 			 Elf_Internal_Verdef *dst)
695796c8dcSSimon Schubert {
705796c8dcSSimon Schubert   dst->vd_version = H_GET_16 (abfd, src->vd_version);
715796c8dcSSimon Schubert   dst->vd_flags   = H_GET_16 (abfd, src->vd_flags);
725796c8dcSSimon Schubert   dst->vd_ndx     = H_GET_16 (abfd, src->vd_ndx);
735796c8dcSSimon Schubert   dst->vd_cnt     = H_GET_16 (abfd, src->vd_cnt);
745796c8dcSSimon Schubert   dst->vd_hash    = H_GET_32 (abfd, src->vd_hash);
755796c8dcSSimon Schubert   dst->vd_aux     = H_GET_32 (abfd, src->vd_aux);
765796c8dcSSimon Schubert   dst->vd_next    = H_GET_32 (abfd, src->vd_next);
775796c8dcSSimon Schubert }
785796c8dcSSimon Schubert 
795796c8dcSSimon Schubert /* Swap out a Verdef structure.  */
805796c8dcSSimon Schubert 
815796c8dcSSimon Schubert void
_bfd_elf_swap_verdef_out(bfd * abfd,const Elf_Internal_Verdef * src,Elf_External_Verdef * dst)825796c8dcSSimon Schubert _bfd_elf_swap_verdef_out (bfd *abfd,
835796c8dcSSimon Schubert 			  const Elf_Internal_Verdef *src,
845796c8dcSSimon Schubert 			  Elf_External_Verdef *dst)
855796c8dcSSimon Schubert {
865796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vd_version, dst->vd_version);
875796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
885796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
895796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
905796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
915796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
925796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vd_next, dst->vd_next);
935796c8dcSSimon Schubert }
945796c8dcSSimon Schubert 
955796c8dcSSimon Schubert /* Swap in a Verdaux structure.  */
965796c8dcSSimon Schubert 
975796c8dcSSimon Schubert void
_bfd_elf_swap_verdaux_in(bfd * abfd,const Elf_External_Verdaux * src,Elf_Internal_Verdaux * dst)985796c8dcSSimon Schubert _bfd_elf_swap_verdaux_in (bfd *abfd,
995796c8dcSSimon Schubert 			  const Elf_External_Verdaux *src,
1005796c8dcSSimon Schubert 			  Elf_Internal_Verdaux *dst)
1015796c8dcSSimon Schubert {
1025796c8dcSSimon Schubert   dst->vda_name = H_GET_32 (abfd, src->vda_name);
1035796c8dcSSimon Schubert   dst->vda_next = H_GET_32 (abfd, src->vda_next);
1045796c8dcSSimon Schubert }
1055796c8dcSSimon Schubert 
1065796c8dcSSimon Schubert /* Swap out a Verdaux structure.  */
1075796c8dcSSimon Schubert 
1085796c8dcSSimon Schubert void
_bfd_elf_swap_verdaux_out(bfd * abfd,const Elf_Internal_Verdaux * src,Elf_External_Verdaux * dst)1095796c8dcSSimon Schubert _bfd_elf_swap_verdaux_out (bfd *abfd,
1105796c8dcSSimon Schubert 			   const Elf_Internal_Verdaux *src,
1115796c8dcSSimon Schubert 			   Elf_External_Verdaux *dst)
1125796c8dcSSimon Schubert {
1135796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vda_name, dst->vda_name);
1145796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vda_next, dst->vda_next);
1155796c8dcSSimon Schubert }
1165796c8dcSSimon Schubert 
1175796c8dcSSimon Schubert /* Swap in a Verneed structure.  */
1185796c8dcSSimon Schubert 
1195796c8dcSSimon Schubert void
_bfd_elf_swap_verneed_in(bfd * abfd,const Elf_External_Verneed * src,Elf_Internal_Verneed * dst)1205796c8dcSSimon Schubert _bfd_elf_swap_verneed_in (bfd *abfd,
1215796c8dcSSimon Schubert 			  const Elf_External_Verneed *src,
1225796c8dcSSimon Schubert 			  Elf_Internal_Verneed *dst)
1235796c8dcSSimon Schubert {
1245796c8dcSSimon Schubert   dst->vn_version = H_GET_16 (abfd, src->vn_version);
1255796c8dcSSimon Schubert   dst->vn_cnt     = H_GET_16 (abfd, src->vn_cnt);
1265796c8dcSSimon Schubert   dst->vn_file    = H_GET_32 (abfd, src->vn_file);
1275796c8dcSSimon Schubert   dst->vn_aux     = H_GET_32 (abfd, src->vn_aux);
1285796c8dcSSimon Schubert   dst->vn_next    = H_GET_32 (abfd, src->vn_next);
1295796c8dcSSimon Schubert }
1305796c8dcSSimon Schubert 
1315796c8dcSSimon Schubert /* Swap out a Verneed structure.  */
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert void
_bfd_elf_swap_verneed_out(bfd * abfd,const Elf_Internal_Verneed * src,Elf_External_Verneed * dst)1345796c8dcSSimon Schubert _bfd_elf_swap_verneed_out (bfd *abfd,
1355796c8dcSSimon Schubert 			   const Elf_Internal_Verneed *src,
1365796c8dcSSimon Schubert 			   Elf_External_Verneed *dst)
1375796c8dcSSimon Schubert {
1385796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vn_version, dst->vn_version);
1395796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
1405796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vn_file, dst->vn_file);
1415796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
1425796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vn_next, dst->vn_next);
1435796c8dcSSimon Schubert }
1445796c8dcSSimon Schubert 
1455796c8dcSSimon Schubert /* Swap in a Vernaux structure.  */
1465796c8dcSSimon Schubert 
1475796c8dcSSimon Schubert void
_bfd_elf_swap_vernaux_in(bfd * abfd,const Elf_External_Vernaux * src,Elf_Internal_Vernaux * dst)1485796c8dcSSimon Schubert _bfd_elf_swap_vernaux_in (bfd *abfd,
1495796c8dcSSimon Schubert 			  const Elf_External_Vernaux *src,
1505796c8dcSSimon Schubert 			  Elf_Internal_Vernaux *dst)
1515796c8dcSSimon Schubert {
1525796c8dcSSimon Schubert   dst->vna_hash  = H_GET_32 (abfd, src->vna_hash);
1535796c8dcSSimon Schubert   dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
1545796c8dcSSimon Schubert   dst->vna_other = H_GET_16 (abfd, src->vna_other);
1555796c8dcSSimon Schubert   dst->vna_name  = H_GET_32 (abfd, src->vna_name);
1565796c8dcSSimon Schubert   dst->vna_next  = H_GET_32 (abfd, src->vna_next);
1575796c8dcSSimon Schubert }
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert /* Swap out a Vernaux structure.  */
1605796c8dcSSimon Schubert 
1615796c8dcSSimon Schubert void
_bfd_elf_swap_vernaux_out(bfd * abfd,const Elf_Internal_Vernaux * src,Elf_External_Vernaux * dst)1625796c8dcSSimon Schubert _bfd_elf_swap_vernaux_out (bfd *abfd,
1635796c8dcSSimon Schubert 			   const Elf_Internal_Vernaux *src,
1645796c8dcSSimon Schubert 			   Elf_External_Vernaux *dst)
1655796c8dcSSimon Schubert {
1665796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
1675796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
1685796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vna_other, dst->vna_other);
1695796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vna_name, dst->vna_name);
1705796c8dcSSimon Schubert   H_PUT_32 (abfd, src->vna_next, dst->vna_next);
1715796c8dcSSimon Schubert }
1725796c8dcSSimon Schubert 
1735796c8dcSSimon Schubert /* Swap in a Versym structure.  */
1745796c8dcSSimon Schubert 
1755796c8dcSSimon Schubert void
_bfd_elf_swap_versym_in(bfd * abfd,const Elf_External_Versym * src,Elf_Internal_Versym * dst)1765796c8dcSSimon Schubert _bfd_elf_swap_versym_in (bfd *abfd,
1775796c8dcSSimon Schubert 			 const Elf_External_Versym *src,
1785796c8dcSSimon Schubert 			 Elf_Internal_Versym *dst)
1795796c8dcSSimon Schubert {
1805796c8dcSSimon Schubert   dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
1815796c8dcSSimon Schubert }
1825796c8dcSSimon Schubert 
1835796c8dcSSimon Schubert /* Swap out a Versym structure.  */
1845796c8dcSSimon Schubert 
1855796c8dcSSimon Schubert void
_bfd_elf_swap_versym_out(bfd * abfd,const Elf_Internal_Versym * src,Elf_External_Versym * dst)1865796c8dcSSimon Schubert _bfd_elf_swap_versym_out (bfd *abfd,
1875796c8dcSSimon Schubert 			  const Elf_Internal_Versym *src,
1885796c8dcSSimon Schubert 			  Elf_External_Versym *dst)
1895796c8dcSSimon Schubert {
1905796c8dcSSimon Schubert   H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
1915796c8dcSSimon Schubert }
1925796c8dcSSimon Schubert 
1935796c8dcSSimon Schubert /* Standard ELF hash function.  Do not change this function; you will
1945796c8dcSSimon Schubert    cause invalid hash tables to be generated.  */
1955796c8dcSSimon Schubert 
1965796c8dcSSimon Schubert unsigned long
bfd_elf_hash(const char * namearg)1975796c8dcSSimon Schubert bfd_elf_hash (const char *namearg)
1985796c8dcSSimon Schubert {
1995796c8dcSSimon Schubert   const unsigned char *name = (const unsigned char *) namearg;
2005796c8dcSSimon Schubert   unsigned long h = 0;
2015796c8dcSSimon Schubert   unsigned long g;
2025796c8dcSSimon Schubert   int ch;
2035796c8dcSSimon Schubert 
2045796c8dcSSimon Schubert   while ((ch = *name++) != '\0')
2055796c8dcSSimon Schubert     {
2065796c8dcSSimon Schubert       h = (h << 4) + ch;
2075796c8dcSSimon Schubert       if ((g = (h & 0xf0000000)) != 0)
2085796c8dcSSimon Schubert 	{
2095796c8dcSSimon Schubert 	  h ^= g >> 24;
2105796c8dcSSimon Schubert 	  /* The ELF ABI says `h &= ~g', but this is equivalent in
2115796c8dcSSimon Schubert 	     this case and on some machines one insn instead of two.  */
2125796c8dcSSimon Schubert 	  h ^= g;
2135796c8dcSSimon Schubert 	}
2145796c8dcSSimon Schubert     }
2155796c8dcSSimon Schubert   return h & 0xffffffff;
2165796c8dcSSimon Schubert }
2175796c8dcSSimon Schubert 
2185796c8dcSSimon Schubert /* DT_GNU_HASH hash function.  Do not change this function; you will
2195796c8dcSSimon Schubert    cause invalid hash tables to be generated.  */
2205796c8dcSSimon Schubert 
2215796c8dcSSimon Schubert unsigned long
bfd_elf_gnu_hash(const char * namearg)2225796c8dcSSimon Schubert bfd_elf_gnu_hash (const char *namearg)
2235796c8dcSSimon Schubert {
2245796c8dcSSimon Schubert   const unsigned char *name = (const unsigned char *) namearg;
2255796c8dcSSimon Schubert   unsigned long h = 5381;
2265796c8dcSSimon Schubert   unsigned char ch;
2275796c8dcSSimon Schubert 
2285796c8dcSSimon Schubert   while ((ch = *name++) != '\0')
2295796c8dcSSimon Schubert     h = (h << 5) + h + ch;
2305796c8dcSSimon Schubert   return h & 0xffffffff;
2315796c8dcSSimon Schubert }
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert /* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
2345796c8dcSSimon Schubert    the object_id field of an elf_obj_tdata field set to OBJECT_ID.  */
2355796c8dcSSimon Schubert bfd_boolean
bfd_elf_allocate_object(bfd * abfd,size_t object_size,enum elf_target_id object_id)2365796c8dcSSimon Schubert bfd_elf_allocate_object (bfd *abfd,
2375796c8dcSSimon Schubert 			 size_t object_size,
238cf7f2e2dSJohn Marino 			 enum elf_target_id object_id)
2395796c8dcSSimon Schubert {
2405796c8dcSSimon Schubert   BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
2415796c8dcSSimon Schubert   abfd->tdata.any = bfd_zalloc (abfd, object_size);
2425796c8dcSSimon Schubert   if (abfd->tdata.any == NULL)
2435796c8dcSSimon Schubert     return FALSE;
2445796c8dcSSimon Schubert 
2455796c8dcSSimon Schubert   elf_object_id (abfd) = object_id;
246*ef5ccd6cSJohn Marino   if (abfd->direction != read_direction)
247*ef5ccd6cSJohn Marino     {
248*ef5ccd6cSJohn Marino       struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
249*ef5ccd6cSJohn Marino       if (o == NULL)
250*ef5ccd6cSJohn Marino 	return FALSE;
251*ef5ccd6cSJohn Marino       elf_tdata (abfd)->o = o;
2525796c8dcSSimon Schubert       elf_program_header_size (abfd) = (bfd_size_type) -1;
253*ef5ccd6cSJohn Marino     }
2545796c8dcSSimon Schubert   return TRUE;
2555796c8dcSSimon Schubert }
2565796c8dcSSimon Schubert 
2575796c8dcSSimon Schubert 
2585796c8dcSSimon Schubert bfd_boolean
bfd_elf_make_object(bfd * abfd)259c50c785cSJohn Marino bfd_elf_make_object (bfd *abfd)
2605796c8dcSSimon Schubert {
261c50c785cSJohn Marino   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2625796c8dcSSimon Schubert   return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
263c50c785cSJohn Marino 				  bed->target_id);
2645796c8dcSSimon Schubert }
2655796c8dcSSimon Schubert 
2665796c8dcSSimon Schubert bfd_boolean
bfd_elf_mkcorefile(bfd * abfd)2675796c8dcSSimon Schubert bfd_elf_mkcorefile (bfd *abfd)
2685796c8dcSSimon Schubert {
2695796c8dcSSimon Schubert   /* I think this can be done just like an object file.  */
270*ef5ccd6cSJohn Marino   if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
271*ef5ccd6cSJohn Marino     return FALSE;
272*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
273*ef5ccd6cSJohn Marino   return elf_tdata (abfd)->core != NULL;
2745796c8dcSSimon Schubert }
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert static char *
bfd_elf_get_str_section(bfd * abfd,unsigned int shindex)2775796c8dcSSimon Schubert bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
2785796c8dcSSimon Schubert {
2795796c8dcSSimon Schubert   Elf_Internal_Shdr **i_shdrp;
2805796c8dcSSimon Schubert   bfd_byte *shstrtab = NULL;
2815796c8dcSSimon Schubert   file_ptr offset;
2825796c8dcSSimon Schubert   bfd_size_type shstrtabsize;
2835796c8dcSSimon Schubert 
2845796c8dcSSimon Schubert   i_shdrp = elf_elfsections (abfd);
2855796c8dcSSimon Schubert   if (i_shdrp == 0
2865796c8dcSSimon Schubert       || shindex >= elf_numsections (abfd)
2875796c8dcSSimon Schubert       || i_shdrp[shindex] == 0)
2885796c8dcSSimon Schubert     return NULL;
2895796c8dcSSimon Schubert 
2905796c8dcSSimon Schubert   shstrtab = i_shdrp[shindex]->contents;
2915796c8dcSSimon Schubert   if (shstrtab == NULL)
2925796c8dcSSimon Schubert     {
2935796c8dcSSimon Schubert       /* No cached one, attempt to read, and cache what we read.  */
2945796c8dcSSimon Schubert       offset = i_shdrp[shindex]->sh_offset;
2955796c8dcSSimon Schubert       shstrtabsize = i_shdrp[shindex]->sh_size;
2965796c8dcSSimon Schubert 
2975796c8dcSSimon Schubert       /* Allocate and clear an extra byte at the end, to prevent crashes
2985796c8dcSSimon Schubert 	 in case the string table is not terminated.  */
2995796c8dcSSimon Schubert       if (shstrtabsize + 1 <= 1
3005796c8dcSSimon Schubert 	  || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL
3015796c8dcSSimon Schubert 	  || bfd_seek (abfd, offset, SEEK_SET) != 0)
3025796c8dcSSimon Schubert 	shstrtab = NULL;
3035796c8dcSSimon Schubert       else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
3045796c8dcSSimon Schubert 	{
3055796c8dcSSimon Schubert 	  if (bfd_get_error () != bfd_error_system_call)
3065796c8dcSSimon Schubert 	    bfd_set_error (bfd_error_file_truncated);
3075796c8dcSSimon Schubert 	  shstrtab = NULL;
3085796c8dcSSimon Schubert 	  /* Once we've failed to read it, make sure we don't keep
3095796c8dcSSimon Schubert 	     trying.  Otherwise, we'll keep allocating space for
3105796c8dcSSimon Schubert 	     the string table over and over.  */
3115796c8dcSSimon Schubert 	  i_shdrp[shindex]->sh_size = 0;
3125796c8dcSSimon Schubert 	}
3135796c8dcSSimon Schubert       else
3145796c8dcSSimon Schubert 	shstrtab[shstrtabsize] = '\0';
3155796c8dcSSimon Schubert       i_shdrp[shindex]->contents = shstrtab;
3165796c8dcSSimon Schubert     }
3175796c8dcSSimon Schubert   return (char *) shstrtab;
3185796c8dcSSimon Schubert }
3195796c8dcSSimon Schubert 
3205796c8dcSSimon Schubert char *
bfd_elf_string_from_elf_section(bfd * abfd,unsigned int shindex,unsigned int strindex)3215796c8dcSSimon Schubert bfd_elf_string_from_elf_section (bfd *abfd,
3225796c8dcSSimon Schubert 				 unsigned int shindex,
3235796c8dcSSimon Schubert 				 unsigned int strindex)
3245796c8dcSSimon Schubert {
3255796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr;
3265796c8dcSSimon Schubert 
3275796c8dcSSimon Schubert   if (strindex == 0)
3285796c8dcSSimon Schubert     return "";
3295796c8dcSSimon Schubert 
3305796c8dcSSimon Schubert   if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd))
3315796c8dcSSimon Schubert     return NULL;
3325796c8dcSSimon Schubert 
3335796c8dcSSimon Schubert   hdr = elf_elfsections (abfd)[shindex];
3345796c8dcSSimon Schubert 
3355796c8dcSSimon Schubert   if (hdr->contents == NULL
3365796c8dcSSimon Schubert       && bfd_elf_get_str_section (abfd, shindex) == NULL)
3375796c8dcSSimon Schubert     return NULL;
3385796c8dcSSimon Schubert 
3395796c8dcSSimon Schubert   if (strindex >= hdr->sh_size)
3405796c8dcSSimon Schubert     {
3415796c8dcSSimon Schubert       unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
3425796c8dcSSimon Schubert       (*_bfd_error_handler)
3435796c8dcSSimon Schubert 	(_("%B: invalid string offset %u >= %lu for section `%s'"),
3445796c8dcSSimon Schubert 	 abfd, strindex, (unsigned long) hdr->sh_size,
3455796c8dcSSimon Schubert 	 (shindex == shstrndx && strindex == hdr->sh_name
3465796c8dcSSimon Schubert 	  ? ".shstrtab"
3475796c8dcSSimon Schubert 	  : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
3485796c8dcSSimon Schubert       return NULL;
3495796c8dcSSimon Schubert     }
3505796c8dcSSimon Schubert 
3515796c8dcSSimon Schubert   return ((char *) hdr->contents) + strindex;
3525796c8dcSSimon Schubert }
3535796c8dcSSimon Schubert 
3545796c8dcSSimon Schubert /* Read and convert symbols to internal format.
3555796c8dcSSimon Schubert    SYMCOUNT specifies the number of symbols to read, starting from
3565796c8dcSSimon Schubert    symbol SYMOFFSET.  If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
3575796c8dcSSimon Schubert    are non-NULL, they are used to store the internal symbols, external
3585796c8dcSSimon Schubert    symbols, and symbol section index extensions, respectively.
3595796c8dcSSimon Schubert    Returns a pointer to the internal symbol buffer (malloced if necessary)
3605796c8dcSSimon Schubert    or NULL if there were no symbols or some kind of problem.  */
3615796c8dcSSimon Schubert 
3625796c8dcSSimon Schubert Elf_Internal_Sym *
bfd_elf_get_elf_syms(bfd * ibfd,Elf_Internal_Shdr * symtab_hdr,size_t symcount,size_t symoffset,Elf_Internal_Sym * intsym_buf,void * extsym_buf,Elf_External_Sym_Shndx * extshndx_buf)3635796c8dcSSimon Schubert bfd_elf_get_elf_syms (bfd *ibfd,
3645796c8dcSSimon Schubert 		      Elf_Internal_Shdr *symtab_hdr,
3655796c8dcSSimon Schubert 		      size_t symcount,
3665796c8dcSSimon Schubert 		      size_t symoffset,
3675796c8dcSSimon Schubert 		      Elf_Internal_Sym *intsym_buf,
3685796c8dcSSimon Schubert 		      void *extsym_buf,
3695796c8dcSSimon Schubert 		      Elf_External_Sym_Shndx *extshndx_buf)
3705796c8dcSSimon Schubert {
3715796c8dcSSimon Schubert   Elf_Internal_Shdr *shndx_hdr;
3725796c8dcSSimon Schubert   void *alloc_ext;
3735796c8dcSSimon Schubert   const bfd_byte *esym;
3745796c8dcSSimon Schubert   Elf_External_Sym_Shndx *alloc_extshndx;
3755796c8dcSSimon Schubert   Elf_External_Sym_Shndx *shndx;
3765796c8dcSSimon Schubert   Elf_Internal_Sym *alloc_intsym;
3775796c8dcSSimon Schubert   Elf_Internal_Sym *isym;
3785796c8dcSSimon Schubert   Elf_Internal_Sym *isymend;
3795796c8dcSSimon Schubert   const struct elf_backend_data *bed;
3805796c8dcSSimon Schubert   size_t extsym_size;
3815796c8dcSSimon Schubert   bfd_size_type amt;
3825796c8dcSSimon Schubert   file_ptr pos;
3835796c8dcSSimon Schubert 
3845796c8dcSSimon Schubert   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
3855796c8dcSSimon Schubert     abort ();
3865796c8dcSSimon Schubert 
3875796c8dcSSimon Schubert   if (symcount == 0)
3885796c8dcSSimon Schubert     return intsym_buf;
3895796c8dcSSimon Schubert 
3905796c8dcSSimon Schubert   /* Normal syms might have section extension entries.  */
3915796c8dcSSimon Schubert   shndx_hdr = NULL;
3925796c8dcSSimon Schubert   if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
3935796c8dcSSimon Schubert     shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
3945796c8dcSSimon Schubert 
3955796c8dcSSimon Schubert   /* Read the symbols.  */
3965796c8dcSSimon Schubert   alloc_ext = NULL;
3975796c8dcSSimon Schubert   alloc_extshndx = NULL;
3985796c8dcSSimon Schubert   alloc_intsym = NULL;
3995796c8dcSSimon Schubert   bed = get_elf_backend_data (ibfd);
4005796c8dcSSimon Schubert   extsym_size = bed->s->sizeof_sym;
4015796c8dcSSimon Schubert   amt = symcount * extsym_size;
4025796c8dcSSimon Schubert   pos = symtab_hdr->sh_offset + symoffset * extsym_size;
4035796c8dcSSimon Schubert   if (extsym_buf == NULL)
4045796c8dcSSimon Schubert     {
4055796c8dcSSimon Schubert       alloc_ext = bfd_malloc2 (symcount, extsym_size);
4065796c8dcSSimon Schubert       extsym_buf = alloc_ext;
4075796c8dcSSimon Schubert     }
4085796c8dcSSimon Schubert   if (extsym_buf == NULL
4095796c8dcSSimon Schubert       || bfd_seek (ibfd, pos, SEEK_SET) != 0
4105796c8dcSSimon Schubert       || bfd_bread (extsym_buf, amt, ibfd) != amt)
4115796c8dcSSimon Schubert     {
4125796c8dcSSimon Schubert       intsym_buf = NULL;
4135796c8dcSSimon Schubert       goto out;
4145796c8dcSSimon Schubert     }
4155796c8dcSSimon Schubert 
4165796c8dcSSimon Schubert   if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
4175796c8dcSSimon Schubert     extshndx_buf = NULL;
4185796c8dcSSimon Schubert   else
4195796c8dcSSimon Schubert     {
4205796c8dcSSimon Schubert       amt = symcount * sizeof (Elf_External_Sym_Shndx);
4215796c8dcSSimon Schubert       pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
4225796c8dcSSimon Schubert       if (extshndx_buf == NULL)
4235796c8dcSSimon Schubert 	{
4245796c8dcSSimon Schubert 	  alloc_extshndx = (Elf_External_Sym_Shndx *)
4255796c8dcSSimon Schubert               bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx));
4265796c8dcSSimon Schubert 	  extshndx_buf = alloc_extshndx;
4275796c8dcSSimon Schubert 	}
4285796c8dcSSimon Schubert       if (extshndx_buf == NULL
4295796c8dcSSimon Schubert 	  || bfd_seek (ibfd, pos, SEEK_SET) != 0
4305796c8dcSSimon Schubert 	  || bfd_bread (extshndx_buf, amt, ibfd) != amt)
4315796c8dcSSimon Schubert 	{
4325796c8dcSSimon Schubert 	  intsym_buf = NULL;
4335796c8dcSSimon Schubert 	  goto out;
4345796c8dcSSimon Schubert 	}
4355796c8dcSSimon Schubert     }
4365796c8dcSSimon Schubert 
4375796c8dcSSimon Schubert   if (intsym_buf == NULL)
4385796c8dcSSimon Schubert     {
4395796c8dcSSimon Schubert       alloc_intsym = (Elf_Internal_Sym *)
4405796c8dcSSimon Schubert           bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
4415796c8dcSSimon Schubert       intsym_buf = alloc_intsym;
4425796c8dcSSimon Schubert       if (intsym_buf == NULL)
4435796c8dcSSimon Schubert 	goto out;
4445796c8dcSSimon Schubert     }
4455796c8dcSSimon Schubert 
4465796c8dcSSimon Schubert   /* Convert the symbols to internal form.  */
4475796c8dcSSimon Schubert   isymend = intsym_buf + symcount;
4485796c8dcSSimon Schubert   for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf,
4495796c8dcSSimon Schubert            shndx = extshndx_buf;
4505796c8dcSSimon Schubert        isym < isymend;
4515796c8dcSSimon Schubert        esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
4525796c8dcSSimon Schubert     if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
4535796c8dcSSimon Schubert       {
4545796c8dcSSimon Schubert 	symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
4555796c8dcSSimon Schubert 	(*_bfd_error_handler) (_("%B symbol number %lu references "
4565796c8dcSSimon Schubert 				 "nonexistent SHT_SYMTAB_SHNDX section"),
4575796c8dcSSimon Schubert 			       ibfd, (unsigned long) symoffset);
4585796c8dcSSimon Schubert 	if (alloc_intsym != NULL)
4595796c8dcSSimon Schubert 	  free (alloc_intsym);
4605796c8dcSSimon Schubert 	intsym_buf = NULL;
4615796c8dcSSimon Schubert 	goto out;
4625796c8dcSSimon Schubert       }
4635796c8dcSSimon Schubert 
4645796c8dcSSimon Schubert  out:
4655796c8dcSSimon Schubert   if (alloc_ext != NULL)
4665796c8dcSSimon Schubert     free (alloc_ext);
4675796c8dcSSimon Schubert   if (alloc_extshndx != NULL)
4685796c8dcSSimon Schubert     free (alloc_extshndx);
4695796c8dcSSimon Schubert 
4705796c8dcSSimon Schubert   return intsym_buf;
4715796c8dcSSimon Schubert }
4725796c8dcSSimon Schubert 
4735796c8dcSSimon Schubert /* Look up a symbol name.  */
4745796c8dcSSimon Schubert const char *
bfd_elf_sym_name(bfd * abfd,Elf_Internal_Shdr * symtab_hdr,Elf_Internal_Sym * isym,asection * sym_sec)4755796c8dcSSimon Schubert bfd_elf_sym_name (bfd *abfd,
4765796c8dcSSimon Schubert 		  Elf_Internal_Shdr *symtab_hdr,
4775796c8dcSSimon Schubert 		  Elf_Internal_Sym *isym,
4785796c8dcSSimon Schubert 		  asection *sym_sec)
4795796c8dcSSimon Schubert {
4805796c8dcSSimon Schubert   const char *name;
4815796c8dcSSimon Schubert   unsigned int iname = isym->st_name;
4825796c8dcSSimon Schubert   unsigned int shindex = symtab_hdr->sh_link;
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert   if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
4855796c8dcSSimon Schubert       /* Check for a bogus st_shndx to avoid crashing.  */
4865796c8dcSSimon Schubert       && isym->st_shndx < elf_numsections (abfd))
4875796c8dcSSimon Schubert     {
4885796c8dcSSimon Schubert       iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
4895796c8dcSSimon Schubert       shindex = elf_elfheader (abfd)->e_shstrndx;
4905796c8dcSSimon Schubert     }
4915796c8dcSSimon Schubert 
4925796c8dcSSimon Schubert   name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
4935796c8dcSSimon Schubert   if (name == NULL)
4945796c8dcSSimon Schubert     name = "(null)";
4955796c8dcSSimon Schubert   else if (sym_sec && *name == '\0')
4965796c8dcSSimon Schubert     name = bfd_section_name (abfd, sym_sec);
4975796c8dcSSimon Schubert 
4985796c8dcSSimon Schubert   return name;
4995796c8dcSSimon Schubert }
5005796c8dcSSimon Schubert 
5015796c8dcSSimon Schubert /* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
5025796c8dcSSimon Schubert    sections.  The first element is the flags, the rest are section
5035796c8dcSSimon Schubert    pointers.  */
5045796c8dcSSimon Schubert 
5055796c8dcSSimon Schubert typedef union elf_internal_group {
5065796c8dcSSimon Schubert   Elf_Internal_Shdr *shdr;
5075796c8dcSSimon Schubert   unsigned int flags;
5085796c8dcSSimon Schubert } Elf_Internal_Group;
5095796c8dcSSimon Schubert 
5105796c8dcSSimon Schubert /* Return the name of the group signature symbol.  Why isn't the
5115796c8dcSSimon Schubert    signature just a string?  */
5125796c8dcSSimon Schubert 
5135796c8dcSSimon Schubert static const char *
group_signature(bfd * abfd,Elf_Internal_Shdr * ghdr)5145796c8dcSSimon Schubert group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
5155796c8dcSSimon Schubert {
5165796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr;
5175796c8dcSSimon Schubert   unsigned char esym[sizeof (Elf64_External_Sym)];
5185796c8dcSSimon Schubert   Elf_External_Sym_Shndx eshndx;
5195796c8dcSSimon Schubert   Elf_Internal_Sym isym;
5205796c8dcSSimon Schubert 
5215796c8dcSSimon Schubert   /* First we need to ensure the symbol table is available.  Make sure
5225796c8dcSSimon Schubert      that it is a symbol table section.  */
5235796c8dcSSimon Schubert   if (ghdr->sh_link >= elf_numsections (abfd))
5245796c8dcSSimon Schubert     return NULL;
5255796c8dcSSimon Schubert   hdr = elf_elfsections (abfd) [ghdr->sh_link];
5265796c8dcSSimon Schubert   if (hdr->sh_type != SHT_SYMTAB
5275796c8dcSSimon Schubert       || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
5285796c8dcSSimon Schubert     return NULL;
5295796c8dcSSimon Schubert 
5305796c8dcSSimon Schubert   /* Go read the symbol.  */
5315796c8dcSSimon Schubert   hdr = &elf_tdata (abfd)->symtab_hdr;
5325796c8dcSSimon Schubert   if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
5335796c8dcSSimon Schubert 			    &isym, esym, &eshndx) == NULL)
5345796c8dcSSimon Schubert     return NULL;
5355796c8dcSSimon Schubert 
5365796c8dcSSimon Schubert   return bfd_elf_sym_name (abfd, hdr, &isym, NULL);
5375796c8dcSSimon Schubert }
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert /* Set next_in_group list pointer, and group name for NEWSECT.  */
5405796c8dcSSimon Schubert 
5415796c8dcSSimon Schubert static bfd_boolean
setup_group(bfd * abfd,Elf_Internal_Shdr * hdr,asection * newsect)5425796c8dcSSimon Schubert setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
5435796c8dcSSimon Schubert {
5445796c8dcSSimon Schubert   unsigned int num_group = elf_tdata (abfd)->num_group;
5455796c8dcSSimon Schubert 
5465796c8dcSSimon Schubert   /* If num_group is zero, read in all SHT_GROUP sections.  The count
5475796c8dcSSimon Schubert      is set to -1 if there are no SHT_GROUP sections.  */
5485796c8dcSSimon Schubert   if (num_group == 0)
5495796c8dcSSimon Schubert     {
5505796c8dcSSimon Schubert       unsigned int i, shnum;
5515796c8dcSSimon Schubert 
5525796c8dcSSimon Schubert       /* First count the number of groups.  If we have a SHT_GROUP
5535796c8dcSSimon Schubert 	 section with just a flag word (ie. sh_size is 4), ignore it.  */
5545796c8dcSSimon Schubert       shnum = elf_numsections (abfd);
5555796c8dcSSimon Schubert       num_group = 0;
5565796c8dcSSimon Schubert 
557*ef5ccd6cSJohn Marino #define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize)	\
5585796c8dcSSimon Schubert 	(   (shdr)->sh_type == SHT_GROUP		\
559*ef5ccd6cSJohn Marino 	 && (shdr)->sh_size >= minsize			\
5605796c8dcSSimon Schubert 	 && (shdr)->sh_entsize == GRP_ENTRY_SIZE	\
5615796c8dcSSimon Schubert 	 && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
5625796c8dcSSimon Schubert 
5635796c8dcSSimon Schubert       for (i = 0; i < shnum; i++)
5645796c8dcSSimon Schubert 	{
5655796c8dcSSimon Schubert 	  Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
5665796c8dcSSimon Schubert 
567*ef5ccd6cSJohn Marino 	  if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
5685796c8dcSSimon Schubert 	    num_group += 1;
5695796c8dcSSimon Schubert 	}
5705796c8dcSSimon Schubert 
5715796c8dcSSimon Schubert       if (num_group == 0)
5725796c8dcSSimon Schubert 	{
5735796c8dcSSimon Schubert 	  num_group = (unsigned) -1;
5745796c8dcSSimon Schubert 	  elf_tdata (abfd)->num_group = num_group;
5755796c8dcSSimon Schubert 	}
5765796c8dcSSimon Schubert       else
5775796c8dcSSimon Schubert 	{
5785796c8dcSSimon Schubert 	  /* We keep a list of elf section headers for group sections,
5795796c8dcSSimon Schubert 	     so we can find them quickly.  */
5805796c8dcSSimon Schubert 	  bfd_size_type amt;
5815796c8dcSSimon Schubert 
5825796c8dcSSimon Schubert 	  elf_tdata (abfd)->num_group = num_group;
5835796c8dcSSimon Schubert 	  elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **)
5845796c8dcSSimon Schubert               bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
5855796c8dcSSimon Schubert 	  if (elf_tdata (abfd)->group_sect_ptr == NULL)
5865796c8dcSSimon Schubert 	    return FALSE;
5875796c8dcSSimon Schubert 
5885796c8dcSSimon Schubert 	  num_group = 0;
5895796c8dcSSimon Schubert 	  for (i = 0; i < shnum; i++)
5905796c8dcSSimon Schubert 	    {
5915796c8dcSSimon Schubert 	      Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
5925796c8dcSSimon Schubert 
593*ef5ccd6cSJohn Marino 	      if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
5945796c8dcSSimon Schubert 		{
5955796c8dcSSimon Schubert 		  unsigned char *src;
5965796c8dcSSimon Schubert 		  Elf_Internal_Group *dest;
5975796c8dcSSimon Schubert 
5985796c8dcSSimon Schubert 		  /* Add to list of sections.  */
5995796c8dcSSimon Schubert 		  elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
6005796c8dcSSimon Schubert 		  num_group += 1;
6015796c8dcSSimon Schubert 
6025796c8dcSSimon Schubert 		  /* Read the raw contents.  */
6035796c8dcSSimon Schubert 		  BFD_ASSERT (sizeof (*dest) >= 4);
6045796c8dcSSimon Schubert 		  amt = shdr->sh_size * sizeof (*dest) / 4;
6055796c8dcSSimon Schubert 		  shdr->contents = (unsigned char *)
6065796c8dcSSimon Schubert                       bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4);
6075796c8dcSSimon Schubert 		  /* PR binutils/4110: Handle corrupt group headers.  */
6085796c8dcSSimon Schubert 		  if (shdr->contents == NULL)
6095796c8dcSSimon Schubert 		    {
6105796c8dcSSimon Schubert 		      _bfd_error_handler
6115796c8dcSSimon Schubert 			(_("%B: Corrupt size field in group section header: 0x%lx"), abfd, shdr->sh_size);
6125796c8dcSSimon Schubert 		      bfd_set_error (bfd_error_bad_value);
6135796c8dcSSimon Schubert 		      return FALSE;
6145796c8dcSSimon Schubert 		    }
6155796c8dcSSimon Schubert 
6165796c8dcSSimon Schubert 		  memset (shdr->contents, 0, amt);
6175796c8dcSSimon Schubert 
6185796c8dcSSimon Schubert 		  if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
6195796c8dcSSimon Schubert 		      || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
6205796c8dcSSimon Schubert 			  != shdr->sh_size))
6215796c8dcSSimon Schubert 		    return FALSE;
6225796c8dcSSimon Schubert 
6235796c8dcSSimon Schubert 		  /* Translate raw contents, a flag word followed by an
6245796c8dcSSimon Schubert 		     array of elf section indices all in target byte order,
6255796c8dcSSimon Schubert 		     to the flag word followed by an array of elf section
6265796c8dcSSimon Schubert 		     pointers.  */
6275796c8dcSSimon Schubert 		  src = shdr->contents + shdr->sh_size;
6285796c8dcSSimon Schubert 		  dest = (Elf_Internal_Group *) (shdr->contents + amt);
6295796c8dcSSimon Schubert 		  while (1)
6305796c8dcSSimon Schubert 		    {
6315796c8dcSSimon Schubert 		      unsigned int idx;
6325796c8dcSSimon Schubert 
6335796c8dcSSimon Schubert 		      src -= 4;
6345796c8dcSSimon Schubert 		      --dest;
6355796c8dcSSimon Schubert 		      idx = H_GET_32 (abfd, src);
6365796c8dcSSimon Schubert 		      if (src == shdr->contents)
6375796c8dcSSimon Schubert 			{
6385796c8dcSSimon Schubert 			  dest->flags = idx;
6395796c8dcSSimon Schubert 			  if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
6405796c8dcSSimon Schubert 			    shdr->bfd_section->flags
6415796c8dcSSimon Schubert 			      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
6425796c8dcSSimon Schubert 			  break;
6435796c8dcSSimon Schubert 			}
6445796c8dcSSimon Schubert 		      if (idx >= shnum)
6455796c8dcSSimon Schubert 			{
6465796c8dcSSimon Schubert 			  ((*_bfd_error_handler)
6475796c8dcSSimon Schubert 			   (_("%B: invalid SHT_GROUP entry"), abfd));
6485796c8dcSSimon Schubert 			  idx = 0;
6495796c8dcSSimon Schubert 			}
6505796c8dcSSimon Schubert 		      dest->shdr = elf_elfsections (abfd)[idx];
6515796c8dcSSimon Schubert 		    }
6525796c8dcSSimon Schubert 		}
6535796c8dcSSimon Schubert 	    }
6545796c8dcSSimon Schubert 	}
6555796c8dcSSimon Schubert     }
6565796c8dcSSimon Schubert 
6575796c8dcSSimon Schubert   if (num_group != (unsigned) -1)
6585796c8dcSSimon Schubert     {
6595796c8dcSSimon Schubert       unsigned int i;
6605796c8dcSSimon Schubert 
6615796c8dcSSimon Schubert       for (i = 0; i < num_group; i++)
6625796c8dcSSimon Schubert 	{
6635796c8dcSSimon Schubert 	  Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
6645796c8dcSSimon Schubert 	  Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
6655796c8dcSSimon Schubert 	  unsigned int n_elt = shdr->sh_size / 4;
6665796c8dcSSimon Schubert 
6675796c8dcSSimon Schubert 	  /* Look through this group's sections to see if current
6685796c8dcSSimon Schubert 	     section is a member.  */
6695796c8dcSSimon Schubert 	  while (--n_elt != 0)
6705796c8dcSSimon Schubert 	    if ((++idx)->shdr == hdr)
6715796c8dcSSimon Schubert 	      {
6725796c8dcSSimon Schubert 		asection *s = NULL;
6735796c8dcSSimon Schubert 
6745796c8dcSSimon Schubert 		/* We are a member of this group.  Go looking through
6755796c8dcSSimon Schubert 		   other members to see if any others are linked via
6765796c8dcSSimon Schubert 		   next_in_group.  */
6775796c8dcSSimon Schubert 		idx = (Elf_Internal_Group *) shdr->contents;
6785796c8dcSSimon Schubert 		n_elt = shdr->sh_size / 4;
6795796c8dcSSimon Schubert 		while (--n_elt != 0)
6805796c8dcSSimon Schubert 		  if ((s = (++idx)->shdr->bfd_section) != NULL
6815796c8dcSSimon Schubert 		      && elf_next_in_group (s) != NULL)
6825796c8dcSSimon Schubert 		    break;
6835796c8dcSSimon Schubert 		if (n_elt != 0)
6845796c8dcSSimon Schubert 		  {
6855796c8dcSSimon Schubert 		    /* Snarf the group name from other member, and
6865796c8dcSSimon Schubert 		       insert current section in circular list.  */
6875796c8dcSSimon Schubert 		    elf_group_name (newsect) = elf_group_name (s);
6885796c8dcSSimon Schubert 		    elf_next_in_group (newsect) = elf_next_in_group (s);
6895796c8dcSSimon Schubert 		    elf_next_in_group (s) = newsect;
6905796c8dcSSimon Schubert 		  }
6915796c8dcSSimon Schubert 		else
6925796c8dcSSimon Schubert 		  {
6935796c8dcSSimon Schubert 		    const char *gname;
6945796c8dcSSimon Schubert 
6955796c8dcSSimon Schubert 		    gname = group_signature (abfd, shdr);
6965796c8dcSSimon Schubert 		    if (gname == NULL)
6975796c8dcSSimon Schubert 		      return FALSE;
6985796c8dcSSimon Schubert 		    elf_group_name (newsect) = gname;
6995796c8dcSSimon Schubert 
7005796c8dcSSimon Schubert 		    /* Start a circular list with one element.  */
7015796c8dcSSimon Schubert 		    elf_next_in_group (newsect) = newsect;
7025796c8dcSSimon Schubert 		  }
7035796c8dcSSimon Schubert 
7045796c8dcSSimon Schubert 		/* If the group section has been created, point to the
7055796c8dcSSimon Schubert 		   new member.  */
7065796c8dcSSimon Schubert 		if (shdr->bfd_section != NULL)
7075796c8dcSSimon Schubert 		  elf_next_in_group (shdr->bfd_section) = newsect;
7085796c8dcSSimon Schubert 
7095796c8dcSSimon Schubert 		i = num_group - 1;
7105796c8dcSSimon Schubert 		break;
7115796c8dcSSimon Schubert 	      }
7125796c8dcSSimon Schubert 	}
7135796c8dcSSimon Schubert     }
7145796c8dcSSimon Schubert 
7155796c8dcSSimon Schubert   if (elf_group_name (newsect) == NULL)
7165796c8dcSSimon Schubert     {
7175796c8dcSSimon Schubert       (*_bfd_error_handler) (_("%B: no group info for section %A"),
7185796c8dcSSimon Schubert 			     abfd, newsect);
7195796c8dcSSimon Schubert     }
7205796c8dcSSimon Schubert   return TRUE;
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert 
7235796c8dcSSimon Schubert bfd_boolean
_bfd_elf_setup_sections(bfd * abfd)7245796c8dcSSimon Schubert _bfd_elf_setup_sections (bfd *abfd)
7255796c8dcSSimon Schubert {
7265796c8dcSSimon Schubert   unsigned int i;
7275796c8dcSSimon Schubert   unsigned int num_group = elf_tdata (abfd)->num_group;
7285796c8dcSSimon Schubert   bfd_boolean result = TRUE;
7295796c8dcSSimon Schubert   asection *s;
7305796c8dcSSimon Schubert 
7315796c8dcSSimon Schubert   /* Process SHF_LINK_ORDER.  */
7325796c8dcSSimon Schubert   for (s = abfd->sections; s != NULL; s = s->next)
7335796c8dcSSimon Schubert     {
7345796c8dcSSimon Schubert       Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
7355796c8dcSSimon Schubert       if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
7365796c8dcSSimon Schubert 	{
7375796c8dcSSimon Schubert 	  unsigned int elfsec = this_hdr->sh_link;
7385796c8dcSSimon Schubert 	  /* FIXME: The old Intel compiler and old strip/objcopy may
7395796c8dcSSimon Schubert 	     not set the sh_link or sh_info fields.  Hence we could
7405796c8dcSSimon Schubert 	     get the situation where elfsec is 0.  */
7415796c8dcSSimon Schubert 	  if (elfsec == 0)
7425796c8dcSSimon Schubert 	    {
7435796c8dcSSimon Schubert 	      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7445796c8dcSSimon Schubert 	      if (bed->link_order_error_handler)
7455796c8dcSSimon Schubert 		bed->link_order_error_handler
7465796c8dcSSimon Schubert 		  (_("%B: warning: sh_link not set for section `%A'"),
7475796c8dcSSimon Schubert 		   abfd, s);
7485796c8dcSSimon Schubert 	    }
7495796c8dcSSimon Schubert 	  else
7505796c8dcSSimon Schubert 	    {
751cf7f2e2dSJohn Marino 	      asection *linksec = NULL;
7525796c8dcSSimon Schubert 
7535796c8dcSSimon Schubert 	      if (elfsec < elf_numsections (abfd))
7545796c8dcSSimon Schubert 		{
7555796c8dcSSimon Schubert 		  this_hdr = elf_elfsections (abfd)[elfsec];
756cf7f2e2dSJohn Marino 		  linksec = this_hdr->bfd_section;
7575796c8dcSSimon Schubert 		}
7585796c8dcSSimon Schubert 
7595796c8dcSSimon Schubert 	      /* PR 1991, 2008:
7605796c8dcSSimon Schubert 		 Some strip/objcopy may leave an incorrect value in
7615796c8dcSSimon Schubert 		 sh_link.  We don't want to proceed.  */
762cf7f2e2dSJohn Marino 	      if (linksec == NULL)
7635796c8dcSSimon Schubert 		{
7645796c8dcSSimon Schubert 		  (*_bfd_error_handler)
7655796c8dcSSimon Schubert 		    (_("%B: sh_link [%d] in section `%A' is incorrect"),
7665796c8dcSSimon Schubert 		     s->owner, s, elfsec);
7675796c8dcSSimon Schubert 		  result = FALSE;
7685796c8dcSSimon Schubert 		}
7695796c8dcSSimon Schubert 
770cf7f2e2dSJohn Marino 	      elf_linked_to_section (s) = linksec;
7715796c8dcSSimon Schubert 	    }
7725796c8dcSSimon Schubert 	}
7735796c8dcSSimon Schubert     }
7745796c8dcSSimon Schubert 
7755796c8dcSSimon Schubert   /* Process section groups.  */
7765796c8dcSSimon Schubert   if (num_group == (unsigned) -1)
7775796c8dcSSimon Schubert     return result;
7785796c8dcSSimon Schubert 
7795796c8dcSSimon Schubert   for (i = 0; i < num_group; i++)
7805796c8dcSSimon Schubert     {
7815796c8dcSSimon Schubert       Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
7825796c8dcSSimon Schubert       Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
7835796c8dcSSimon Schubert       unsigned int n_elt = shdr->sh_size / 4;
7845796c8dcSSimon Schubert 
7855796c8dcSSimon Schubert       while (--n_elt != 0)
7865796c8dcSSimon Schubert 	if ((++idx)->shdr->bfd_section)
7875796c8dcSSimon Schubert 	  elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
7885796c8dcSSimon Schubert 	else if (idx->shdr->sh_type == SHT_RELA
7895796c8dcSSimon Schubert 		 || idx->shdr->sh_type == SHT_REL)
7905796c8dcSSimon Schubert 	  /* We won't include relocation sections in section groups in
7915796c8dcSSimon Schubert 	     output object files. We adjust the group section size here
7925796c8dcSSimon Schubert 	     so that relocatable link will work correctly when
7935796c8dcSSimon Schubert 	     relocation sections are in section group in input object
7945796c8dcSSimon Schubert 	     files.  */
7955796c8dcSSimon Schubert 	  shdr->bfd_section->size -= 4;
7965796c8dcSSimon Schubert 	else
7975796c8dcSSimon Schubert 	  {
7985796c8dcSSimon Schubert 	    /* There are some unknown sections in the group.  */
7995796c8dcSSimon Schubert 	    (*_bfd_error_handler)
8005796c8dcSSimon Schubert 	      (_("%B: unknown [%d] section `%s' in group [%s]"),
8015796c8dcSSimon Schubert 	       abfd,
8025796c8dcSSimon Schubert 	       (unsigned int) idx->shdr->sh_type,
8035796c8dcSSimon Schubert 	       bfd_elf_string_from_elf_section (abfd,
8045796c8dcSSimon Schubert 						(elf_elfheader (abfd)
8055796c8dcSSimon Schubert 						 ->e_shstrndx),
8065796c8dcSSimon Schubert 						idx->shdr->sh_name),
8075796c8dcSSimon Schubert 	       shdr->bfd_section->name);
8085796c8dcSSimon Schubert 	    result = FALSE;
8095796c8dcSSimon Schubert 	  }
8105796c8dcSSimon Schubert     }
8115796c8dcSSimon Schubert   return result;
8125796c8dcSSimon Schubert }
8135796c8dcSSimon Schubert 
8145796c8dcSSimon Schubert bfd_boolean
bfd_elf_is_group_section(bfd * abfd ATTRIBUTE_UNUSED,const asection * sec)8155796c8dcSSimon Schubert bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
8165796c8dcSSimon Schubert {
8175796c8dcSSimon Schubert   return elf_next_in_group (sec) != NULL;
8185796c8dcSSimon Schubert }
8195796c8dcSSimon Schubert 
8205796c8dcSSimon Schubert /* Make a BFD section from an ELF section.  We store a pointer to the
8215796c8dcSSimon Schubert    BFD section in the bfd_section field of the header.  */
8225796c8dcSSimon Schubert 
8235796c8dcSSimon Schubert bfd_boolean
_bfd_elf_make_section_from_shdr(bfd * abfd,Elf_Internal_Shdr * hdr,const char * name,int shindex)8245796c8dcSSimon Schubert _bfd_elf_make_section_from_shdr (bfd *abfd,
8255796c8dcSSimon Schubert 				 Elf_Internal_Shdr *hdr,
8265796c8dcSSimon Schubert 				 const char *name,
8275796c8dcSSimon Schubert 				 int shindex)
8285796c8dcSSimon Schubert {
8295796c8dcSSimon Schubert   asection *newsect;
8305796c8dcSSimon Schubert   flagword flags;
8315796c8dcSSimon Schubert   const struct elf_backend_data *bed;
8325796c8dcSSimon Schubert 
8335796c8dcSSimon Schubert   if (hdr->bfd_section != NULL)
8345796c8dcSSimon Schubert     return TRUE;
8355796c8dcSSimon Schubert 
8365796c8dcSSimon Schubert   newsect = bfd_make_section_anyway (abfd, name);
8375796c8dcSSimon Schubert   if (newsect == NULL)
8385796c8dcSSimon Schubert     return FALSE;
8395796c8dcSSimon Schubert 
8405796c8dcSSimon Schubert   hdr->bfd_section = newsect;
8415796c8dcSSimon Schubert   elf_section_data (newsect)->this_hdr = *hdr;
8425796c8dcSSimon Schubert   elf_section_data (newsect)->this_idx = shindex;
8435796c8dcSSimon Schubert 
8445796c8dcSSimon Schubert   /* Always use the real type/flags.  */
8455796c8dcSSimon Schubert   elf_section_type (newsect) = hdr->sh_type;
8465796c8dcSSimon Schubert   elf_section_flags (newsect) = hdr->sh_flags;
8475796c8dcSSimon Schubert 
8485796c8dcSSimon Schubert   newsect->filepos = hdr->sh_offset;
8495796c8dcSSimon Schubert 
8505796c8dcSSimon Schubert   if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
8515796c8dcSSimon Schubert       || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
8525796c8dcSSimon Schubert       || ! bfd_set_section_alignment (abfd, newsect,
8535796c8dcSSimon Schubert 				      bfd_log2 (hdr->sh_addralign)))
8545796c8dcSSimon Schubert     return FALSE;
8555796c8dcSSimon Schubert 
8565796c8dcSSimon Schubert   flags = SEC_NO_FLAGS;
8575796c8dcSSimon Schubert   if (hdr->sh_type != SHT_NOBITS)
8585796c8dcSSimon Schubert     flags |= SEC_HAS_CONTENTS;
8595796c8dcSSimon Schubert   if (hdr->sh_type == SHT_GROUP)
8605796c8dcSSimon Schubert     flags |= SEC_GROUP | SEC_EXCLUDE;
8615796c8dcSSimon Schubert   if ((hdr->sh_flags & SHF_ALLOC) != 0)
8625796c8dcSSimon Schubert     {
8635796c8dcSSimon Schubert       flags |= SEC_ALLOC;
8645796c8dcSSimon Schubert       if (hdr->sh_type != SHT_NOBITS)
8655796c8dcSSimon Schubert 	flags |= SEC_LOAD;
8665796c8dcSSimon Schubert     }
8675796c8dcSSimon Schubert   if ((hdr->sh_flags & SHF_WRITE) == 0)
8685796c8dcSSimon Schubert     flags |= SEC_READONLY;
8695796c8dcSSimon Schubert   if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
8705796c8dcSSimon Schubert     flags |= SEC_CODE;
8715796c8dcSSimon Schubert   else if ((flags & SEC_LOAD) != 0)
8725796c8dcSSimon Schubert     flags |= SEC_DATA;
8735796c8dcSSimon Schubert   if ((hdr->sh_flags & SHF_MERGE) != 0)
8745796c8dcSSimon Schubert     {
8755796c8dcSSimon Schubert       flags |= SEC_MERGE;
8765796c8dcSSimon Schubert       newsect->entsize = hdr->sh_entsize;
8775796c8dcSSimon Schubert       if ((hdr->sh_flags & SHF_STRINGS) != 0)
8785796c8dcSSimon Schubert 	flags |= SEC_STRINGS;
8795796c8dcSSimon Schubert     }
8805796c8dcSSimon Schubert   if (hdr->sh_flags & SHF_GROUP)
8815796c8dcSSimon Schubert     if (!setup_group (abfd, hdr, newsect))
8825796c8dcSSimon Schubert       return FALSE;
8835796c8dcSSimon Schubert   if ((hdr->sh_flags & SHF_TLS) != 0)
8845796c8dcSSimon Schubert     flags |= SEC_THREAD_LOCAL;
885cf7f2e2dSJohn Marino   if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
886cf7f2e2dSJohn Marino     flags |= SEC_EXCLUDE;
8875796c8dcSSimon Schubert 
8885796c8dcSSimon Schubert   if ((flags & SEC_ALLOC) == 0)
8895796c8dcSSimon Schubert     {
8905796c8dcSSimon Schubert       /* The debugging sections appear to be recognized only by name,
8915796c8dcSSimon Schubert 	 not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
8925796c8dcSSimon Schubert       if (name [0] == '.')
8935796c8dcSSimon Schubert 	{
894*ef5ccd6cSJohn Marino 	  const char *p;
895*ef5ccd6cSJohn Marino 	  int n;
896*ef5ccd6cSJohn Marino 	  if (name[1] == 'd')
897*ef5ccd6cSJohn Marino 	    p = ".debug", n = 6;
898*ef5ccd6cSJohn Marino 	  else if (name[1] == 'g' && name[2] == 'n')
899*ef5ccd6cSJohn Marino 	    p = ".gnu.linkonce.wi.", n = 17;
900*ef5ccd6cSJohn Marino 	  else if (name[1] == 'g' && name[2] == 'd')
901*ef5ccd6cSJohn Marino 	    p = ".gdb_index", n = 11; /* yes we really do mean 11.  */
902*ef5ccd6cSJohn Marino 	  else if (name[1] == 'l')
903*ef5ccd6cSJohn Marino 	    p = ".line", n = 5;
904*ef5ccd6cSJohn Marino 	  else if (name[1] == 's')
905*ef5ccd6cSJohn Marino 	    p = ".stab", n = 5;
906*ef5ccd6cSJohn Marino 	  else if (name[1] == 'z')
907*ef5ccd6cSJohn Marino 	    p = ".zdebug", n = 7;
908*ef5ccd6cSJohn Marino 	  else
909*ef5ccd6cSJohn Marino 	    p = NULL, n = 0;
910*ef5ccd6cSJohn Marino 	  if (p != NULL && strncmp (name, p, n) == 0)
9115796c8dcSSimon Schubert 	    flags |= SEC_DEBUGGING;
9125796c8dcSSimon Schubert 	}
9135796c8dcSSimon Schubert     }
9145796c8dcSSimon Schubert 
9155796c8dcSSimon Schubert   /* As a GNU extension, if the name begins with .gnu.linkonce, we
9165796c8dcSSimon Schubert      only link a single copy of the section.  This is used to support
9175796c8dcSSimon Schubert      g++.  g++ will emit each template expansion in its own section.
9185796c8dcSSimon Schubert      The symbols will be defined as weak, so that multiple definitions
9195796c8dcSSimon Schubert      are permitted.  The GNU linker extension is to actually discard
9205796c8dcSSimon Schubert      all but one of the sections.  */
9215796c8dcSSimon Schubert   if (CONST_STRNEQ (name, ".gnu.linkonce")
9225796c8dcSSimon Schubert       && elf_next_in_group (newsect) == NULL)
9235796c8dcSSimon Schubert     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
9245796c8dcSSimon Schubert 
9255796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
9265796c8dcSSimon Schubert   if (bed->elf_backend_section_flags)
9275796c8dcSSimon Schubert     if (! bed->elf_backend_section_flags (&flags, hdr))
9285796c8dcSSimon Schubert       return FALSE;
9295796c8dcSSimon Schubert 
9305796c8dcSSimon Schubert   if (! bfd_set_section_flags (abfd, newsect, flags))
9315796c8dcSSimon Schubert     return FALSE;
9325796c8dcSSimon Schubert 
9335796c8dcSSimon Schubert   /* We do not parse the PT_NOTE segments as we are interested even in the
9345796c8dcSSimon Schubert      separate debug info files which may have the segments offsets corrupted.
9355796c8dcSSimon Schubert      PT_NOTEs from the core files are currently not parsed using BFD.  */
9365796c8dcSSimon Schubert   if (hdr->sh_type == SHT_NOTE)
9375796c8dcSSimon Schubert     {
9385796c8dcSSimon Schubert       bfd_byte *contents;
9395796c8dcSSimon Schubert 
9405796c8dcSSimon Schubert       if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
9415796c8dcSSimon Schubert 	return FALSE;
9425796c8dcSSimon Schubert 
9435796c8dcSSimon Schubert       elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);
9445796c8dcSSimon Schubert       free (contents);
9455796c8dcSSimon Schubert     }
9465796c8dcSSimon Schubert 
9475796c8dcSSimon Schubert   if ((flags & SEC_ALLOC) != 0)
9485796c8dcSSimon Schubert     {
9495796c8dcSSimon Schubert       Elf_Internal_Phdr *phdr;
9505796c8dcSSimon Schubert       unsigned int i, nload;
9515796c8dcSSimon Schubert 
9525796c8dcSSimon Schubert       /* Some ELF linkers produce binaries with all the program header
9535796c8dcSSimon Schubert 	 p_paddr fields zero.  If we have such a binary with more than
9545796c8dcSSimon Schubert 	 one PT_LOAD header, then leave the section lma equal to vma
9555796c8dcSSimon Schubert 	 so that we don't create sections with overlapping lma.  */
9565796c8dcSSimon Schubert       phdr = elf_tdata (abfd)->phdr;
9575796c8dcSSimon Schubert       for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
9585796c8dcSSimon Schubert 	if (phdr->p_paddr != 0)
9595796c8dcSSimon Schubert 	  break;
9605796c8dcSSimon Schubert 	else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
9615796c8dcSSimon Schubert 	  ++nload;
9625796c8dcSSimon Schubert       if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
9635796c8dcSSimon Schubert 	return TRUE;
9645796c8dcSSimon Schubert 
9655796c8dcSSimon Schubert       phdr = elf_tdata (abfd)->phdr;
9665796c8dcSSimon Schubert       for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
9675796c8dcSSimon Schubert 	{
968a45ae5f8SJohn Marino 	  if (((phdr->p_type == PT_LOAD
969a45ae5f8SJohn Marino 		&& (hdr->sh_flags & SHF_TLS) == 0)
970a45ae5f8SJohn Marino 	       || phdr->p_type == PT_TLS)
971cf7f2e2dSJohn Marino 	      && ELF_SECTION_IN_SEGMENT (hdr, phdr))
9725796c8dcSSimon Schubert 	    {
9735796c8dcSSimon Schubert 	      if ((flags & SEC_LOAD) == 0)
9745796c8dcSSimon Schubert 		newsect->lma = (phdr->p_paddr
9755796c8dcSSimon Schubert 				+ hdr->sh_addr - phdr->p_vaddr);
9765796c8dcSSimon Schubert 	      else
9775796c8dcSSimon Schubert 		/* We used to use the same adjustment for SEC_LOAD
9785796c8dcSSimon Schubert 		   sections, but that doesn't work if the segment
9795796c8dcSSimon Schubert 		   is packed with code from multiple VMAs.
9805796c8dcSSimon Schubert 		   Instead we calculate the section LMA based on
9815796c8dcSSimon Schubert 		   the segment LMA.  It is assumed that the
9825796c8dcSSimon Schubert 		   segment will contain sections with contiguous
9835796c8dcSSimon Schubert 		   LMAs, even if the VMAs are not.  */
9845796c8dcSSimon Schubert 		newsect->lma = (phdr->p_paddr
9855796c8dcSSimon Schubert 				+ hdr->sh_offset - phdr->p_offset);
9865796c8dcSSimon Schubert 
9875796c8dcSSimon Schubert 	      /* With contiguous segments, we can't tell from file
9885796c8dcSSimon Schubert 		 offsets whether a section with zero size should
9895796c8dcSSimon Schubert 		 be placed at the end of one segment or the
9905796c8dcSSimon Schubert 		 beginning of the next.  Decide based on vaddr.  */
9915796c8dcSSimon Schubert 	      if (hdr->sh_addr >= phdr->p_vaddr
9925796c8dcSSimon Schubert 		  && (hdr->sh_addr + hdr->sh_size
9935796c8dcSSimon Schubert 		      <= phdr->p_vaddr + phdr->p_memsz))
9945796c8dcSSimon Schubert 		break;
9955796c8dcSSimon Schubert 	    }
9965796c8dcSSimon Schubert 	}
9975796c8dcSSimon Schubert     }
9985796c8dcSSimon Schubert 
999c50c785cSJohn Marino   /* Compress/decompress DWARF debug sections with names: .debug_* and
1000c50c785cSJohn Marino      .zdebug_*, after the section flags is set.  */
1001c50c785cSJohn Marino   if ((flags & SEC_DEBUGGING)
1002c50c785cSJohn Marino       && ((name[1] == 'd' && name[6] == '_')
1003c50c785cSJohn Marino 	  || (name[1] == 'z' && name[7] == '_')))
1004c50c785cSJohn Marino     {
1005c50c785cSJohn Marino       enum { nothing, compress, decompress } action = nothing;
1006c50c785cSJohn Marino       char *new_name;
1007c50c785cSJohn Marino 
1008c50c785cSJohn Marino       if (bfd_is_section_compressed (abfd, newsect))
1009c50c785cSJohn Marino 	{
1010c50c785cSJohn Marino 	  /* Compressed section.  Check if we should decompress.  */
1011c50c785cSJohn Marino 	  if ((abfd->flags & BFD_DECOMPRESS))
1012c50c785cSJohn Marino 	    action = decompress;
1013c50c785cSJohn Marino 	}
1014c50c785cSJohn Marino       else
1015c50c785cSJohn Marino 	{
1016c50c785cSJohn Marino 	  /* Normal section.  Check if we should compress.  */
1017*ef5ccd6cSJohn Marino 	  if ((abfd->flags & BFD_COMPRESS) && newsect->size != 0)
1018c50c785cSJohn Marino 	    action = compress;
1019c50c785cSJohn Marino 	}
1020c50c785cSJohn Marino 
1021c50c785cSJohn Marino       new_name = NULL;
1022c50c785cSJohn Marino       switch (action)
1023c50c785cSJohn Marino 	{
1024c50c785cSJohn Marino 	case nothing:
1025c50c785cSJohn Marino 	  break;
1026c50c785cSJohn Marino 	case compress:
1027c50c785cSJohn Marino 	  if (!bfd_init_section_compress_status (abfd, newsect))
1028c50c785cSJohn Marino 	    {
1029c50c785cSJohn Marino 	      (*_bfd_error_handler)
1030*ef5ccd6cSJohn Marino 		(_("%B: unable to initialize compress status for section %s"),
1031c50c785cSJohn Marino 		 abfd, name);
1032c50c785cSJohn Marino 	      return FALSE;
1033c50c785cSJohn Marino 	    }
1034c50c785cSJohn Marino 	  if (name[1] != 'z')
1035c50c785cSJohn Marino 	    {
1036c50c785cSJohn Marino 	      unsigned int len = strlen (name);
1037c50c785cSJohn Marino 
1038c50c785cSJohn Marino 	      new_name = bfd_alloc (abfd, len + 2);
1039c50c785cSJohn Marino 	      if (new_name == NULL)
1040c50c785cSJohn Marino 		return FALSE;
1041c50c785cSJohn Marino 	      new_name[0] = '.';
1042c50c785cSJohn Marino 	      new_name[1] = 'z';
1043c50c785cSJohn Marino 	      memcpy (new_name + 2, name + 1, len);
1044c50c785cSJohn Marino 	    }
1045c50c785cSJohn Marino 	  break;
1046c50c785cSJohn Marino 	case decompress:
1047c50c785cSJohn Marino 	  if (!bfd_init_section_decompress_status (abfd, newsect))
1048c50c785cSJohn Marino 	    {
1049c50c785cSJohn Marino 	      (*_bfd_error_handler)
1050*ef5ccd6cSJohn Marino 		(_("%B: unable to initialize decompress status for section %s"),
1051c50c785cSJohn Marino 		 abfd, name);
1052c50c785cSJohn Marino 	      return FALSE;
1053c50c785cSJohn Marino 	    }
1054c50c785cSJohn Marino 	  if (name[1] == 'z')
1055c50c785cSJohn Marino 	    {
1056c50c785cSJohn Marino 	      unsigned int len = strlen (name);
1057c50c785cSJohn Marino 
1058c50c785cSJohn Marino 	      new_name = bfd_alloc (abfd, len);
1059c50c785cSJohn Marino 	      if (new_name == NULL)
1060c50c785cSJohn Marino 		return FALSE;
1061c50c785cSJohn Marino 	      new_name[0] = '.';
1062c50c785cSJohn Marino 	      memcpy (new_name + 1, name + 2, len - 1);
1063c50c785cSJohn Marino 	    }
1064c50c785cSJohn Marino 	  break;
1065c50c785cSJohn Marino 	}
1066c50c785cSJohn Marino       if (new_name != NULL)
1067c50c785cSJohn Marino 	bfd_rename_section (abfd, newsect, new_name);
1068c50c785cSJohn Marino     }
1069c50c785cSJohn Marino 
10705796c8dcSSimon Schubert   return TRUE;
10715796c8dcSSimon Schubert }
10725796c8dcSSimon Schubert 
10735796c8dcSSimon Schubert const char *const bfd_elf_section_type_names[] = {
10745796c8dcSSimon Schubert   "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
10755796c8dcSSimon Schubert   "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
10765796c8dcSSimon Schubert   "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
10775796c8dcSSimon Schubert };
10785796c8dcSSimon Schubert 
10795796c8dcSSimon Schubert /* ELF relocs are against symbols.  If we are producing relocatable
10805796c8dcSSimon Schubert    output, and the reloc is against an external symbol, and nothing
10815796c8dcSSimon Schubert    has given us any additional addend, the resulting reloc will also
10825796c8dcSSimon Schubert    be against the same symbol.  In such a case, we don't want to
10835796c8dcSSimon Schubert    change anything about the way the reloc is handled, since it will
10845796c8dcSSimon Schubert    all be done at final link time.  Rather than put special case code
10855796c8dcSSimon Schubert    into bfd_perform_relocation, all the reloc types use this howto
10865796c8dcSSimon Schubert    function.  It just short circuits the reloc if producing
10875796c8dcSSimon Schubert    relocatable output against an external symbol.  */
10885796c8dcSSimon Schubert 
10895796c8dcSSimon Schubert bfd_reloc_status_type
bfd_elf_generic_reloc(bfd * abfd ATTRIBUTE_UNUSED,arelent * reloc_entry,asymbol * symbol,void * data ATTRIBUTE_UNUSED,asection * input_section,bfd * output_bfd,char ** error_message ATTRIBUTE_UNUSED)10905796c8dcSSimon Schubert bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
10915796c8dcSSimon Schubert 		       arelent *reloc_entry,
10925796c8dcSSimon Schubert 		       asymbol *symbol,
10935796c8dcSSimon Schubert 		       void *data ATTRIBUTE_UNUSED,
10945796c8dcSSimon Schubert 		       asection *input_section,
10955796c8dcSSimon Schubert 		       bfd *output_bfd,
10965796c8dcSSimon Schubert 		       char **error_message ATTRIBUTE_UNUSED)
10975796c8dcSSimon Schubert {
10985796c8dcSSimon Schubert   if (output_bfd != NULL
10995796c8dcSSimon Schubert       && (symbol->flags & BSF_SECTION_SYM) == 0
11005796c8dcSSimon Schubert       && (! reloc_entry->howto->partial_inplace
11015796c8dcSSimon Schubert 	  || reloc_entry->addend == 0))
11025796c8dcSSimon Schubert     {
11035796c8dcSSimon Schubert       reloc_entry->address += input_section->output_offset;
11045796c8dcSSimon Schubert       return bfd_reloc_ok;
11055796c8dcSSimon Schubert     }
11065796c8dcSSimon Schubert 
11075796c8dcSSimon Schubert   return bfd_reloc_continue;
11085796c8dcSSimon Schubert }
11095796c8dcSSimon Schubert 
11105796c8dcSSimon Schubert /* Copy the program header and other data from one object module to
11115796c8dcSSimon Schubert    another.  */
11125796c8dcSSimon Schubert 
11135796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_bfd_data(bfd * ibfd,bfd * obfd)11145796c8dcSSimon Schubert _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
11155796c8dcSSimon Schubert {
11165796c8dcSSimon Schubert   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
11175796c8dcSSimon Schubert       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
11185796c8dcSSimon Schubert     return TRUE;
11195796c8dcSSimon Schubert 
11205796c8dcSSimon Schubert   BFD_ASSERT (!elf_flags_init (obfd)
11215796c8dcSSimon Schubert 	      || (elf_elfheader (obfd)->e_flags
11225796c8dcSSimon Schubert 		  == elf_elfheader (ibfd)->e_flags));
11235796c8dcSSimon Schubert 
11245796c8dcSSimon Schubert   elf_gp (obfd) = elf_gp (ibfd);
11255796c8dcSSimon Schubert   elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
11265796c8dcSSimon Schubert   elf_flags_init (obfd) = TRUE;
11275796c8dcSSimon Schubert 
11285796c8dcSSimon Schubert   /* Copy object attributes.  */
11295796c8dcSSimon Schubert   _bfd_elf_copy_obj_attributes (ibfd, obfd);
11305796c8dcSSimon Schubert   return TRUE;
11315796c8dcSSimon Schubert }
11325796c8dcSSimon Schubert 
11335796c8dcSSimon Schubert static const char *
get_segment_type(unsigned int p_type)11345796c8dcSSimon Schubert get_segment_type (unsigned int p_type)
11355796c8dcSSimon Schubert {
11365796c8dcSSimon Schubert   const char *pt;
11375796c8dcSSimon Schubert   switch (p_type)
11385796c8dcSSimon Schubert     {
11395796c8dcSSimon Schubert     case PT_NULL: pt = "NULL"; break;
11405796c8dcSSimon Schubert     case PT_LOAD: pt = "LOAD"; break;
11415796c8dcSSimon Schubert     case PT_DYNAMIC: pt = "DYNAMIC"; break;
11425796c8dcSSimon Schubert     case PT_INTERP: pt = "INTERP"; break;
11435796c8dcSSimon Schubert     case PT_NOTE: pt = "NOTE"; break;
11445796c8dcSSimon Schubert     case PT_SHLIB: pt = "SHLIB"; break;
11455796c8dcSSimon Schubert     case PT_PHDR: pt = "PHDR"; break;
11465796c8dcSSimon Schubert     case PT_TLS: pt = "TLS"; break;
11475796c8dcSSimon Schubert     case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
11485796c8dcSSimon Schubert     case PT_GNU_STACK: pt = "STACK"; break;
11495796c8dcSSimon Schubert     case PT_GNU_RELRO: pt = "RELRO"; break;
11505796c8dcSSimon Schubert     default: pt = NULL; break;
11515796c8dcSSimon Schubert     }
11525796c8dcSSimon Schubert   return pt;
11535796c8dcSSimon Schubert }
11545796c8dcSSimon Schubert 
11555796c8dcSSimon Schubert /* Print out the program headers.  */
11565796c8dcSSimon Schubert 
11575796c8dcSSimon Schubert bfd_boolean
_bfd_elf_print_private_bfd_data(bfd * abfd,void * farg)11585796c8dcSSimon Schubert _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
11595796c8dcSSimon Schubert {
11605796c8dcSSimon Schubert   FILE *f = (FILE *) farg;
11615796c8dcSSimon Schubert   Elf_Internal_Phdr *p;
11625796c8dcSSimon Schubert   asection *s;
11635796c8dcSSimon Schubert   bfd_byte *dynbuf = NULL;
11645796c8dcSSimon Schubert 
11655796c8dcSSimon Schubert   p = elf_tdata (abfd)->phdr;
11665796c8dcSSimon Schubert   if (p != NULL)
11675796c8dcSSimon Schubert     {
11685796c8dcSSimon Schubert       unsigned int i, c;
11695796c8dcSSimon Schubert 
11705796c8dcSSimon Schubert       fprintf (f, _("\nProgram Header:\n"));
11715796c8dcSSimon Schubert       c = elf_elfheader (abfd)->e_phnum;
11725796c8dcSSimon Schubert       for (i = 0; i < c; i++, p++)
11735796c8dcSSimon Schubert 	{
11745796c8dcSSimon Schubert 	  const char *pt = get_segment_type (p->p_type);
11755796c8dcSSimon Schubert 	  char buf[20];
11765796c8dcSSimon Schubert 
11775796c8dcSSimon Schubert 	  if (pt == NULL)
11785796c8dcSSimon Schubert 	    {
11795796c8dcSSimon Schubert 	      sprintf (buf, "0x%lx", p->p_type);
11805796c8dcSSimon Schubert 	      pt = buf;
11815796c8dcSSimon Schubert 	    }
11825796c8dcSSimon Schubert 	  fprintf (f, "%8s off    0x", pt);
11835796c8dcSSimon Schubert 	  bfd_fprintf_vma (abfd, f, p->p_offset);
11845796c8dcSSimon Schubert 	  fprintf (f, " vaddr 0x");
11855796c8dcSSimon Schubert 	  bfd_fprintf_vma (abfd, f, p->p_vaddr);
11865796c8dcSSimon Schubert 	  fprintf (f, " paddr 0x");
11875796c8dcSSimon Schubert 	  bfd_fprintf_vma (abfd, f, p->p_paddr);
11885796c8dcSSimon Schubert 	  fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
11895796c8dcSSimon Schubert 	  fprintf (f, "         filesz 0x");
11905796c8dcSSimon Schubert 	  bfd_fprintf_vma (abfd, f, p->p_filesz);
11915796c8dcSSimon Schubert 	  fprintf (f, " memsz 0x");
11925796c8dcSSimon Schubert 	  bfd_fprintf_vma (abfd, f, p->p_memsz);
11935796c8dcSSimon Schubert 	  fprintf (f, " flags %c%c%c",
11945796c8dcSSimon Schubert 		   (p->p_flags & PF_R) != 0 ? 'r' : '-',
11955796c8dcSSimon Schubert 		   (p->p_flags & PF_W) != 0 ? 'w' : '-',
11965796c8dcSSimon Schubert 		   (p->p_flags & PF_X) != 0 ? 'x' : '-');
11975796c8dcSSimon Schubert 	  if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
11985796c8dcSSimon Schubert 	    fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
11995796c8dcSSimon Schubert 	  fprintf (f, "\n");
12005796c8dcSSimon Schubert 	}
12015796c8dcSSimon Schubert     }
12025796c8dcSSimon Schubert 
12035796c8dcSSimon Schubert   s = bfd_get_section_by_name (abfd, ".dynamic");
12045796c8dcSSimon Schubert   if (s != NULL)
12055796c8dcSSimon Schubert     {
12065796c8dcSSimon Schubert       unsigned int elfsec;
12075796c8dcSSimon Schubert       unsigned long shlink;
12085796c8dcSSimon Schubert       bfd_byte *extdyn, *extdynend;
12095796c8dcSSimon Schubert       size_t extdynsize;
12105796c8dcSSimon Schubert       void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
12115796c8dcSSimon Schubert 
12125796c8dcSSimon Schubert       fprintf (f, _("\nDynamic Section:\n"));
12135796c8dcSSimon Schubert 
12145796c8dcSSimon Schubert       if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
12155796c8dcSSimon Schubert 	goto error_return;
12165796c8dcSSimon Schubert 
12175796c8dcSSimon Schubert       elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
12185796c8dcSSimon Schubert       if (elfsec == SHN_BAD)
12195796c8dcSSimon Schubert 	goto error_return;
12205796c8dcSSimon Schubert       shlink = elf_elfsections (abfd)[elfsec]->sh_link;
12215796c8dcSSimon Schubert 
12225796c8dcSSimon Schubert       extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
12235796c8dcSSimon Schubert       swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
12245796c8dcSSimon Schubert 
12255796c8dcSSimon Schubert       extdyn = dynbuf;
12265796c8dcSSimon Schubert       extdynend = extdyn + s->size;
12275796c8dcSSimon Schubert       for (; extdyn < extdynend; extdyn += extdynsize)
12285796c8dcSSimon Schubert 	{
12295796c8dcSSimon Schubert 	  Elf_Internal_Dyn dyn;
12305796c8dcSSimon Schubert 	  const char *name = "";
12315796c8dcSSimon Schubert 	  char ab[20];
12325796c8dcSSimon Schubert 	  bfd_boolean stringp;
12335796c8dcSSimon Schubert 	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
12345796c8dcSSimon Schubert 
12355796c8dcSSimon Schubert 	  (*swap_dyn_in) (abfd, extdyn, &dyn);
12365796c8dcSSimon Schubert 
12375796c8dcSSimon Schubert 	  if (dyn.d_tag == DT_NULL)
12385796c8dcSSimon Schubert 	    break;
12395796c8dcSSimon Schubert 
12405796c8dcSSimon Schubert 	  stringp = FALSE;
12415796c8dcSSimon Schubert 	  switch (dyn.d_tag)
12425796c8dcSSimon Schubert 	    {
12435796c8dcSSimon Schubert 	    default:
12445796c8dcSSimon Schubert 	      if (bed->elf_backend_get_target_dtag)
12455796c8dcSSimon Schubert 		name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
12465796c8dcSSimon Schubert 
12475796c8dcSSimon Schubert 	      if (!strcmp (name, ""))
12485796c8dcSSimon Schubert 		{
12495796c8dcSSimon Schubert 		  sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
12505796c8dcSSimon Schubert 		  name = ab;
12515796c8dcSSimon Schubert 		}
12525796c8dcSSimon Schubert 	      break;
12535796c8dcSSimon Schubert 
12545796c8dcSSimon Schubert 	    case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
12555796c8dcSSimon Schubert 	    case DT_PLTRELSZ: name = "PLTRELSZ"; break;
12565796c8dcSSimon Schubert 	    case DT_PLTGOT: name = "PLTGOT"; break;
12575796c8dcSSimon Schubert 	    case DT_HASH: name = "HASH"; break;
12585796c8dcSSimon Schubert 	    case DT_STRTAB: name = "STRTAB"; break;
12595796c8dcSSimon Schubert 	    case DT_SYMTAB: name = "SYMTAB"; break;
12605796c8dcSSimon Schubert 	    case DT_RELA: name = "RELA"; break;
12615796c8dcSSimon Schubert 	    case DT_RELASZ: name = "RELASZ"; break;
12625796c8dcSSimon Schubert 	    case DT_RELAENT: name = "RELAENT"; break;
12635796c8dcSSimon Schubert 	    case DT_STRSZ: name = "STRSZ"; break;
12645796c8dcSSimon Schubert 	    case DT_SYMENT: name = "SYMENT"; break;
12655796c8dcSSimon Schubert 	    case DT_INIT: name = "INIT"; break;
12665796c8dcSSimon Schubert 	    case DT_FINI: name = "FINI"; break;
12675796c8dcSSimon Schubert 	    case DT_SONAME: name = "SONAME"; stringp = TRUE; break;
12685796c8dcSSimon Schubert 	    case DT_RPATH: name = "RPATH"; stringp = TRUE; break;
12695796c8dcSSimon Schubert 	    case DT_SYMBOLIC: name = "SYMBOLIC"; break;
12705796c8dcSSimon Schubert 	    case DT_REL: name = "REL"; break;
12715796c8dcSSimon Schubert 	    case DT_RELSZ: name = "RELSZ"; break;
12725796c8dcSSimon Schubert 	    case DT_RELENT: name = "RELENT"; break;
12735796c8dcSSimon Schubert 	    case DT_PLTREL: name = "PLTREL"; break;
12745796c8dcSSimon Schubert 	    case DT_DEBUG: name = "DEBUG"; break;
12755796c8dcSSimon Schubert 	    case DT_TEXTREL: name = "TEXTREL"; break;
12765796c8dcSSimon Schubert 	    case DT_JMPREL: name = "JMPREL"; break;
12775796c8dcSSimon Schubert 	    case DT_BIND_NOW: name = "BIND_NOW"; break;
12785796c8dcSSimon Schubert 	    case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
12795796c8dcSSimon Schubert 	    case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
12805796c8dcSSimon Schubert 	    case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
12815796c8dcSSimon Schubert 	    case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
12825796c8dcSSimon Schubert 	    case DT_RUNPATH: name = "RUNPATH"; stringp = TRUE; break;
12835796c8dcSSimon Schubert 	    case DT_FLAGS: name = "FLAGS"; break;
12845796c8dcSSimon Schubert 	    case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
12855796c8dcSSimon Schubert 	    case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
12865796c8dcSSimon Schubert 	    case DT_CHECKSUM: name = "CHECKSUM"; break;
12875796c8dcSSimon Schubert 	    case DT_PLTPADSZ: name = "PLTPADSZ"; break;
12885796c8dcSSimon Schubert 	    case DT_MOVEENT: name = "MOVEENT"; break;
12895796c8dcSSimon Schubert 	    case DT_MOVESZ: name = "MOVESZ"; break;
12905796c8dcSSimon Schubert 	    case DT_FEATURE: name = "FEATURE"; break;
12915796c8dcSSimon Schubert 	    case DT_POSFLAG_1: name = "POSFLAG_1"; break;
12925796c8dcSSimon Schubert 	    case DT_SYMINSZ: name = "SYMINSZ"; break;
12935796c8dcSSimon Schubert 	    case DT_SYMINENT: name = "SYMINENT"; break;
12945796c8dcSSimon Schubert 	    case DT_CONFIG: name = "CONFIG"; stringp = TRUE; break;
12955796c8dcSSimon Schubert 	    case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = TRUE; break;
12965796c8dcSSimon Schubert 	    case DT_AUDIT: name = "AUDIT"; stringp = TRUE; break;
12975796c8dcSSimon Schubert 	    case DT_PLTPAD: name = "PLTPAD"; break;
12985796c8dcSSimon Schubert 	    case DT_MOVETAB: name = "MOVETAB"; break;
12995796c8dcSSimon Schubert 	    case DT_SYMINFO: name = "SYMINFO"; break;
13005796c8dcSSimon Schubert 	    case DT_RELACOUNT: name = "RELACOUNT"; break;
13015796c8dcSSimon Schubert 	    case DT_RELCOUNT: name = "RELCOUNT"; break;
13025796c8dcSSimon Schubert 	    case DT_FLAGS_1: name = "FLAGS_1"; break;
13035796c8dcSSimon Schubert 	    case DT_VERSYM: name = "VERSYM"; break;
13045796c8dcSSimon Schubert 	    case DT_VERDEF: name = "VERDEF"; break;
13055796c8dcSSimon Schubert 	    case DT_VERDEFNUM: name = "VERDEFNUM"; break;
13065796c8dcSSimon Schubert 	    case DT_VERNEED: name = "VERNEED"; break;
13075796c8dcSSimon Schubert 	    case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
13085796c8dcSSimon Schubert 	    case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
13095796c8dcSSimon Schubert 	    case DT_USED: name = "USED"; break;
13105796c8dcSSimon Schubert 	    case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
13115796c8dcSSimon Schubert 	    case DT_GNU_HASH: name = "GNU_HASH"; break;
13125796c8dcSSimon Schubert 	    }
13135796c8dcSSimon Schubert 
13145796c8dcSSimon Schubert 	  fprintf (f, "  %-20s ", name);
13155796c8dcSSimon Schubert 	  if (! stringp)
13165796c8dcSSimon Schubert 	    {
13175796c8dcSSimon Schubert 	      fprintf (f, "0x");
13185796c8dcSSimon Schubert 	      bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
13195796c8dcSSimon Schubert 	    }
13205796c8dcSSimon Schubert 	  else
13215796c8dcSSimon Schubert 	    {
13225796c8dcSSimon Schubert 	      const char *string;
13235796c8dcSSimon Schubert 	      unsigned int tagv = dyn.d_un.d_val;
13245796c8dcSSimon Schubert 
13255796c8dcSSimon Schubert 	      string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
13265796c8dcSSimon Schubert 	      if (string == NULL)
13275796c8dcSSimon Schubert 		goto error_return;
13285796c8dcSSimon Schubert 	      fprintf (f, "%s", string);
13295796c8dcSSimon Schubert 	    }
13305796c8dcSSimon Schubert 	  fprintf (f, "\n");
13315796c8dcSSimon Schubert 	}
13325796c8dcSSimon Schubert 
13335796c8dcSSimon Schubert       free (dynbuf);
13345796c8dcSSimon Schubert       dynbuf = NULL;
13355796c8dcSSimon Schubert     }
13365796c8dcSSimon Schubert 
13375796c8dcSSimon Schubert   if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
13385796c8dcSSimon Schubert       || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
13395796c8dcSSimon Schubert     {
13405796c8dcSSimon Schubert       if (! _bfd_elf_slurp_version_tables (abfd, FALSE))
13415796c8dcSSimon Schubert 	return FALSE;
13425796c8dcSSimon Schubert     }
13435796c8dcSSimon Schubert 
13445796c8dcSSimon Schubert   if (elf_dynverdef (abfd) != 0)
13455796c8dcSSimon Schubert     {
13465796c8dcSSimon Schubert       Elf_Internal_Verdef *t;
13475796c8dcSSimon Schubert 
13485796c8dcSSimon Schubert       fprintf (f, _("\nVersion definitions:\n"));
13495796c8dcSSimon Schubert       for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
13505796c8dcSSimon Schubert 	{
13515796c8dcSSimon Schubert 	  fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
13525796c8dcSSimon Schubert 		   t->vd_flags, t->vd_hash,
13535796c8dcSSimon Schubert 		   t->vd_nodename ? t->vd_nodename : "<corrupt>");
13545796c8dcSSimon Schubert 	  if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
13555796c8dcSSimon Schubert 	    {
13565796c8dcSSimon Schubert 	      Elf_Internal_Verdaux *a;
13575796c8dcSSimon Schubert 
13585796c8dcSSimon Schubert 	      fprintf (f, "\t");
13595796c8dcSSimon Schubert 	      for (a = t->vd_auxptr->vda_nextptr;
13605796c8dcSSimon Schubert 		   a != NULL;
13615796c8dcSSimon Schubert 		   a = a->vda_nextptr)
13625796c8dcSSimon Schubert 		fprintf (f, "%s ",
13635796c8dcSSimon Schubert 			 a->vda_nodename ? a->vda_nodename : "<corrupt>");
13645796c8dcSSimon Schubert 	      fprintf (f, "\n");
13655796c8dcSSimon Schubert 	    }
13665796c8dcSSimon Schubert 	}
13675796c8dcSSimon Schubert     }
13685796c8dcSSimon Schubert 
13695796c8dcSSimon Schubert   if (elf_dynverref (abfd) != 0)
13705796c8dcSSimon Schubert     {
13715796c8dcSSimon Schubert       Elf_Internal_Verneed *t;
13725796c8dcSSimon Schubert 
13735796c8dcSSimon Schubert       fprintf (f, _("\nVersion References:\n"));
13745796c8dcSSimon Schubert       for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
13755796c8dcSSimon Schubert 	{
13765796c8dcSSimon Schubert 	  Elf_Internal_Vernaux *a;
13775796c8dcSSimon Schubert 
13785796c8dcSSimon Schubert 	  fprintf (f, _("  required from %s:\n"),
13795796c8dcSSimon Schubert 		   t->vn_filename ? t->vn_filename : "<corrupt>");
13805796c8dcSSimon Schubert 	  for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
13815796c8dcSSimon Schubert 	    fprintf (f, "    0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
13825796c8dcSSimon Schubert 		     a->vna_flags, a->vna_other,
13835796c8dcSSimon Schubert 		     a->vna_nodename ? a->vna_nodename : "<corrupt>");
13845796c8dcSSimon Schubert 	}
13855796c8dcSSimon Schubert     }
13865796c8dcSSimon Schubert 
13875796c8dcSSimon Schubert   return TRUE;
13885796c8dcSSimon Schubert 
13895796c8dcSSimon Schubert  error_return:
13905796c8dcSSimon Schubert   if (dynbuf != NULL)
13915796c8dcSSimon Schubert     free (dynbuf);
13925796c8dcSSimon Schubert   return FALSE;
13935796c8dcSSimon Schubert }
13945796c8dcSSimon Schubert 
13955796c8dcSSimon Schubert /* Display ELF-specific fields of a symbol.  */
13965796c8dcSSimon Schubert 
13975796c8dcSSimon Schubert void
bfd_elf_print_symbol(bfd * abfd,void * filep,asymbol * symbol,bfd_print_symbol_type how)13985796c8dcSSimon Schubert bfd_elf_print_symbol (bfd *abfd,
13995796c8dcSSimon Schubert 		      void *filep,
14005796c8dcSSimon Schubert 		      asymbol *symbol,
14015796c8dcSSimon Schubert 		      bfd_print_symbol_type how)
14025796c8dcSSimon Schubert {
14035796c8dcSSimon Schubert   FILE *file = (FILE *) filep;
14045796c8dcSSimon Schubert   switch (how)
14055796c8dcSSimon Schubert     {
14065796c8dcSSimon Schubert     case bfd_print_symbol_name:
14075796c8dcSSimon Schubert       fprintf (file, "%s", symbol->name);
14085796c8dcSSimon Schubert       break;
14095796c8dcSSimon Schubert     case bfd_print_symbol_more:
14105796c8dcSSimon Schubert       fprintf (file, "elf ");
14115796c8dcSSimon Schubert       bfd_fprintf_vma (abfd, file, symbol->value);
14125796c8dcSSimon Schubert       fprintf (file, " %lx", (unsigned long) symbol->flags);
14135796c8dcSSimon Schubert       break;
14145796c8dcSSimon Schubert     case bfd_print_symbol_all:
14155796c8dcSSimon Schubert       {
14165796c8dcSSimon Schubert 	const char *section_name;
14175796c8dcSSimon Schubert 	const char *name = NULL;
14185796c8dcSSimon Schubert 	const struct elf_backend_data *bed;
14195796c8dcSSimon Schubert 	unsigned char st_other;
14205796c8dcSSimon Schubert 	bfd_vma val;
14215796c8dcSSimon Schubert 
14225796c8dcSSimon Schubert 	section_name = symbol->section ? symbol->section->name : "(*none*)";
14235796c8dcSSimon Schubert 
14245796c8dcSSimon Schubert 	bed = get_elf_backend_data (abfd);
14255796c8dcSSimon Schubert 	if (bed->elf_backend_print_symbol_all)
14265796c8dcSSimon Schubert 	  name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
14275796c8dcSSimon Schubert 
14285796c8dcSSimon Schubert 	if (name == NULL)
14295796c8dcSSimon Schubert 	  {
14305796c8dcSSimon Schubert 	    name = symbol->name;
14315796c8dcSSimon Schubert 	    bfd_print_symbol_vandf (abfd, file, symbol);
14325796c8dcSSimon Schubert 	  }
14335796c8dcSSimon Schubert 
14345796c8dcSSimon Schubert 	fprintf (file, " %s\t", section_name);
14355796c8dcSSimon Schubert 	/* Print the "other" value for a symbol.  For common symbols,
14365796c8dcSSimon Schubert 	   we've already printed the size; now print the alignment.
14375796c8dcSSimon Schubert 	   For other symbols, we have no specified alignment, and
14385796c8dcSSimon Schubert 	   we've printed the address; now print the size.  */
14395796c8dcSSimon Schubert 	if (symbol->section && bfd_is_com_section (symbol->section))
14405796c8dcSSimon Schubert 	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
14415796c8dcSSimon Schubert 	else
14425796c8dcSSimon Schubert 	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
14435796c8dcSSimon Schubert 	bfd_fprintf_vma (abfd, file, val);
14445796c8dcSSimon Schubert 
14455796c8dcSSimon Schubert 	/* If we have version information, print it.  */
1446*ef5ccd6cSJohn Marino 	if (elf_dynversym (abfd) != 0
1447*ef5ccd6cSJohn Marino 	    && (elf_dynverdef (abfd) != 0
1448*ef5ccd6cSJohn Marino 		|| elf_dynverref (abfd) != 0))
14495796c8dcSSimon Schubert 	  {
14505796c8dcSSimon Schubert 	    unsigned int vernum;
14515796c8dcSSimon Schubert 	    const char *version_string;
14525796c8dcSSimon Schubert 
14535796c8dcSSimon Schubert 	    vernum = ((elf_symbol_type *) symbol)->version & VERSYM_VERSION;
14545796c8dcSSimon Schubert 
14555796c8dcSSimon Schubert 	    if (vernum == 0)
14565796c8dcSSimon Schubert 	      version_string = "";
14575796c8dcSSimon Schubert 	    else if (vernum == 1)
14585796c8dcSSimon Schubert 	      version_string = "Base";
14595796c8dcSSimon Schubert 	    else if (vernum <= elf_tdata (abfd)->cverdefs)
14605796c8dcSSimon Schubert 	      version_string =
14615796c8dcSSimon Schubert 		elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
14625796c8dcSSimon Schubert 	    else
14635796c8dcSSimon Schubert 	      {
14645796c8dcSSimon Schubert 		Elf_Internal_Verneed *t;
14655796c8dcSSimon Schubert 
14665796c8dcSSimon Schubert 		version_string = "";
14675796c8dcSSimon Schubert 		for (t = elf_tdata (abfd)->verref;
14685796c8dcSSimon Schubert 		     t != NULL;
14695796c8dcSSimon Schubert 		     t = t->vn_nextref)
14705796c8dcSSimon Schubert 		  {
14715796c8dcSSimon Schubert 		    Elf_Internal_Vernaux *a;
14725796c8dcSSimon Schubert 
14735796c8dcSSimon Schubert 		    for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
14745796c8dcSSimon Schubert 		      {
14755796c8dcSSimon Schubert 			if (a->vna_other == vernum)
14765796c8dcSSimon Schubert 			  {
14775796c8dcSSimon Schubert 			    version_string = a->vna_nodename;
14785796c8dcSSimon Schubert 			    break;
14795796c8dcSSimon Schubert 			  }
14805796c8dcSSimon Schubert 		      }
14815796c8dcSSimon Schubert 		  }
14825796c8dcSSimon Schubert 	      }
14835796c8dcSSimon Schubert 
14845796c8dcSSimon Schubert 	    if ((((elf_symbol_type *) symbol)->version & VERSYM_HIDDEN) == 0)
14855796c8dcSSimon Schubert 	      fprintf (file, "  %-11s", version_string);
14865796c8dcSSimon Schubert 	    else
14875796c8dcSSimon Schubert 	      {
14885796c8dcSSimon Schubert 		int i;
14895796c8dcSSimon Schubert 
14905796c8dcSSimon Schubert 		fprintf (file, " (%s)", version_string);
14915796c8dcSSimon Schubert 		for (i = 10 - strlen (version_string); i > 0; --i)
14925796c8dcSSimon Schubert 		  putc (' ', file);
14935796c8dcSSimon Schubert 	      }
14945796c8dcSSimon Schubert 	  }
14955796c8dcSSimon Schubert 
14965796c8dcSSimon Schubert 	/* If the st_other field is not zero, print it.  */
14975796c8dcSSimon Schubert 	st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
14985796c8dcSSimon Schubert 
14995796c8dcSSimon Schubert 	switch (st_other)
15005796c8dcSSimon Schubert 	  {
15015796c8dcSSimon Schubert 	  case 0: break;
15025796c8dcSSimon Schubert 	  case STV_INTERNAL:  fprintf (file, " .internal");  break;
15035796c8dcSSimon Schubert 	  case STV_HIDDEN:    fprintf (file, " .hidden");    break;
15045796c8dcSSimon Schubert 	  case STV_PROTECTED: fprintf (file, " .protected"); break;
15055796c8dcSSimon Schubert 	  default:
15065796c8dcSSimon Schubert 	    /* Some other non-defined flags are also present, so print
15075796c8dcSSimon Schubert 	       everything hex.  */
15085796c8dcSSimon Schubert 	    fprintf (file, " 0x%02x", (unsigned int) st_other);
15095796c8dcSSimon Schubert 	  }
15105796c8dcSSimon Schubert 
15115796c8dcSSimon Schubert 	fprintf (file, " %s", name);
15125796c8dcSSimon Schubert       }
15135796c8dcSSimon Schubert       break;
15145796c8dcSSimon Schubert     }
15155796c8dcSSimon Schubert }
15165796c8dcSSimon Schubert 
15175796c8dcSSimon Schubert /* Allocate an ELF string table--force the first byte to be zero.  */
15185796c8dcSSimon Schubert 
15195796c8dcSSimon Schubert struct bfd_strtab_hash *
_bfd_elf_stringtab_init(void)15205796c8dcSSimon Schubert _bfd_elf_stringtab_init (void)
15215796c8dcSSimon Schubert {
15225796c8dcSSimon Schubert   struct bfd_strtab_hash *ret;
15235796c8dcSSimon Schubert 
15245796c8dcSSimon Schubert   ret = _bfd_stringtab_init ();
15255796c8dcSSimon Schubert   if (ret != NULL)
15265796c8dcSSimon Schubert     {
15275796c8dcSSimon Schubert       bfd_size_type loc;
15285796c8dcSSimon Schubert 
15295796c8dcSSimon Schubert       loc = _bfd_stringtab_add (ret, "", TRUE, FALSE);
15305796c8dcSSimon Schubert       BFD_ASSERT (loc == 0 || loc == (bfd_size_type) -1);
15315796c8dcSSimon Schubert       if (loc == (bfd_size_type) -1)
15325796c8dcSSimon Schubert 	{
15335796c8dcSSimon Schubert 	  _bfd_stringtab_free (ret);
15345796c8dcSSimon Schubert 	  ret = NULL;
15355796c8dcSSimon Schubert 	}
15365796c8dcSSimon Schubert     }
15375796c8dcSSimon Schubert   return ret;
15385796c8dcSSimon Schubert }
15395796c8dcSSimon Schubert 
15405796c8dcSSimon Schubert /* ELF .o/exec file reading */
15415796c8dcSSimon Schubert 
15425796c8dcSSimon Schubert /* Create a new bfd section from an ELF section header.  */
15435796c8dcSSimon Schubert 
15445796c8dcSSimon Schubert bfd_boolean
bfd_section_from_shdr(bfd * abfd,unsigned int shindex)15455796c8dcSSimon Schubert bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
15465796c8dcSSimon Schubert {
15475796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr;
15485796c8dcSSimon Schubert   Elf_Internal_Ehdr *ehdr;
15495796c8dcSSimon Schubert   const struct elf_backend_data *bed;
15505796c8dcSSimon Schubert   const char *name;
15515796c8dcSSimon Schubert 
15525796c8dcSSimon Schubert   if (shindex >= elf_numsections (abfd))
15535796c8dcSSimon Schubert     return FALSE;
15545796c8dcSSimon Schubert 
15555796c8dcSSimon Schubert   hdr = elf_elfsections (abfd)[shindex];
15565796c8dcSSimon Schubert   ehdr = elf_elfheader (abfd);
15575796c8dcSSimon Schubert   name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
15585796c8dcSSimon Schubert 					  hdr->sh_name);
15595796c8dcSSimon Schubert   if (name == NULL)
15605796c8dcSSimon Schubert     return FALSE;
15615796c8dcSSimon Schubert 
15625796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
15635796c8dcSSimon Schubert   switch (hdr->sh_type)
15645796c8dcSSimon Schubert     {
15655796c8dcSSimon Schubert     case SHT_NULL:
15665796c8dcSSimon Schubert       /* Inactive section. Throw it away.  */
15675796c8dcSSimon Schubert       return TRUE;
15685796c8dcSSimon Schubert 
15695796c8dcSSimon Schubert     case SHT_PROGBITS:	/* Normal section with contents.  */
15705796c8dcSSimon Schubert     case SHT_NOBITS:	/* .bss section.  */
15715796c8dcSSimon Schubert     case SHT_HASH:	/* .hash section.  */
15725796c8dcSSimon Schubert     case SHT_NOTE:	/* .note section.  */
15735796c8dcSSimon Schubert     case SHT_INIT_ARRAY:	/* .init_array section.  */
15745796c8dcSSimon Schubert     case SHT_FINI_ARRAY:	/* .fini_array section.  */
15755796c8dcSSimon Schubert     case SHT_PREINIT_ARRAY:	/* .preinit_array section.  */
15765796c8dcSSimon Schubert     case SHT_GNU_LIBLIST:	/* .gnu.liblist section.  */
15775796c8dcSSimon Schubert     case SHT_GNU_HASH:		/* .gnu.hash section.  */
15785796c8dcSSimon Schubert       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
15795796c8dcSSimon Schubert 
15805796c8dcSSimon Schubert     case SHT_DYNAMIC:	/* Dynamic linking information.  */
15815796c8dcSSimon Schubert       if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
15825796c8dcSSimon Schubert 	return FALSE;
15835796c8dcSSimon Schubert       if (hdr->sh_link > elf_numsections (abfd))
15845796c8dcSSimon Schubert 	{
1585cf7f2e2dSJohn Marino 	  /* PR 10478: Accept Solaris binaries with a sh_link
15865796c8dcSSimon Schubert 	     field set to SHN_BEFORE or SHN_AFTER.  */
15875796c8dcSSimon Schubert 	  switch (bfd_get_arch (abfd))
15885796c8dcSSimon Schubert 	    {
1589cf7f2e2dSJohn Marino 	    case bfd_arch_i386:
15905796c8dcSSimon Schubert 	    case bfd_arch_sparc:
15915796c8dcSSimon Schubert 	      if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
15925796c8dcSSimon Schubert 		  || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
15935796c8dcSSimon Schubert 		break;
15945796c8dcSSimon Schubert 	      /* Otherwise fall through.  */
15955796c8dcSSimon Schubert 	    default:
15965796c8dcSSimon Schubert 	      return FALSE;
15975796c8dcSSimon Schubert 	    }
15985796c8dcSSimon Schubert 	}
15995796c8dcSSimon Schubert       else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
16005796c8dcSSimon Schubert 	return FALSE;
16015796c8dcSSimon Schubert       else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
16025796c8dcSSimon Schubert 	{
16035796c8dcSSimon Schubert 	  Elf_Internal_Shdr *dynsymhdr;
16045796c8dcSSimon Schubert 
16055796c8dcSSimon Schubert 	  /* The shared libraries distributed with hpux11 have a bogus
16065796c8dcSSimon Schubert 	     sh_link field for the ".dynamic" section.  Find the
16075796c8dcSSimon Schubert 	     string table for the ".dynsym" section instead.  */
16085796c8dcSSimon Schubert 	  if (elf_dynsymtab (abfd) != 0)
16095796c8dcSSimon Schubert 	    {
16105796c8dcSSimon Schubert 	      dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
16115796c8dcSSimon Schubert 	      hdr->sh_link = dynsymhdr->sh_link;
16125796c8dcSSimon Schubert 	    }
16135796c8dcSSimon Schubert 	  else
16145796c8dcSSimon Schubert 	    {
16155796c8dcSSimon Schubert 	      unsigned int i, num_sec;
16165796c8dcSSimon Schubert 
16175796c8dcSSimon Schubert 	      num_sec = elf_numsections (abfd);
16185796c8dcSSimon Schubert 	      for (i = 1; i < num_sec; i++)
16195796c8dcSSimon Schubert 		{
16205796c8dcSSimon Schubert 		  dynsymhdr = elf_elfsections (abfd)[i];
16215796c8dcSSimon Schubert 		  if (dynsymhdr->sh_type == SHT_DYNSYM)
16225796c8dcSSimon Schubert 		    {
16235796c8dcSSimon Schubert 		      hdr->sh_link = dynsymhdr->sh_link;
16245796c8dcSSimon Schubert 		      break;
16255796c8dcSSimon Schubert 		    }
16265796c8dcSSimon Schubert 		}
16275796c8dcSSimon Schubert 	    }
16285796c8dcSSimon Schubert 	}
16295796c8dcSSimon Schubert       break;
16305796c8dcSSimon Schubert 
16315796c8dcSSimon Schubert     case SHT_SYMTAB:		/* A symbol table */
16325796c8dcSSimon Schubert       if (elf_onesymtab (abfd) == shindex)
16335796c8dcSSimon Schubert 	return TRUE;
16345796c8dcSSimon Schubert 
16355796c8dcSSimon Schubert       if (hdr->sh_entsize != bed->s->sizeof_sym)
16365796c8dcSSimon Schubert 	return FALSE;
16375796c8dcSSimon Schubert       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
1638*ef5ccd6cSJohn Marino 	{
1639*ef5ccd6cSJohn Marino 	  if (hdr->sh_size != 0)
16405796c8dcSSimon Schubert 	    return FALSE;
1641*ef5ccd6cSJohn Marino 	  /* Some assemblers erroneously set sh_info to one with a
1642*ef5ccd6cSJohn Marino 	     zero sh_size.  ld sees this as a global symbol count
1643*ef5ccd6cSJohn Marino 	     of (unsigned) -1.  Fix it here.  */
1644*ef5ccd6cSJohn Marino 	  hdr->sh_info = 0;
1645*ef5ccd6cSJohn Marino 	  return TRUE;
1646*ef5ccd6cSJohn Marino 	}
16475796c8dcSSimon Schubert       BFD_ASSERT (elf_onesymtab (abfd) == 0);
16485796c8dcSSimon Schubert       elf_onesymtab (abfd) = shindex;
16495796c8dcSSimon Schubert       elf_tdata (abfd)->symtab_hdr = *hdr;
16505796c8dcSSimon Schubert       elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->symtab_hdr;
16515796c8dcSSimon Schubert       abfd->flags |= HAS_SYMS;
16525796c8dcSSimon Schubert 
16535796c8dcSSimon Schubert       /* Sometimes a shared object will map in the symbol table.  If
16545796c8dcSSimon Schubert 	 SHF_ALLOC is set, and this is a shared object, then we also
16555796c8dcSSimon Schubert 	 treat this section as a BFD section.  We can not base the
16565796c8dcSSimon Schubert 	 decision purely on SHF_ALLOC, because that flag is sometimes
16575796c8dcSSimon Schubert 	 set in a relocatable object file, which would confuse the
16585796c8dcSSimon Schubert 	 linker.  */
16595796c8dcSSimon Schubert       if ((hdr->sh_flags & SHF_ALLOC) != 0
16605796c8dcSSimon Schubert 	  && (abfd->flags & DYNAMIC) != 0
16615796c8dcSSimon Schubert 	  && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
16625796c8dcSSimon Schubert 						shindex))
16635796c8dcSSimon Schubert 	return FALSE;
16645796c8dcSSimon Schubert 
16655796c8dcSSimon Schubert       /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
16665796c8dcSSimon Schubert 	 can't read symbols without that section loaded as well.  It
16675796c8dcSSimon Schubert 	 is most likely specified by the next section header.  */
16685796c8dcSSimon Schubert       if (elf_elfsections (abfd)[elf_symtab_shndx (abfd)]->sh_link != shindex)
16695796c8dcSSimon Schubert 	{
16705796c8dcSSimon Schubert 	  unsigned int i, num_sec;
16715796c8dcSSimon Schubert 
16725796c8dcSSimon Schubert 	  num_sec = elf_numsections (abfd);
16735796c8dcSSimon Schubert 	  for (i = shindex + 1; i < num_sec; i++)
16745796c8dcSSimon Schubert 	    {
16755796c8dcSSimon Schubert 	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
16765796c8dcSSimon Schubert 	      if (hdr2->sh_type == SHT_SYMTAB_SHNDX
16775796c8dcSSimon Schubert 		  && hdr2->sh_link == shindex)
16785796c8dcSSimon Schubert 		break;
16795796c8dcSSimon Schubert 	    }
16805796c8dcSSimon Schubert 	  if (i == num_sec)
16815796c8dcSSimon Schubert 	    for (i = 1; i < shindex; i++)
16825796c8dcSSimon Schubert 	      {
16835796c8dcSSimon Schubert 		Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
16845796c8dcSSimon Schubert 		if (hdr2->sh_type == SHT_SYMTAB_SHNDX
16855796c8dcSSimon Schubert 		    && hdr2->sh_link == shindex)
16865796c8dcSSimon Schubert 		  break;
16875796c8dcSSimon Schubert 	      }
16885796c8dcSSimon Schubert 	  if (i != shindex)
16895796c8dcSSimon Schubert 	    return bfd_section_from_shdr (abfd, i);
16905796c8dcSSimon Schubert 	}
16915796c8dcSSimon Schubert       return TRUE;
16925796c8dcSSimon Schubert 
16935796c8dcSSimon Schubert     case SHT_DYNSYM:		/* A dynamic symbol table */
16945796c8dcSSimon Schubert       if (elf_dynsymtab (abfd) == shindex)
16955796c8dcSSimon Schubert 	return TRUE;
16965796c8dcSSimon Schubert 
16975796c8dcSSimon Schubert       if (hdr->sh_entsize != bed->s->sizeof_sym)
16985796c8dcSSimon Schubert 	return FALSE;
1699*ef5ccd6cSJohn Marino       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
1700*ef5ccd6cSJohn Marino 	{
1701*ef5ccd6cSJohn Marino 	  if (hdr->sh_size != 0)
1702*ef5ccd6cSJohn Marino 	    return FALSE;
1703*ef5ccd6cSJohn Marino 	  /* Some linkers erroneously set sh_info to one with a
1704*ef5ccd6cSJohn Marino 	     zero sh_size.  ld sees this as a global symbol count
1705*ef5ccd6cSJohn Marino 	     of (unsigned) -1.  Fix it here.  */
1706*ef5ccd6cSJohn Marino 	  hdr->sh_info = 0;
1707*ef5ccd6cSJohn Marino 	  return TRUE;
1708*ef5ccd6cSJohn Marino 	}
17095796c8dcSSimon Schubert       BFD_ASSERT (elf_dynsymtab (abfd) == 0);
17105796c8dcSSimon Schubert       elf_dynsymtab (abfd) = shindex;
17115796c8dcSSimon Schubert       elf_tdata (abfd)->dynsymtab_hdr = *hdr;
17125796c8dcSSimon Schubert       elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
17135796c8dcSSimon Schubert       abfd->flags |= HAS_SYMS;
17145796c8dcSSimon Schubert 
17155796c8dcSSimon Schubert       /* Besides being a symbol table, we also treat this as a regular
17165796c8dcSSimon Schubert 	 section, so that objcopy can handle it.  */
17175796c8dcSSimon Schubert       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
17185796c8dcSSimon Schubert 
17195796c8dcSSimon Schubert     case SHT_SYMTAB_SHNDX:	/* Symbol section indices when >64k sections */
17205796c8dcSSimon Schubert       if (elf_symtab_shndx (abfd) == shindex)
17215796c8dcSSimon Schubert 	return TRUE;
17225796c8dcSSimon Schubert 
17235796c8dcSSimon Schubert       BFD_ASSERT (elf_symtab_shndx (abfd) == 0);
17245796c8dcSSimon Schubert       elf_symtab_shndx (abfd) = shindex;
17255796c8dcSSimon Schubert       elf_tdata (abfd)->symtab_shndx_hdr = *hdr;
17265796c8dcSSimon Schubert       elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->symtab_shndx_hdr;
17275796c8dcSSimon Schubert       return TRUE;
17285796c8dcSSimon Schubert 
17295796c8dcSSimon Schubert     case SHT_STRTAB:		/* A string table */
17305796c8dcSSimon Schubert       if (hdr->bfd_section != NULL)
17315796c8dcSSimon Schubert 	return TRUE;
17325796c8dcSSimon Schubert       if (ehdr->e_shstrndx == shindex)
17335796c8dcSSimon Schubert 	{
17345796c8dcSSimon Schubert 	  elf_tdata (abfd)->shstrtab_hdr = *hdr;
17355796c8dcSSimon Schubert 	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
17365796c8dcSSimon Schubert 	  return TRUE;
17375796c8dcSSimon Schubert 	}
17385796c8dcSSimon Schubert       if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
17395796c8dcSSimon Schubert 	{
17405796c8dcSSimon Schubert 	symtab_strtab:
17415796c8dcSSimon Schubert 	  elf_tdata (abfd)->strtab_hdr = *hdr;
17425796c8dcSSimon Schubert 	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
17435796c8dcSSimon Schubert 	  return TRUE;
17445796c8dcSSimon Schubert 	}
17455796c8dcSSimon Schubert       if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
17465796c8dcSSimon Schubert 	{
17475796c8dcSSimon Schubert 	dynsymtab_strtab:
17485796c8dcSSimon Schubert 	  elf_tdata (abfd)->dynstrtab_hdr = *hdr;
17495796c8dcSSimon Schubert 	  hdr = &elf_tdata (abfd)->dynstrtab_hdr;
17505796c8dcSSimon Schubert 	  elf_elfsections (abfd)[shindex] = hdr;
17515796c8dcSSimon Schubert 	  /* We also treat this as a regular section, so that objcopy
17525796c8dcSSimon Schubert 	     can handle it.  */
17535796c8dcSSimon Schubert 	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
17545796c8dcSSimon Schubert 						  shindex);
17555796c8dcSSimon Schubert 	}
17565796c8dcSSimon Schubert 
17575796c8dcSSimon Schubert       /* If the string table isn't one of the above, then treat it as a
17585796c8dcSSimon Schubert 	 regular section.  We need to scan all the headers to be sure,
17595796c8dcSSimon Schubert 	 just in case this strtab section appeared before the above.  */
17605796c8dcSSimon Schubert       if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
17615796c8dcSSimon Schubert 	{
17625796c8dcSSimon Schubert 	  unsigned int i, num_sec;
17635796c8dcSSimon Schubert 
17645796c8dcSSimon Schubert 	  num_sec = elf_numsections (abfd);
17655796c8dcSSimon Schubert 	  for (i = 1; i < num_sec; i++)
17665796c8dcSSimon Schubert 	    {
17675796c8dcSSimon Schubert 	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
17685796c8dcSSimon Schubert 	      if (hdr2->sh_link == shindex)
17695796c8dcSSimon Schubert 		{
17705796c8dcSSimon Schubert 		  /* Prevent endless recursion on broken objects.  */
17715796c8dcSSimon Schubert 		  if (i == shindex)
17725796c8dcSSimon Schubert 		    return FALSE;
17735796c8dcSSimon Schubert 		  if (! bfd_section_from_shdr (abfd, i))
17745796c8dcSSimon Schubert 		    return FALSE;
17755796c8dcSSimon Schubert 		  if (elf_onesymtab (abfd) == i)
17765796c8dcSSimon Schubert 		    goto symtab_strtab;
17775796c8dcSSimon Schubert 		  if (elf_dynsymtab (abfd) == i)
17785796c8dcSSimon Schubert 		    goto dynsymtab_strtab;
17795796c8dcSSimon Schubert 		}
17805796c8dcSSimon Schubert 	    }
17815796c8dcSSimon Schubert 	}
17825796c8dcSSimon Schubert       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
17835796c8dcSSimon Schubert 
17845796c8dcSSimon Schubert     case SHT_REL:
17855796c8dcSSimon Schubert     case SHT_RELA:
17865796c8dcSSimon Schubert       /* *These* do a lot of work -- but build no sections!  */
17875796c8dcSSimon Schubert       {
17885796c8dcSSimon Schubert 	asection *target_sect;
1789c50c785cSJohn Marino 	Elf_Internal_Shdr *hdr2, **p_hdr;
17905796c8dcSSimon Schubert 	unsigned int num_sec = elf_numsections (abfd);
1791c50c785cSJohn Marino 	struct bfd_elf_section_data *esdt;
1792c50c785cSJohn Marino 	bfd_size_type amt;
17935796c8dcSSimon Schubert 
17945796c8dcSSimon Schubert 	if (hdr->sh_entsize
17955796c8dcSSimon Schubert 	    != (bfd_size_type) (hdr->sh_type == SHT_REL
17965796c8dcSSimon Schubert 				? bed->s->sizeof_rel : bed->s->sizeof_rela))
17975796c8dcSSimon Schubert 	  return FALSE;
17985796c8dcSSimon Schubert 
17995796c8dcSSimon Schubert 	/* Check for a bogus link to avoid crashing.  */
18005796c8dcSSimon Schubert 	if (hdr->sh_link >= num_sec)
18015796c8dcSSimon Schubert 	  {
18025796c8dcSSimon Schubert 	    ((*_bfd_error_handler)
18035796c8dcSSimon Schubert 	     (_("%B: invalid link %lu for reloc section %s (index %u)"),
18045796c8dcSSimon Schubert 	      abfd, hdr->sh_link, name, shindex));
18055796c8dcSSimon Schubert 	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
18065796c8dcSSimon Schubert 						    shindex);
18075796c8dcSSimon Schubert 	  }
18085796c8dcSSimon Schubert 
18095796c8dcSSimon Schubert 	/* For some incomprehensible reason Oracle distributes
18105796c8dcSSimon Schubert 	   libraries for Solaris in which some of the objects have
18115796c8dcSSimon Schubert 	   bogus sh_link fields.  It would be nice if we could just
18125796c8dcSSimon Schubert 	   reject them, but, unfortunately, some people need to use
18135796c8dcSSimon Schubert 	   them.  We scan through the section headers; if we find only
18145796c8dcSSimon Schubert 	   one suitable symbol table, we clobber the sh_link to point
18155796c8dcSSimon Schubert 	   to it.  I hope this doesn't break anything.
18165796c8dcSSimon Schubert 
18175796c8dcSSimon Schubert 	   Don't do it on executable nor shared library.  */
18185796c8dcSSimon Schubert 	if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0
18195796c8dcSSimon Schubert 	    && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
18205796c8dcSSimon Schubert 	    && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
18215796c8dcSSimon Schubert 	  {
18225796c8dcSSimon Schubert 	    unsigned int scan;
18235796c8dcSSimon Schubert 	    int found;
18245796c8dcSSimon Schubert 
18255796c8dcSSimon Schubert 	    found = 0;
18265796c8dcSSimon Schubert 	    for (scan = 1; scan < num_sec; scan++)
18275796c8dcSSimon Schubert 	      {
18285796c8dcSSimon Schubert 		if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
18295796c8dcSSimon Schubert 		    || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
18305796c8dcSSimon Schubert 		  {
18315796c8dcSSimon Schubert 		    if (found != 0)
18325796c8dcSSimon Schubert 		      {
18335796c8dcSSimon Schubert 			found = 0;
18345796c8dcSSimon Schubert 			break;
18355796c8dcSSimon Schubert 		      }
18365796c8dcSSimon Schubert 		    found = scan;
18375796c8dcSSimon Schubert 		  }
18385796c8dcSSimon Schubert 	      }
18395796c8dcSSimon Schubert 	    if (found != 0)
18405796c8dcSSimon Schubert 	      hdr->sh_link = found;
18415796c8dcSSimon Schubert 	  }
18425796c8dcSSimon Schubert 
18435796c8dcSSimon Schubert 	/* Get the symbol table.  */
18445796c8dcSSimon Schubert 	if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
18455796c8dcSSimon Schubert 	     || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
18465796c8dcSSimon Schubert 	    && ! bfd_section_from_shdr (abfd, hdr->sh_link))
18475796c8dcSSimon Schubert 	  return FALSE;
18485796c8dcSSimon Schubert 
18495796c8dcSSimon Schubert 	/* If this reloc section does not use the main symbol table we
18505796c8dcSSimon Schubert 	   don't treat it as a reloc section.  BFD can't adequately
18515796c8dcSSimon Schubert 	   represent such a section, so at least for now, we don't
18525796c8dcSSimon Schubert 	   try.  We just present it as a normal section.  We also
18535796c8dcSSimon Schubert 	   can't use it as a reloc section if it points to the null
18545796c8dcSSimon Schubert 	   section, an invalid section, another reloc section, or its
18555796c8dcSSimon Schubert 	   sh_link points to the null section.  */
18565796c8dcSSimon Schubert 	if (hdr->sh_link != elf_onesymtab (abfd)
18575796c8dcSSimon Schubert 	    || hdr->sh_link == SHN_UNDEF
18585796c8dcSSimon Schubert 	    || hdr->sh_info == SHN_UNDEF
18595796c8dcSSimon Schubert 	    || hdr->sh_info >= num_sec
18605796c8dcSSimon Schubert 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
18615796c8dcSSimon Schubert 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
18625796c8dcSSimon Schubert 	  return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
18635796c8dcSSimon Schubert 						  shindex);
18645796c8dcSSimon Schubert 
18655796c8dcSSimon Schubert 	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
18665796c8dcSSimon Schubert 	  return FALSE;
18675796c8dcSSimon Schubert 	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
18685796c8dcSSimon Schubert 	if (target_sect == NULL)
18695796c8dcSSimon Schubert 	  return FALSE;
18705796c8dcSSimon Schubert 
1871c50c785cSJohn Marino 	esdt = elf_section_data (target_sect);
1872c50c785cSJohn Marino 	if (hdr->sh_type == SHT_RELA)
1873c50c785cSJohn Marino 	  p_hdr = &esdt->rela.hdr;
18745796c8dcSSimon Schubert 	else
1875c50c785cSJohn Marino 	  p_hdr = &esdt->rel.hdr;
1876c50c785cSJohn Marino 
1877c50c785cSJohn Marino 	BFD_ASSERT (*p_hdr == NULL);
18785796c8dcSSimon Schubert 	amt = sizeof (*hdr2);
18795796c8dcSSimon Schubert 	hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
18805796c8dcSSimon Schubert 	if (hdr2 == NULL)
18815796c8dcSSimon Schubert 	  return FALSE;
18825796c8dcSSimon Schubert 	*hdr2 = *hdr;
1883c50c785cSJohn Marino 	*p_hdr = hdr2;
18845796c8dcSSimon Schubert 	elf_elfsections (abfd)[shindex] = hdr2;
18855796c8dcSSimon Schubert 	target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
18865796c8dcSSimon Schubert 	target_sect->flags |= SEC_RELOC;
18875796c8dcSSimon Schubert 	target_sect->relocation = NULL;
18885796c8dcSSimon Schubert 	target_sect->rel_filepos = hdr->sh_offset;
18895796c8dcSSimon Schubert 	/* In the section to which the relocations apply, mark whether
18905796c8dcSSimon Schubert 	   its relocations are of the REL or RELA variety.  */
18915796c8dcSSimon Schubert 	if (hdr->sh_size != 0)
1892c50c785cSJohn Marino 	  {
1893c50c785cSJohn Marino 	    if (hdr->sh_type == SHT_RELA)
1894c50c785cSJohn Marino 	      target_sect->use_rela_p = 1;
1895c50c785cSJohn Marino 	  }
18965796c8dcSSimon Schubert 	abfd->flags |= HAS_RELOC;
18975796c8dcSSimon Schubert 	return TRUE;
18985796c8dcSSimon Schubert       }
18995796c8dcSSimon Schubert 
19005796c8dcSSimon Schubert     case SHT_GNU_verdef:
19015796c8dcSSimon Schubert       elf_dynverdef (abfd) = shindex;
19025796c8dcSSimon Schubert       elf_tdata (abfd)->dynverdef_hdr = *hdr;
19035796c8dcSSimon Schubert       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
19045796c8dcSSimon Schubert 
19055796c8dcSSimon Schubert     case SHT_GNU_versym:
19065796c8dcSSimon Schubert       if (hdr->sh_entsize != sizeof (Elf_External_Versym))
19075796c8dcSSimon Schubert 	return FALSE;
19085796c8dcSSimon Schubert       elf_dynversym (abfd) = shindex;
19095796c8dcSSimon Schubert       elf_tdata (abfd)->dynversym_hdr = *hdr;
19105796c8dcSSimon Schubert       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
19115796c8dcSSimon Schubert 
19125796c8dcSSimon Schubert     case SHT_GNU_verneed:
19135796c8dcSSimon Schubert       elf_dynverref (abfd) = shindex;
19145796c8dcSSimon Schubert       elf_tdata (abfd)->dynverref_hdr = *hdr;
19155796c8dcSSimon Schubert       return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
19165796c8dcSSimon Schubert 
19175796c8dcSSimon Schubert     case SHT_SHLIB:
19185796c8dcSSimon Schubert       return TRUE;
19195796c8dcSSimon Schubert 
19205796c8dcSSimon Schubert     case SHT_GROUP:
1921*ef5ccd6cSJohn Marino       if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE))
19225796c8dcSSimon Schubert 	return FALSE;
19235796c8dcSSimon Schubert       if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
19245796c8dcSSimon Schubert 	return FALSE;
19255796c8dcSSimon Schubert       if (hdr->contents != NULL)
19265796c8dcSSimon Schubert 	{
19275796c8dcSSimon Schubert 	  Elf_Internal_Group *idx = (Elf_Internal_Group *) hdr->contents;
19285796c8dcSSimon Schubert 	  unsigned int n_elt = hdr->sh_size / GRP_ENTRY_SIZE;
19295796c8dcSSimon Schubert 	  asection *s;
19305796c8dcSSimon Schubert 
19315796c8dcSSimon Schubert 	  if (idx->flags & GRP_COMDAT)
19325796c8dcSSimon Schubert 	    hdr->bfd_section->flags
19335796c8dcSSimon Schubert 	      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
19345796c8dcSSimon Schubert 
19355796c8dcSSimon Schubert 	  /* We try to keep the same section order as it comes in.  */
19365796c8dcSSimon Schubert 	  idx += n_elt;
19375796c8dcSSimon Schubert 	  while (--n_elt != 0)
19385796c8dcSSimon Schubert 	    {
19395796c8dcSSimon Schubert 	      --idx;
19405796c8dcSSimon Schubert 
19415796c8dcSSimon Schubert 	      if (idx->shdr != NULL
19425796c8dcSSimon Schubert 		  && (s = idx->shdr->bfd_section) != NULL
19435796c8dcSSimon Schubert 		  && elf_next_in_group (s) != NULL)
19445796c8dcSSimon Schubert 		{
19455796c8dcSSimon Schubert 		  elf_next_in_group (hdr->bfd_section) = s;
19465796c8dcSSimon Schubert 		  break;
19475796c8dcSSimon Schubert 		}
19485796c8dcSSimon Schubert 	    }
19495796c8dcSSimon Schubert 	}
19505796c8dcSSimon Schubert       break;
19515796c8dcSSimon Schubert 
19525796c8dcSSimon Schubert     default:
19535796c8dcSSimon Schubert       /* Possibly an attributes section.  */
19545796c8dcSSimon Schubert       if (hdr->sh_type == SHT_GNU_ATTRIBUTES
19555796c8dcSSimon Schubert 	  || hdr->sh_type == bed->obj_attrs_section_type)
19565796c8dcSSimon Schubert 	{
19575796c8dcSSimon Schubert 	  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
19585796c8dcSSimon Schubert 	    return FALSE;
19595796c8dcSSimon Schubert 	  _bfd_elf_parse_attributes (abfd, hdr);
19605796c8dcSSimon Schubert 	  return TRUE;
19615796c8dcSSimon Schubert 	}
19625796c8dcSSimon Schubert 
19635796c8dcSSimon Schubert       /* Check for any processor-specific section types.  */
19645796c8dcSSimon Schubert       if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
19655796c8dcSSimon Schubert 	return TRUE;
19665796c8dcSSimon Schubert 
19675796c8dcSSimon Schubert       if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
19685796c8dcSSimon Schubert 	{
19695796c8dcSSimon Schubert 	  if ((hdr->sh_flags & SHF_ALLOC) != 0)
19705796c8dcSSimon Schubert 	    /* FIXME: How to properly handle allocated section reserved
19715796c8dcSSimon Schubert 	       for applications?  */
19725796c8dcSSimon Schubert 	    (*_bfd_error_handler)
19735796c8dcSSimon Schubert 	      (_("%B: don't know how to handle allocated, application "
19745796c8dcSSimon Schubert 		 "specific section `%s' [0x%8x]"),
19755796c8dcSSimon Schubert 	       abfd, name, hdr->sh_type);
19765796c8dcSSimon Schubert 	  else
19775796c8dcSSimon Schubert 	    /* Allow sections reserved for applications.  */
19785796c8dcSSimon Schubert 	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name,
19795796c8dcSSimon Schubert 						    shindex);
19805796c8dcSSimon Schubert 	}
19815796c8dcSSimon Schubert       else if (hdr->sh_type >= SHT_LOPROC
19825796c8dcSSimon Schubert 	       && hdr->sh_type <= SHT_HIPROC)
19835796c8dcSSimon Schubert 	/* FIXME: We should handle this section.  */
19845796c8dcSSimon Schubert 	(*_bfd_error_handler)
19855796c8dcSSimon Schubert 	  (_("%B: don't know how to handle processor specific section "
19865796c8dcSSimon Schubert 	     "`%s' [0x%8x]"),
19875796c8dcSSimon Schubert 	   abfd, name, hdr->sh_type);
19885796c8dcSSimon Schubert       else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
19895796c8dcSSimon Schubert 	{
19905796c8dcSSimon Schubert 	  /* Unrecognised OS-specific sections.  */
19915796c8dcSSimon Schubert 	  if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0)
19925796c8dcSSimon Schubert 	    /* SHF_OS_NONCONFORMING indicates that special knowledge is
19935796c8dcSSimon Schubert 	       required to correctly process the section and the file should
19945796c8dcSSimon Schubert 	       be rejected with an error message.  */
19955796c8dcSSimon Schubert 	    (*_bfd_error_handler)
19965796c8dcSSimon Schubert 	      (_("%B: don't know how to handle OS specific section "
19975796c8dcSSimon Schubert 		 "`%s' [0x%8x]"),
19985796c8dcSSimon Schubert 	       abfd, name, hdr->sh_type);
19995796c8dcSSimon Schubert 	  else
20005796c8dcSSimon Schubert 	    /* Otherwise it should be processed.  */
20015796c8dcSSimon Schubert 	    return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
20025796c8dcSSimon Schubert 	}
20035796c8dcSSimon Schubert       else
20045796c8dcSSimon Schubert 	/* FIXME: We should handle this section.  */
20055796c8dcSSimon Schubert 	(*_bfd_error_handler)
20065796c8dcSSimon Schubert 	  (_("%B: don't know how to handle section `%s' [0x%8x]"),
20075796c8dcSSimon Schubert 	   abfd, name, hdr->sh_type);
20085796c8dcSSimon Schubert 
20095796c8dcSSimon Schubert       return FALSE;
20105796c8dcSSimon Schubert     }
20115796c8dcSSimon Schubert 
20125796c8dcSSimon Schubert   return TRUE;
20135796c8dcSSimon Schubert }
20145796c8dcSSimon Schubert 
20155796c8dcSSimon Schubert /* Return the local symbol specified by ABFD, R_SYMNDX.  */
20165796c8dcSSimon Schubert 
20175796c8dcSSimon Schubert Elf_Internal_Sym *
bfd_sym_from_r_symndx(struct sym_cache * cache,bfd * abfd,unsigned long r_symndx)20185796c8dcSSimon Schubert bfd_sym_from_r_symndx (struct sym_cache *cache,
20195796c8dcSSimon Schubert 		       bfd *abfd,
20205796c8dcSSimon Schubert 		       unsigned long r_symndx)
20215796c8dcSSimon Schubert {
20225796c8dcSSimon Schubert   unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
20235796c8dcSSimon Schubert 
20245796c8dcSSimon Schubert   if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
20255796c8dcSSimon Schubert     {
20265796c8dcSSimon Schubert       Elf_Internal_Shdr *symtab_hdr;
20275796c8dcSSimon Schubert       unsigned char esym[sizeof (Elf64_External_Sym)];
20285796c8dcSSimon Schubert       Elf_External_Sym_Shndx eshndx;
20295796c8dcSSimon Schubert 
20305796c8dcSSimon Schubert       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
20315796c8dcSSimon Schubert       if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
20325796c8dcSSimon Schubert 				&cache->sym[ent], esym, &eshndx) == NULL)
20335796c8dcSSimon Schubert 	return NULL;
20345796c8dcSSimon Schubert 
20355796c8dcSSimon Schubert       if (cache->abfd != abfd)
20365796c8dcSSimon Schubert 	{
20375796c8dcSSimon Schubert 	  memset (cache->indx, -1, sizeof (cache->indx));
20385796c8dcSSimon Schubert 	  cache->abfd = abfd;
20395796c8dcSSimon Schubert 	}
20405796c8dcSSimon Schubert       cache->indx[ent] = r_symndx;
20415796c8dcSSimon Schubert     }
20425796c8dcSSimon Schubert 
20435796c8dcSSimon Schubert   return &cache->sym[ent];
20445796c8dcSSimon Schubert }
20455796c8dcSSimon Schubert 
20465796c8dcSSimon Schubert /* Given an ELF section number, retrieve the corresponding BFD
20475796c8dcSSimon Schubert    section.  */
20485796c8dcSSimon Schubert 
20495796c8dcSSimon Schubert asection *
bfd_section_from_elf_index(bfd * abfd,unsigned int sec_index)2050cf7f2e2dSJohn Marino bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index)
20515796c8dcSSimon Schubert {
2052cf7f2e2dSJohn Marino   if (sec_index >= elf_numsections (abfd))
20535796c8dcSSimon Schubert     return NULL;
2054cf7f2e2dSJohn Marino   return elf_elfsections (abfd)[sec_index]->bfd_section;
20555796c8dcSSimon Schubert }
20565796c8dcSSimon Schubert 
20575796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_b[] =
20585796c8dcSSimon Schubert {
20595796c8dcSSimon Schubert   { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
20605796c8dcSSimon Schubert   { NULL,                   0,  0, 0,            0 }
20615796c8dcSSimon Schubert };
20625796c8dcSSimon Schubert 
20635796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_c[] =
20645796c8dcSSimon Schubert {
20655796c8dcSSimon Schubert   { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
20665796c8dcSSimon Schubert   { NULL,                       0, 0, 0,            0 }
20675796c8dcSSimon Schubert };
20685796c8dcSSimon Schubert 
20695796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_d[] =
20705796c8dcSSimon Schubert {
20715796c8dcSSimon Schubert   { STRING_COMMA_LEN (".data"),         -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
20725796c8dcSSimon Schubert   { STRING_COMMA_LEN (".data1"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
2073*ef5ccd6cSJohn Marino   /* There are more DWARF sections than these, but they needn't be added here
2074*ef5ccd6cSJohn Marino      unless you have to cope with broken compilers that don't emit section
2075*ef5ccd6cSJohn Marino      attributes or you want to help the user writing assembler.  */
20765796c8dcSSimon Schubert   { STRING_COMMA_LEN (".debug"),         0, SHT_PROGBITS, 0 },
20775796c8dcSSimon Schubert   { STRING_COMMA_LEN (".debug_line"),    0, SHT_PROGBITS, 0 },
20785796c8dcSSimon Schubert   { STRING_COMMA_LEN (".debug_info"),    0, SHT_PROGBITS, 0 },
20795796c8dcSSimon Schubert   { STRING_COMMA_LEN (".debug_abbrev"),  0, SHT_PROGBITS, 0 },
20805796c8dcSSimon Schubert   { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
20815796c8dcSSimon Schubert   { STRING_COMMA_LEN (".dynamic"),       0, SHT_DYNAMIC,  SHF_ALLOC },
20825796c8dcSSimon Schubert   { STRING_COMMA_LEN (".dynstr"),        0, SHT_STRTAB,   SHF_ALLOC },
20835796c8dcSSimon Schubert   { STRING_COMMA_LEN (".dynsym"),        0, SHT_DYNSYM,   SHF_ALLOC },
20845796c8dcSSimon Schubert   { NULL,                      0,        0, 0,            0 }
20855796c8dcSSimon Schubert };
20865796c8dcSSimon Schubert 
20875796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_f[] =
20885796c8dcSSimon Schubert {
20895796c8dcSSimon Schubert   { STRING_COMMA_LEN (".fini"),       0, SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR },
20905796c8dcSSimon Schubert   { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
20915796c8dcSSimon Schubert   { NULL,                          0, 0, 0,              0 }
20925796c8dcSSimon Schubert };
20935796c8dcSSimon Schubert 
20945796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_g[] =
20955796c8dcSSimon Schubert {
20965796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
2097c50c785cSJohn Marino   { STRING_COMMA_LEN (".gnu.lto_"),       -1, SHT_PROGBITS,    SHF_EXCLUDE },
20985796c8dcSSimon Schubert   { STRING_COMMA_LEN (".got"),             0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
20995796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.version"),     0, SHT_GNU_versym,  0 },
21005796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
21015796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.version_r"),   0, SHT_GNU_verneed, 0 },
21025796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.liblist"),     0, SHT_GNU_LIBLIST, SHF_ALLOC },
21035796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.conflict"),    0, SHT_RELA,        SHF_ALLOC },
21045796c8dcSSimon Schubert   { STRING_COMMA_LEN (".gnu.hash"),        0, SHT_GNU_HASH,    SHF_ALLOC },
21055796c8dcSSimon Schubert   { NULL,                        0,        0, 0,               0 }
21065796c8dcSSimon Schubert };
21075796c8dcSSimon Schubert 
21085796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_h[] =
21095796c8dcSSimon Schubert {
21105796c8dcSSimon Schubert   { STRING_COMMA_LEN (".hash"), 0, SHT_HASH,     SHF_ALLOC },
21115796c8dcSSimon Schubert   { NULL,                    0, 0, 0,            0 }
21125796c8dcSSimon Schubert };
21135796c8dcSSimon Schubert 
21145796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_i[] =
21155796c8dcSSimon Schubert {
21165796c8dcSSimon Schubert   { STRING_COMMA_LEN (".init"),       0, SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR },
21175796c8dcSSimon Schubert   { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
21185796c8dcSSimon Schubert   { STRING_COMMA_LEN (".interp"),     0, SHT_PROGBITS,   0 },
21195796c8dcSSimon Schubert   { NULL,                      0,     0, 0,              0 }
21205796c8dcSSimon Schubert };
21215796c8dcSSimon Schubert 
21225796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_l[] =
21235796c8dcSSimon Schubert {
21245796c8dcSSimon Schubert   { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
21255796c8dcSSimon Schubert   { NULL,                    0, 0, 0,            0 }
21265796c8dcSSimon Schubert };
21275796c8dcSSimon Schubert 
21285796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_n[] =
21295796c8dcSSimon Schubert {
21305796c8dcSSimon Schubert   { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
21315796c8dcSSimon Schubert   { STRING_COMMA_LEN (".note"),          -1, SHT_NOTE,     0 },
21325796c8dcSSimon Schubert   { NULL,                    0,           0, 0,            0 }
21335796c8dcSSimon Schubert };
21345796c8dcSSimon Schubert 
21355796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_p[] =
21365796c8dcSSimon Schubert {
21375796c8dcSSimon Schubert   { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
21385796c8dcSSimon Schubert   { STRING_COMMA_LEN (".plt"),           0, SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
21395796c8dcSSimon Schubert   { NULL,                   0,           0, 0,                 0 }
21405796c8dcSSimon Schubert };
21415796c8dcSSimon Schubert 
21425796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_r[] =
21435796c8dcSSimon Schubert {
21445796c8dcSSimon Schubert   { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
21455796c8dcSSimon Schubert   { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
21465796c8dcSSimon Schubert   { STRING_COMMA_LEN (".rela"),   -1, SHT_RELA,     0 },
21475796c8dcSSimon Schubert   { STRING_COMMA_LEN (".rel"),    -1, SHT_REL,      0 },
21485796c8dcSSimon Schubert   { NULL,                   0,     0, 0,            0 }
21495796c8dcSSimon Schubert };
21505796c8dcSSimon Schubert 
21515796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_s[] =
21525796c8dcSSimon Schubert {
21535796c8dcSSimon Schubert   { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
21545796c8dcSSimon Schubert   { STRING_COMMA_LEN (".strtab"),   0, SHT_STRTAB, 0 },
21555796c8dcSSimon Schubert   { STRING_COMMA_LEN (".symtab"),   0, SHT_SYMTAB, 0 },
21565796c8dcSSimon Schubert   /* See struct bfd_elf_special_section declaration for the semantics of
21575796c8dcSSimon Schubert      this special case where .prefix_length != strlen (.prefix).  */
21585796c8dcSSimon Schubert   { ".stabstr",			5,  3, SHT_STRTAB, 0 },
21595796c8dcSSimon Schubert   { NULL,                       0,  0, 0,          0 }
21605796c8dcSSimon Schubert };
21615796c8dcSSimon Schubert 
21625796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_t[] =
21635796c8dcSSimon Schubert {
21645796c8dcSSimon Schubert   { STRING_COMMA_LEN (".text"),  -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
21655796c8dcSSimon Schubert   { STRING_COMMA_LEN (".tbss"),  -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
21665796c8dcSSimon Schubert   { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
21675796c8dcSSimon Schubert   { NULL,                     0,  0, 0,            0 }
21685796c8dcSSimon Schubert };
21695796c8dcSSimon Schubert 
21705796c8dcSSimon Schubert static const struct bfd_elf_special_section special_sections_z[] =
21715796c8dcSSimon Schubert {
21725796c8dcSSimon Schubert   { STRING_COMMA_LEN (".zdebug_line"),    0, SHT_PROGBITS, 0 },
21735796c8dcSSimon Schubert   { STRING_COMMA_LEN (".zdebug_info"),    0, SHT_PROGBITS, 0 },
21745796c8dcSSimon Schubert   { STRING_COMMA_LEN (".zdebug_abbrev"),  0, SHT_PROGBITS, 0 },
21755796c8dcSSimon Schubert   { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
21765796c8dcSSimon Schubert   { NULL,                     0,  0, 0,            0 }
21775796c8dcSSimon Schubert };
21785796c8dcSSimon Schubert 
2179a45ae5f8SJohn Marino static const struct bfd_elf_special_section * const special_sections[] =
21805796c8dcSSimon Schubert {
21815796c8dcSSimon Schubert   special_sections_b,		/* 'b' */
21825796c8dcSSimon Schubert   special_sections_c,		/* 'c' */
21835796c8dcSSimon Schubert   special_sections_d,		/* 'd' */
21845796c8dcSSimon Schubert   NULL,				/* 'e' */
21855796c8dcSSimon Schubert   special_sections_f,		/* 'f' */
21865796c8dcSSimon Schubert   special_sections_g,		/* 'g' */
21875796c8dcSSimon Schubert   special_sections_h,		/* 'h' */
21885796c8dcSSimon Schubert   special_sections_i,		/* 'i' */
21895796c8dcSSimon Schubert   NULL,				/* 'j' */
21905796c8dcSSimon Schubert   NULL,				/* 'k' */
21915796c8dcSSimon Schubert   special_sections_l,		/* 'l' */
21925796c8dcSSimon Schubert   NULL,				/* 'm' */
21935796c8dcSSimon Schubert   special_sections_n,		/* 'n' */
21945796c8dcSSimon Schubert   NULL,				/* 'o' */
21955796c8dcSSimon Schubert   special_sections_p,		/* 'p' */
21965796c8dcSSimon Schubert   NULL,				/* 'q' */
21975796c8dcSSimon Schubert   special_sections_r,		/* 'r' */
21985796c8dcSSimon Schubert   special_sections_s,		/* 's' */
21995796c8dcSSimon Schubert   special_sections_t,		/* 't' */
22005796c8dcSSimon Schubert   NULL,				/* 'u' */
22015796c8dcSSimon Schubert   NULL,				/* 'v' */
22025796c8dcSSimon Schubert   NULL,				/* 'w' */
22035796c8dcSSimon Schubert   NULL,				/* 'x' */
22045796c8dcSSimon Schubert   NULL,				/* 'y' */
22055796c8dcSSimon Schubert   special_sections_z		/* 'z' */
22065796c8dcSSimon Schubert };
22075796c8dcSSimon Schubert 
22085796c8dcSSimon Schubert const struct bfd_elf_special_section *
_bfd_elf_get_special_section(const char * name,const struct bfd_elf_special_section * spec,unsigned int rela)22095796c8dcSSimon Schubert _bfd_elf_get_special_section (const char *name,
22105796c8dcSSimon Schubert 			      const struct bfd_elf_special_section *spec,
22115796c8dcSSimon Schubert 			      unsigned int rela)
22125796c8dcSSimon Schubert {
22135796c8dcSSimon Schubert   int i;
22145796c8dcSSimon Schubert   int len;
22155796c8dcSSimon Schubert 
22165796c8dcSSimon Schubert   len = strlen (name);
22175796c8dcSSimon Schubert 
22185796c8dcSSimon Schubert   for (i = 0; spec[i].prefix != NULL; i++)
22195796c8dcSSimon Schubert     {
22205796c8dcSSimon Schubert       int suffix_len;
22215796c8dcSSimon Schubert       int prefix_len = spec[i].prefix_length;
22225796c8dcSSimon Schubert 
22235796c8dcSSimon Schubert       if (len < prefix_len)
22245796c8dcSSimon Schubert 	continue;
22255796c8dcSSimon Schubert       if (memcmp (name, spec[i].prefix, prefix_len) != 0)
22265796c8dcSSimon Schubert 	continue;
22275796c8dcSSimon Schubert 
22285796c8dcSSimon Schubert       suffix_len = spec[i].suffix_length;
22295796c8dcSSimon Schubert       if (suffix_len <= 0)
22305796c8dcSSimon Schubert 	{
22315796c8dcSSimon Schubert 	  if (name[prefix_len] != 0)
22325796c8dcSSimon Schubert 	    {
22335796c8dcSSimon Schubert 	      if (suffix_len == 0)
22345796c8dcSSimon Schubert 		continue;
22355796c8dcSSimon Schubert 	      if (name[prefix_len] != '.'
22365796c8dcSSimon Schubert 		  && (suffix_len == -2
22375796c8dcSSimon Schubert 		      || (rela && spec[i].type == SHT_REL)))
22385796c8dcSSimon Schubert 		continue;
22395796c8dcSSimon Schubert 	    }
22405796c8dcSSimon Schubert 	}
22415796c8dcSSimon Schubert       else
22425796c8dcSSimon Schubert 	{
22435796c8dcSSimon Schubert 	  if (len < prefix_len + suffix_len)
22445796c8dcSSimon Schubert 	    continue;
22455796c8dcSSimon Schubert 	  if (memcmp (name + len - suffix_len,
22465796c8dcSSimon Schubert 		      spec[i].prefix + prefix_len,
22475796c8dcSSimon Schubert 		      suffix_len) != 0)
22485796c8dcSSimon Schubert 	    continue;
22495796c8dcSSimon Schubert 	}
22505796c8dcSSimon Schubert       return &spec[i];
22515796c8dcSSimon Schubert     }
22525796c8dcSSimon Schubert 
22535796c8dcSSimon Schubert   return NULL;
22545796c8dcSSimon Schubert }
22555796c8dcSSimon Schubert 
22565796c8dcSSimon Schubert const struct bfd_elf_special_section *
_bfd_elf_get_sec_type_attr(bfd * abfd,asection * sec)22575796c8dcSSimon Schubert _bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
22585796c8dcSSimon Schubert {
22595796c8dcSSimon Schubert   int i;
22605796c8dcSSimon Schubert   const struct bfd_elf_special_section *spec;
22615796c8dcSSimon Schubert   const struct elf_backend_data *bed;
22625796c8dcSSimon Schubert 
22635796c8dcSSimon Schubert   /* See if this is one of the special sections.  */
22645796c8dcSSimon Schubert   if (sec->name == NULL)
22655796c8dcSSimon Schubert     return NULL;
22665796c8dcSSimon Schubert 
22675796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
22685796c8dcSSimon Schubert   spec = bed->special_sections;
22695796c8dcSSimon Schubert   if (spec)
22705796c8dcSSimon Schubert     {
22715796c8dcSSimon Schubert       spec = _bfd_elf_get_special_section (sec->name,
22725796c8dcSSimon Schubert 					   bed->special_sections,
22735796c8dcSSimon Schubert 					   sec->use_rela_p);
22745796c8dcSSimon Schubert       if (spec != NULL)
22755796c8dcSSimon Schubert 	return spec;
22765796c8dcSSimon Schubert     }
22775796c8dcSSimon Schubert 
22785796c8dcSSimon Schubert   if (sec->name[0] != '.')
22795796c8dcSSimon Schubert     return NULL;
22805796c8dcSSimon Schubert 
22815796c8dcSSimon Schubert   i = sec->name[1] - 'b';
22825796c8dcSSimon Schubert   if (i < 0 || i > 'z' - 'b')
22835796c8dcSSimon Schubert     return NULL;
22845796c8dcSSimon Schubert 
22855796c8dcSSimon Schubert   spec = special_sections[i];
22865796c8dcSSimon Schubert 
22875796c8dcSSimon Schubert   if (spec == NULL)
22885796c8dcSSimon Schubert     return NULL;
22895796c8dcSSimon Schubert 
22905796c8dcSSimon Schubert   return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
22915796c8dcSSimon Schubert }
22925796c8dcSSimon Schubert 
22935796c8dcSSimon Schubert bfd_boolean
_bfd_elf_new_section_hook(bfd * abfd,asection * sec)22945796c8dcSSimon Schubert _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
22955796c8dcSSimon Schubert {
22965796c8dcSSimon Schubert   struct bfd_elf_section_data *sdata;
22975796c8dcSSimon Schubert   const struct elf_backend_data *bed;
22985796c8dcSSimon Schubert   const struct bfd_elf_special_section *ssect;
22995796c8dcSSimon Schubert 
23005796c8dcSSimon Schubert   sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
23015796c8dcSSimon Schubert   if (sdata == NULL)
23025796c8dcSSimon Schubert     {
23035796c8dcSSimon Schubert       sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd,
23045796c8dcSSimon Schubert                                                           sizeof (*sdata));
23055796c8dcSSimon Schubert       if (sdata == NULL)
23065796c8dcSSimon Schubert 	return FALSE;
23075796c8dcSSimon Schubert       sec->used_by_bfd = sdata;
23085796c8dcSSimon Schubert     }
23095796c8dcSSimon Schubert 
23105796c8dcSSimon Schubert   /* Indicate whether or not this section should use RELA relocations.  */
23115796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
23125796c8dcSSimon Schubert   sec->use_rela_p = bed->default_use_rela_p;
23135796c8dcSSimon Schubert 
23145796c8dcSSimon Schubert   /* When we read a file, we don't need to set ELF section type and
23155796c8dcSSimon Schubert      flags.  They will be overridden in _bfd_elf_make_section_from_shdr
23165796c8dcSSimon Schubert      anyway.  We will set ELF section type and flags for all linker
23175796c8dcSSimon Schubert      created sections.  If user specifies BFD section flags, we will
23185796c8dcSSimon Schubert      set ELF section type and flags based on BFD section flags in
2319c50c785cSJohn Marino      elf_fake_sections.  Special handling for .init_array/.fini_array
2320c50c785cSJohn Marino      output sections since they may contain .ctors/.dtors input
2321c50c785cSJohn Marino      sections.  We don't want _bfd_elf_init_private_section_data to
2322c50c785cSJohn Marino      copy ELF section type from .ctors/.dtors input sections.  */
2323c50c785cSJohn Marino   if (abfd->direction != read_direction
23245796c8dcSSimon Schubert       || (sec->flags & SEC_LINKER_CREATED) != 0)
23255796c8dcSSimon Schubert     {
23265796c8dcSSimon Schubert       ssect = (*bed->get_sec_type_attr) (abfd, sec);
2327c50c785cSJohn Marino       if (ssect != NULL
2328c50c785cSJohn Marino 	  && (!sec->flags
2329c50c785cSJohn Marino 	      || (sec->flags & SEC_LINKER_CREATED) != 0
2330c50c785cSJohn Marino 	      || ssect->type == SHT_INIT_ARRAY
2331c50c785cSJohn Marino 	      || ssect->type == SHT_FINI_ARRAY))
23325796c8dcSSimon Schubert 	{
23335796c8dcSSimon Schubert 	  elf_section_type (sec) = ssect->type;
23345796c8dcSSimon Schubert 	  elf_section_flags (sec) = ssect->attr;
23355796c8dcSSimon Schubert 	}
23365796c8dcSSimon Schubert     }
23375796c8dcSSimon Schubert 
23385796c8dcSSimon Schubert   return _bfd_generic_new_section_hook (abfd, sec);
23395796c8dcSSimon Schubert }
23405796c8dcSSimon Schubert 
23415796c8dcSSimon Schubert /* Create a new bfd section from an ELF program header.
23425796c8dcSSimon Schubert 
23435796c8dcSSimon Schubert    Since program segments have no names, we generate a synthetic name
23445796c8dcSSimon Schubert    of the form segment<NUM>, where NUM is generally the index in the
23455796c8dcSSimon Schubert    program header table.  For segments that are split (see below) we
23465796c8dcSSimon Schubert    generate the names segment<NUM>a and segment<NUM>b.
23475796c8dcSSimon Schubert 
23485796c8dcSSimon Schubert    Note that some program segments may have a file size that is different than
23495796c8dcSSimon Schubert    (less than) the memory size.  All this means is that at execution the
23505796c8dcSSimon Schubert    system must allocate the amount of memory specified by the memory size,
23515796c8dcSSimon Schubert    but only initialize it with the first "file size" bytes read from the
23525796c8dcSSimon Schubert    file.  This would occur for example, with program segments consisting
23535796c8dcSSimon Schubert    of combined data+bss.
23545796c8dcSSimon Schubert 
23555796c8dcSSimon Schubert    To handle the above situation, this routine generates TWO bfd sections
23565796c8dcSSimon Schubert    for the single program segment.  The first has the length specified by
23575796c8dcSSimon Schubert    the file size of the segment, and the second has the length specified
23585796c8dcSSimon Schubert    by the difference between the two sizes.  In effect, the segment is split
23595796c8dcSSimon Schubert    into its initialized and uninitialized parts.
23605796c8dcSSimon Schubert 
23615796c8dcSSimon Schubert  */
23625796c8dcSSimon Schubert 
23635796c8dcSSimon Schubert bfd_boolean
_bfd_elf_make_section_from_phdr(bfd * abfd,Elf_Internal_Phdr * hdr,int hdr_index,const char * type_name)23645796c8dcSSimon Schubert _bfd_elf_make_section_from_phdr (bfd *abfd,
23655796c8dcSSimon Schubert 				 Elf_Internal_Phdr *hdr,
2366cf7f2e2dSJohn Marino 				 int hdr_index,
23675796c8dcSSimon Schubert 				 const char *type_name)
23685796c8dcSSimon Schubert {
23695796c8dcSSimon Schubert   asection *newsect;
23705796c8dcSSimon Schubert   char *name;
23715796c8dcSSimon Schubert   char namebuf[64];
23725796c8dcSSimon Schubert   size_t len;
23735796c8dcSSimon Schubert   int split;
23745796c8dcSSimon Schubert 
23755796c8dcSSimon Schubert   split = ((hdr->p_memsz > 0)
23765796c8dcSSimon Schubert 	    && (hdr->p_filesz > 0)
23775796c8dcSSimon Schubert 	    && (hdr->p_memsz > hdr->p_filesz));
23785796c8dcSSimon Schubert 
23795796c8dcSSimon Schubert   if (hdr->p_filesz > 0)
23805796c8dcSSimon Schubert     {
2381cf7f2e2dSJohn Marino       sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : "");
23825796c8dcSSimon Schubert       len = strlen (namebuf) + 1;
23835796c8dcSSimon Schubert       name = (char *) bfd_alloc (abfd, len);
23845796c8dcSSimon Schubert       if (!name)
23855796c8dcSSimon Schubert 	return FALSE;
23865796c8dcSSimon Schubert       memcpy (name, namebuf, len);
23875796c8dcSSimon Schubert       newsect = bfd_make_section (abfd, name);
23885796c8dcSSimon Schubert       if (newsect == NULL)
23895796c8dcSSimon Schubert 	return FALSE;
23905796c8dcSSimon Schubert       newsect->vma = hdr->p_vaddr;
23915796c8dcSSimon Schubert       newsect->lma = hdr->p_paddr;
23925796c8dcSSimon Schubert       newsect->size = hdr->p_filesz;
23935796c8dcSSimon Schubert       newsect->filepos = hdr->p_offset;
23945796c8dcSSimon Schubert       newsect->flags |= SEC_HAS_CONTENTS;
23955796c8dcSSimon Schubert       newsect->alignment_power = bfd_log2 (hdr->p_align);
23965796c8dcSSimon Schubert       if (hdr->p_type == PT_LOAD)
23975796c8dcSSimon Schubert 	{
23985796c8dcSSimon Schubert 	  newsect->flags |= SEC_ALLOC;
23995796c8dcSSimon Schubert 	  newsect->flags |= SEC_LOAD;
24005796c8dcSSimon Schubert 	  if (hdr->p_flags & PF_X)
24015796c8dcSSimon Schubert 	    {
24025796c8dcSSimon Schubert 	      /* FIXME: all we known is that it has execute PERMISSION,
24035796c8dcSSimon Schubert 		 may be data.  */
24045796c8dcSSimon Schubert 	      newsect->flags |= SEC_CODE;
24055796c8dcSSimon Schubert 	    }
24065796c8dcSSimon Schubert 	}
24075796c8dcSSimon Schubert       if (!(hdr->p_flags & PF_W))
24085796c8dcSSimon Schubert 	{
24095796c8dcSSimon Schubert 	  newsect->flags |= SEC_READONLY;
24105796c8dcSSimon Schubert 	}
24115796c8dcSSimon Schubert     }
24125796c8dcSSimon Schubert 
24135796c8dcSSimon Schubert   if (hdr->p_memsz > hdr->p_filesz)
24145796c8dcSSimon Schubert     {
24155796c8dcSSimon Schubert       bfd_vma align;
24165796c8dcSSimon Schubert 
2417cf7f2e2dSJohn Marino       sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : "");
24185796c8dcSSimon Schubert       len = strlen (namebuf) + 1;
24195796c8dcSSimon Schubert       name = (char *) bfd_alloc (abfd, len);
24205796c8dcSSimon Schubert       if (!name)
24215796c8dcSSimon Schubert 	return FALSE;
24225796c8dcSSimon Schubert       memcpy (name, namebuf, len);
24235796c8dcSSimon Schubert       newsect = bfd_make_section (abfd, name);
24245796c8dcSSimon Schubert       if (newsect == NULL)
24255796c8dcSSimon Schubert 	return FALSE;
24265796c8dcSSimon Schubert       newsect->vma = hdr->p_vaddr + hdr->p_filesz;
24275796c8dcSSimon Schubert       newsect->lma = hdr->p_paddr + hdr->p_filesz;
24285796c8dcSSimon Schubert       newsect->size = hdr->p_memsz - hdr->p_filesz;
24295796c8dcSSimon Schubert       newsect->filepos = hdr->p_offset + hdr->p_filesz;
24305796c8dcSSimon Schubert       align = newsect->vma & -newsect->vma;
24315796c8dcSSimon Schubert       if (align == 0 || align > hdr->p_align)
24325796c8dcSSimon Schubert 	align = hdr->p_align;
24335796c8dcSSimon Schubert       newsect->alignment_power = bfd_log2 (align);
24345796c8dcSSimon Schubert       if (hdr->p_type == PT_LOAD)
24355796c8dcSSimon Schubert 	{
24365796c8dcSSimon Schubert 	  /* Hack for gdb.  Segments that have not been modified do
24375796c8dcSSimon Schubert 	     not have their contents written to a core file, on the
24385796c8dcSSimon Schubert 	     assumption that a debugger can find the contents in the
24395796c8dcSSimon Schubert 	     executable.  We flag this case by setting the fake
24405796c8dcSSimon Schubert 	     section size to zero.  Note that "real" bss sections will
24415796c8dcSSimon Schubert 	     always have their contents dumped to the core file.  */
24425796c8dcSSimon Schubert 	  if (bfd_get_format (abfd) == bfd_core)
24435796c8dcSSimon Schubert 	    newsect->size = 0;
24445796c8dcSSimon Schubert 	  newsect->flags |= SEC_ALLOC;
24455796c8dcSSimon Schubert 	  if (hdr->p_flags & PF_X)
24465796c8dcSSimon Schubert 	    newsect->flags |= SEC_CODE;
24475796c8dcSSimon Schubert 	}
24485796c8dcSSimon Schubert       if (!(hdr->p_flags & PF_W))
24495796c8dcSSimon Schubert 	newsect->flags |= SEC_READONLY;
24505796c8dcSSimon Schubert     }
24515796c8dcSSimon Schubert 
24525796c8dcSSimon Schubert   return TRUE;
24535796c8dcSSimon Schubert }
24545796c8dcSSimon Schubert 
24555796c8dcSSimon Schubert bfd_boolean
bfd_section_from_phdr(bfd * abfd,Elf_Internal_Phdr * hdr,int hdr_index)2456cf7f2e2dSJohn Marino bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
24575796c8dcSSimon Schubert {
24585796c8dcSSimon Schubert   const struct elf_backend_data *bed;
24595796c8dcSSimon Schubert 
24605796c8dcSSimon Schubert   switch (hdr->p_type)
24615796c8dcSSimon Schubert     {
24625796c8dcSSimon Schubert     case PT_NULL:
2463cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null");
24645796c8dcSSimon Schubert 
24655796c8dcSSimon Schubert     case PT_LOAD:
2466cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load");
24675796c8dcSSimon Schubert 
24685796c8dcSSimon Schubert     case PT_DYNAMIC:
2469cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic");
24705796c8dcSSimon Schubert 
24715796c8dcSSimon Schubert     case PT_INTERP:
2472cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp");
24735796c8dcSSimon Schubert 
24745796c8dcSSimon Schubert     case PT_NOTE:
2475cf7f2e2dSJohn Marino       if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
24765796c8dcSSimon Schubert 	return FALSE;
24775796c8dcSSimon Schubert       if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz))
24785796c8dcSSimon Schubert 	return FALSE;
24795796c8dcSSimon Schubert       return TRUE;
24805796c8dcSSimon Schubert 
24815796c8dcSSimon Schubert     case PT_SHLIB:
2482cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib");
24835796c8dcSSimon Schubert 
24845796c8dcSSimon Schubert     case PT_PHDR:
2485cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr");
24865796c8dcSSimon Schubert 
24875796c8dcSSimon Schubert     case PT_GNU_EH_FRAME:
2488cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
24895796c8dcSSimon Schubert 					      "eh_frame_hdr");
24905796c8dcSSimon Schubert 
24915796c8dcSSimon Schubert     case PT_GNU_STACK:
2492cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack");
24935796c8dcSSimon Schubert 
24945796c8dcSSimon Schubert     case PT_GNU_RELRO:
2495cf7f2e2dSJohn Marino       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro");
24965796c8dcSSimon Schubert 
24975796c8dcSSimon Schubert     default:
24985796c8dcSSimon Schubert       /* Check for any processor-specific program segment types.  */
24995796c8dcSSimon Schubert       bed = get_elf_backend_data (abfd);
2500cf7f2e2dSJohn Marino       return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc");
25015796c8dcSSimon Schubert     }
25025796c8dcSSimon Schubert }
25035796c8dcSSimon Schubert 
2504c50c785cSJohn Marino /* Return the REL_HDR for SEC, assuming there is only a single one, either
2505c50c785cSJohn Marino    REL or RELA.  */
2506c50c785cSJohn Marino 
2507c50c785cSJohn Marino Elf_Internal_Shdr *
_bfd_elf_single_rel_hdr(asection * sec)2508c50c785cSJohn Marino _bfd_elf_single_rel_hdr (asection *sec)
2509c50c785cSJohn Marino {
2510c50c785cSJohn Marino   if (elf_section_data (sec)->rel.hdr)
2511c50c785cSJohn Marino     {
2512c50c785cSJohn Marino       BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
2513c50c785cSJohn Marino       return elf_section_data (sec)->rel.hdr;
2514c50c785cSJohn Marino     }
2515c50c785cSJohn Marino   else
2516c50c785cSJohn Marino     return elf_section_data (sec)->rela.hdr;
2517c50c785cSJohn Marino }
2518c50c785cSJohn Marino 
2519c50c785cSJohn Marino /* Allocate and initialize a section-header for a new reloc section,
2520c50c785cSJohn Marino    containing relocations against ASECT.  It is stored in RELDATA.  If
2521c50c785cSJohn Marino    USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
2522c50c785cSJohn Marino    relocations.  */
25235796c8dcSSimon Schubert 
25245796c8dcSSimon Schubert bfd_boolean
_bfd_elf_init_reloc_shdr(bfd * abfd,struct bfd_elf_section_reloc_data * reldata,asection * asect,bfd_boolean use_rela_p)25255796c8dcSSimon Schubert _bfd_elf_init_reloc_shdr (bfd *abfd,
2526c50c785cSJohn Marino 			  struct bfd_elf_section_reloc_data *reldata,
25275796c8dcSSimon Schubert 			  asection *asect,
25285796c8dcSSimon Schubert 			  bfd_boolean use_rela_p)
25295796c8dcSSimon Schubert {
2530c50c785cSJohn Marino   Elf_Internal_Shdr *rel_hdr;
25315796c8dcSSimon Schubert   char *name;
25325796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2533c50c785cSJohn Marino   bfd_size_type amt;
25345796c8dcSSimon Schubert 
2535c50c785cSJohn Marino   amt = sizeof (Elf_Internal_Shdr);
2536c50c785cSJohn Marino   BFD_ASSERT (reldata->hdr == NULL);
2537c50c785cSJohn Marino   rel_hdr = bfd_zalloc (abfd, amt);
2538c50c785cSJohn Marino   reldata->hdr = rel_hdr;
2539c50c785cSJohn Marino 
2540c50c785cSJohn Marino   amt = sizeof ".rela" + strlen (asect->name);
25415796c8dcSSimon Schubert   name = (char *) bfd_alloc (abfd, amt);
25425796c8dcSSimon Schubert   if (name == NULL)
25435796c8dcSSimon Schubert     return FALSE;
25445796c8dcSSimon Schubert   sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
25455796c8dcSSimon Schubert   rel_hdr->sh_name =
25465796c8dcSSimon Schubert     (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
25475796c8dcSSimon Schubert 					FALSE);
25485796c8dcSSimon Schubert   if (rel_hdr->sh_name == (unsigned int) -1)
25495796c8dcSSimon Schubert     return FALSE;
25505796c8dcSSimon Schubert   rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
25515796c8dcSSimon Schubert   rel_hdr->sh_entsize = (use_rela_p
25525796c8dcSSimon Schubert 			 ? bed->s->sizeof_rela
25535796c8dcSSimon Schubert 			 : bed->s->sizeof_rel);
25545796c8dcSSimon Schubert   rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
25555796c8dcSSimon Schubert   rel_hdr->sh_flags = 0;
25565796c8dcSSimon Schubert   rel_hdr->sh_addr = 0;
25575796c8dcSSimon Schubert   rel_hdr->sh_size = 0;
25585796c8dcSSimon Schubert   rel_hdr->sh_offset = 0;
25595796c8dcSSimon Schubert 
25605796c8dcSSimon Schubert   return TRUE;
25615796c8dcSSimon Schubert }
25625796c8dcSSimon Schubert 
25635796c8dcSSimon Schubert /* Return the default section type based on the passed in section flags.  */
25645796c8dcSSimon Schubert 
25655796c8dcSSimon Schubert int
bfd_elf_get_default_section_type(flagword flags)25665796c8dcSSimon Schubert bfd_elf_get_default_section_type (flagword flags)
25675796c8dcSSimon Schubert {
25685796c8dcSSimon Schubert   if ((flags & SEC_ALLOC) != 0
2569c50c785cSJohn Marino       && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
25705796c8dcSSimon Schubert     return SHT_NOBITS;
25715796c8dcSSimon Schubert   return SHT_PROGBITS;
25725796c8dcSSimon Schubert }
25735796c8dcSSimon Schubert 
2574c50c785cSJohn Marino struct fake_section_arg
2575c50c785cSJohn Marino {
2576c50c785cSJohn Marino   struct bfd_link_info *link_info;
2577c50c785cSJohn Marino   bfd_boolean failed;
2578c50c785cSJohn Marino };
2579c50c785cSJohn Marino 
25805796c8dcSSimon Schubert /* Set up an ELF internal section header for a section.  */
25815796c8dcSSimon Schubert 
25825796c8dcSSimon Schubert static void
elf_fake_sections(bfd * abfd,asection * asect,void * fsarg)2583c50c785cSJohn Marino elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
25845796c8dcSSimon Schubert {
2585c50c785cSJohn Marino   struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
25865796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2587c50c785cSJohn Marino   struct bfd_elf_section_data *esd = elf_section_data (asect);
25885796c8dcSSimon Schubert   Elf_Internal_Shdr *this_hdr;
25895796c8dcSSimon Schubert   unsigned int sh_type;
25905796c8dcSSimon Schubert 
2591c50c785cSJohn Marino   if (arg->failed)
25925796c8dcSSimon Schubert     {
25935796c8dcSSimon Schubert       /* We already failed; just get out of the bfd_map_over_sections
25945796c8dcSSimon Schubert 	 loop.  */
25955796c8dcSSimon Schubert       return;
25965796c8dcSSimon Schubert     }
25975796c8dcSSimon Schubert 
2598c50c785cSJohn Marino   this_hdr = &esd->this_hdr;
25995796c8dcSSimon Schubert 
26005796c8dcSSimon Schubert   this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
26015796c8dcSSimon Schubert 							  asect->name, FALSE);
26025796c8dcSSimon Schubert   if (this_hdr->sh_name == (unsigned int) -1)
26035796c8dcSSimon Schubert     {
2604c50c785cSJohn Marino       arg->failed = TRUE;
26055796c8dcSSimon Schubert       return;
26065796c8dcSSimon Schubert     }
26075796c8dcSSimon Schubert 
26085796c8dcSSimon Schubert   /* Don't clear sh_flags. Assembler may set additional bits.  */
26095796c8dcSSimon Schubert 
26105796c8dcSSimon Schubert   if ((asect->flags & SEC_ALLOC) != 0
26115796c8dcSSimon Schubert       || asect->user_set_vma)
26125796c8dcSSimon Schubert     this_hdr->sh_addr = asect->vma;
26135796c8dcSSimon Schubert   else
26145796c8dcSSimon Schubert     this_hdr->sh_addr = 0;
26155796c8dcSSimon Schubert 
26165796c8dcSSimon Schubert   this_hdr->sh_offset = 0;
26175796c8dcSSimon Schubert   this_hdr->sh_size = asect->size;
26185796c8dcSSimon Schubert   this_hdr->sh_link = 0;
26195796c8dcSSimon Schubert   this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power;
26205796c8dcSSimon Schubert   /* The sh_entsize and sh_info fields may have been set already by
26215796c8dcSSimon Schubert      copy_private_section_data.  */
26225796c8dcSSimon Schubert 
26235796c8dcSSimon Schubert   this_hdr->bfd_section = asect;
26245796c8dcSSimon Schubert   this_hdr->contents = NULL;
26255796c8dcSSimon Schubert 
26265796c8dcSSimon Schubert   /* If the section type is unspecified, we set it based on
26275796c8dcSSimon Schubert      asect->flags.  */
26285796c8dcSSimon Schubert   if ((asect->flags & SEC_GROUP) != 0)
26295796c8dcSSimon Schubert     sh_type = SHT_GROUP;
26305796c8dcSSimon Schubert   else
26315796c8dcSSimon Schubert     sh_type = bfd_elf_get_default_section_type (asect->flags);
26325796c8dcSSimon Schubert 
26335796c8dcSSimon Schubert   if (this_hdr->sh_type == SHT_NULL)
26345796c8dcSSimon Schubert     this_hdr->sh_type = sh_type;
26355796c8dcSSimon Schubert   else if (this_hdr->sh_type == SHT_NOBITS
26365796c8dcSSimon Schubert 	   && sh_type == SHT_PROGBITS
26375796c8dcSSimon Schubert 	   && (asect->flags & SEC_ALLOC) != 0)
26385796c8dcSSimon Schubert     {
26395796c8dcSSimon Schubert       /* Warn if we are changing a NOBITS section to PROGBITS, but
26405796c8dcSSimon Schubert 	 allow the link to proceed.  This can happen when users link
26415796c8dcSSimon Schubert 	 non-bss input sections to bss output sections, or emit data
26425796c8dcSSimon Schubert 	 to a bss output section via a linker script.  */
26435796c8dcSSimon Schubert       (*_bfd_error_handler)
26445796c8dcSSimon Schubert 	(_("warning: section `%A' type changed to PROGBITS"), asect);
26455796c8dcSSimon Schubert       this_hdr->sh_type = sh_type;
26465796c8dcSSimon Schubert     }
26475796c8dcSSimon Schubert 
26485796c8dcSSimon Schubert   switch (this_hdr->sh_type)
26495796c8dcSSimon Schubert     {
26505796c8dcSSimon Schubert     default:
26515796c8dcSSimon Schubert       break;
26525796c8dcSSimon Schubert 
26535796c8dcSSimon Schubert     case SHT_STRTAB:
26545796c8dcSSimon Schubert     case SHT_INIT_ARRAY:
26555796c8dcSSimon Schubert     case SHT_FINI_ARRAY:
26565796c8dcSSimon Schubert     case SHT_PREINIT_ARRAY:
26575796c8dcSSimon Schubert     case SHT_NOTE:
26585796c8dcSSimon Schubert     case SHT_NOBITS:
26595796c8dcSSimon Schubert     case SHT_PROGBITS:
26605796c8dcSSimon Schubert       break;
26615796c8dcSSimon Schubert 
26625796c8dcSSimon Schubert     case SHT_HASH:
26635796c8dcSSimon Schubert       this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
26645796c8dcSSimon Schubert       break;
26655796c8dcSSimon Schubert 
26665796c8dcSSimon Schubert     case SHT_DYNSYM:
26675796c8dcSSimon Schubert       this_hdr->sh_entsize = bed->s->sizeof_sym;
26685796c8dcSSimon Schubert       break;
26695796c8dcSSimon Schubert 
26705796c8dcSSimon Schubert     case SHT_DYNAMIC:
26715796c8dcSSimon Schubert       this_hdr->sh_entsize = bed->s->sizeof_dyn;
26725796c8dcSSimon Schubert       break;
26735796c8dcSSimon Schubert 
26745796c8dcSSimon Schubert     case SHT_RELA:
26755796c8dcSSimon Schubert       if (get_elf_backend_data (abfd)->may_use_rela_p)
26765796c8dcSSimon Schubert 	this_hdr->sh_entsize = bed->s->sizeof_rela;
26775796c8dcSSimon Schubert       break;
26785796c8dcSSimon Schubert 
26795796c8dcSSimon Schubert      case SHT_REL:
26805796c8dcSSimon Schubert       if (get_elf_backend_data (abfd)->may_use_rel_p)
26815796c8dcSSimon Schubert 	this_hdr->sh_entsize = bed->s->sizeof_rel;
26825796c8dcSSimon Schubert       break;
26835796c8dcSSimon Schubert 
26845796c8dcSSimon Schubert      case SHT_GNU_versym:
26855796c8dcSSimon Schubert       this_hdr->sh_entsize = sizeof (Elf_External_Versym);
26865796c8dcSSimon Schubert       break;
26875796c8dcSSimon Schubert 
26885796c8dcSSimon Schubert      case SHT_GNU_verdef:
26895796c8dcSSimon Schubert       this_hdr->sh_entsize = 0;
26905796c8dcSSimon Schubert       /* objcopy or strip will copy over sh_info, but may not set
26915796c8dcSSimon Schubert 	 cverdefs.  The linker will set cverdefs, but sh_info will be
26925796c8dcSSimon Schubert 	 zero.  */
26935796c8dcSSimon Schubert       if (this_hdr->sh_info == 0)
26945796c8dcSSimon Schubert 	this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
26955796c8dcSSimon Schubert       else
26965796c8dcSSimon Schubert 	BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
26975796c8dcSSimon Schubert 		    || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
26985796c8dcSSimon Schubert       break;
26995796c8dcSSimon Schubert 
27005796c8dcSSimon Schubert     case SHT_GNU_verneed:
27015796c8dcSSimon Schubert       this_hdr->sh_entsize = 0;
27025796c8dcSSimon Schubert       /* objcopy or strip will copy over sh_info, but may not set
27035796c8dcSSimon Schubert 	 cverrefs.  The linker will set cverrefs, but sh_info will be
27045796c8dcSSimon Schubert 	 zero.  */
27055796c8dcSSimon Schubert       if (this_hdr->sh_info == 0)
27065796c8dcSSimon Schubert 	this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
27075796c8dcSSimon Schubert       else
27085796c8dcSSimon Schubert 	BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
27095796c8dcSSimon Schubert 		    || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
27105796c8dcSSimon Schubert       break;
27115796c8dcSSimon Schubert 
27125796c8dcSSimon Schubert     case SHT_GROUP:
27135796c8dcSSimon Schubert       this_hdr->sh_entsize = GRP_ENTRY_SIZE;
27145796c8dcSSimon Schubert       break;
27155796c8dcSSimon Schubert 
27165796c8dcSSimon Schubert     case SHT_GNU_HASH:
27175796c8dcSSimon Schubert       this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
27185796c8dcSSimon Schubert       break;
27195796c8dcSSimon Schubert     }
27205796c8dcSSimon Schubert 
27215796c8dcSSimon Schubert   if ((asect->flags & SEC_ALLOC) != 0)
27225796c8dcSSimon Schubert     this_hdr->sh_flags |= SHF_ALLOC;
27235796c8dcSSimon Schubert   if ((asect->flags & SEC_READONLY) == 0)
27245796c8dcSSimon Schubert     this_hdr->sh_flags |= SHF_WRITE;
27255796c8dcSSimon Schubert   if ((asect->flags & SEC_CODE) != 0)
27265796c8dcSSimon Schubert     this_hdr->sh_flags |= SHF_EXECINSTR;
27275796c8dcSSimon Schubert   if ((asect->flags & SEC_MERGE) != 0)
27285796c8dcSSimon Schubert     {
27295796c8dcSSimon Schubert       this_hdr->sh_flags |= SHF_MERGE;
27305796c8dcSSimon Schubert       this_hdr->sh_entsize = asect->entsize;
27315796c8dcSSimon Schubert       if ((asect->flags & SEC_STRINGS) != 0)
27325796c8dcSSimon Schubert 	this_hdr->sh_flags |= SHF_STRINGS;
27335796c8dcSSimon Schubert     }
27345796c8dcSSimon Schubert   if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
27355796c8dcSSimon Schubert     this_hdr->sh_flags |= SHF_GROUP;
27365796c8dcSSimon Schubert   if ((asect->flags & SEC_THREAD_LOCAL) != 0)
27375796c8dcSSimon Schubert     {
27385796c8dcSSimon Schubert       this_hdr->sh_flags |= SHF_TLS;
27395796c8dcSSimon Schubert       if (asect->size == 0
27405796c8dcSSimon Schubert 	  && (asect->flags & SEC_HAS_CONTENTS) == 0)
27415796c8dcSSimon Schubert 	{
27425796c8dcSSimon Schubert 	  struct bfd_link_order *o = asect->map_tail.link_order;
27435796c8dcSSimon Schubert 
27445796c8dcSSimon Schubert 	  this_hdr->sh_size = 0;
27455796c8dcSSimon Schubert 	  if (o != NULL)
27465796c8dcSSimon Schubert 	    {
27475796c8dcSSimon Schubert 	      this_hdr->sh_size = o->offset + o->size;
27485796c8dcSSimon Schubert 	      if (this_hdr->sh_size != 0)
27495796c8dcSSimon Schubert 		this_hdr->sh_type = SHT_NOBITS;
27505796c8dcSSimon Schubert 	    }
27515796c8dcSSimon Schubert 	}
27525796c8dcSSimon Schubert     }
2753cf7f2e2dSJohn Marino   if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
2754cf7f2e2dSJohn Marino     this_hdr->sh_flags |= SHF_EXCLUDE;
27555796c8dcSSimon Schubert 
2756c50c785cSJohn Marino   /* If the section has relocs, set up a section header for the
2757c50c785cSJohn Marino      SHT_REL[A] section.  If two relocation sections are required for
2758c50c785cSJohn Marino      this section, it is up to the processor-specific back-end to
2759c50c785cSJohn Marino      create the other.  */
2760c50c785cSJohn Marino   if ((asect->flags & SEC_RELOC) != 0)
2761c50c785cSJohn Marino     {
2762c50c785cSJohn Marino       /* When doing a relocatable link, create both REL and RELA sections if
2763c50c785cSJohn Marino 	 needed.  */
2764c50c785cSJohn Marino       if (arg->link_info
2765c50c785cSJohn Marino 	  /* Do the normal setup if we wouldn't create any sections here.  */
2766c50c785cSJohn Marino 	  && esd->rel.count + esd->rela.count > 0
2767c50c785cSJohn Marino 	  && (arg->link_info->relocatable || arg->link_info->emitrelocations))
2768c50c785cSJohn Marino 	{
2769c50c785cSJohn Marino 	  if (esd->rel.count && esd->rel.hdr == NULL
2770c50c785cSJohn Marino 	      && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
2771c50c785cSJohn Marino 	    {
2772c50c785cSJohn Marino 	      arg->failed = TRUE;
2773c50c785cSJohn Marino 	      return;
2774c50c785cSJohn Marino 	    }
2775c50c785cSJohn Marino 	  if (esd->rela.count && esd->rela.hdr == NULL
2776c50c785cSJohn Marino 	      && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
2777c50c785cSJohn Marino 	    {
2778c50c785cSJohn Marino 	      arg->failed = TRUE;
2779c50c785cSJohn Marino 	      return;
2780c50c785cSJohn Marino 	    }
2781c50c785cSJohn Marino 	}
2782c50c785cSJohn Marino       else if (!_bfd_elf_init_reloc_shdr (abfd,
2783c50c785cSJohn Marino 					  (asect->use_rela_p
2784c50c785cSJohn Marino 					   ? &esd->rela : &esd->rel),
2785c50c785cSJohn Marino 					  asect,
2786c50c785cSJohn Marino 					  asect->use_rela_p))
2787c50c785cSJohn Marino 	  arg->failed = TRUE;
2788c50c785cSJohn Marino     }
2789c50c785cSJohn Marino 
27905796c8dcSSimon Schubert   /* Check for processor-specific section types.  */
27915796c8dcSSimon Schubert   sh_type = this_hdr->sh_type;
27925796c8dcSSimon Schubert   if (bed->elf_backend_fake_sections
27935796c8dcSSimon Schubert       && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
2794c50c785cSJohn Marino     arg->failed = TRUE;
27955796c8dcSSimon Schubert 
27965796c8dcSSimon Schubert   if (sh_type == SHT_NOBITS && asect->size != 0)
27975796c8dcSSimon Schubert     {
27985796c8dcSSimon Schubert       /* Don't change the header type from NOBITS if we are being
27995796c8dcSSimon Schubert 	 called for objcopy --only-keep-debug.  */
28005796c8dcSSimon Schubert       this_hdr->sh_type = sh_type;
28015796c8dcSSimon Schubert     }
28025796c8dcSSimon Schubert }
28035796c8dcSSimon Schubert 
28045796c8dcSSimon Schubert /* Fill in the contents of a SHT_GROUP section.  Called from
28055796c8dcSSimon Schubert    _bfd_elf_compute_section_file_positions for gas, objcopy, and
28065796c8dcSSimon Schubert    when ELF targets use the generic linker, ld.  Called for ld -r
28075796c8dcSSimon Schubert    from bfd_elf_final_link.  */
28085796c8dcSSimon Schubert 
28095796c8dcSSimon Schubert void
bfd_elf_set_group_contents(bfd * abfd,asection * sec,void * failedptrarg)28105796c8dcSSimon Schubert bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
28115796c8dcSSimon Schubert {
28125796c8dcSSimon Schubert   bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
28135796c8dcSSimon Schubert   asection *elt, *first;
28145796c8dcSSimon Schubert   unsigned char *loc;
28155796c8dcSSimon Schubert   bfd_boolean gas;
28165796c8dcSSimon Schubert 
28175796c8dcSSimon Schubert   /* Ignore linker created group section.  See elfNN_ia64_object_p in
28185796c8dcSSimon Schubert      elfxx-ia64.c.  */
28195796c8dcSSimon Schubert   if (((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP)
28205796c8dcSSimon Schubert       || *failedptr)
28215796c8dcSSimon Schubert     return;
28225796c8dcSSimon Schubert 
28235796c8dcSSimon Schubert   if (elf_section_data (sec)->this_hdr.sh_info == 0)
28245796c8dcSSimon Schubert     {
28255796c8dcSSimon Schubert       unsigned long symindx = 0;
28265796c8dcSSimon Schubert 
28275796c8dcSSimon Schubert       /* elf_group_id will have been set up by objcopy and the
28285796c8dcSSimon Schubert 	 generic linker.  */
28295796c8dcSSimon Schubert       if (elf_group_id (sec) != NULL)
28305796c8dcSSimon Schubert 	symindx = elf_group_id (sec)->udata.i;
28315796c8dcSSimon Schubert 
28325796c8dcSSimon Schubert       if (symindx == 0)
28335796c8dcSSimon Schubert 	{
28345796c8dcSSimon Schubert 	  /* If called from the assembler, swap_out_syms will have set up
28355796c8dcSSimon Schubert 	     elf_section_syms.  */
28365796c8dcSSimon Schubert 	  BFD_ASSERT (elf_section_syms (abfd) != NULL);
28375796c8dcSSimon Schubert 	  symindx = elf_section_syms (abfd)[sec->index]->udata.i;
28385796c8dcSSimon Schubert 	}
28395796c8dcSSimon Schubert       elf_section_data (sec)->this_hdr.sh_info = symindx;
28405796c8dcSSimon Schubert     }
28415796c8dcSSimon Schubert   else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
28425796c8dcSSimon Schubert     {
28435796c8dcSSimon Schubert       /* The ELF backend linker sets sh_info to -2 when the group
28445796c8dcSSimon Schubert 	 signature symbol is global, and thus the index can't be
28455796c8dcSSimon Schubert 	 set until all local symbols are output.  */
28465796c8dcSSimon Schubert       asection *igroup = elf_sec_group (elf_next_in_group (sec));
28475796c8dcSSimon Schubert       struct bfd_elf_section_data *sec_data = elf_section_data (igroup);
28485796c8dcSSimon Schubert       unsigned long symndx = sec_data->this_hdr.sh_info;
28495796c8dcSSimon Schubert       unsigned long extsymoff = 0;
28505796c8dcSSimon Schubert       struct elf_link_hash_entry *h;
28515796c8dcSSimon Schubert 
28525796c8dcSSimon Schubert       if (!elf_bad_symtab (igroup->owner))
28535796c8dcSSimon Schubert 	{
28545796c8dcSSimon Schubert 	  Elf_Internal_Shdr *symtab_hdr;
28555796c8dcSSimon Schubert 
28565796c8dcSSimon Schubert 	  symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
28575796c8dcSSimon Schubert 	  extsymoff = symtab_hdr->sh_info;
28585796c8dcSSimon Schubert 	}
28595796c8dcSSimon Schubert       h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
28605796c8dcSSimon Schubert       while (h->root.type == bfd_link_hash_indirect
28615796c8dcSSimon Schubert 	     || h->root.type == bfd_link_hash_warning)
28625796c8dcSSimon Schubert 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
28635796c8dcSSimon Schubert 
28645796c8dcSSimon Schubert       elf_section_data (sec)->this_hdr.sh_info = h->indx;
28655796c8dcSSimon Schubert     }
28665796c8dcSSimon Schubert 
28675796c8dcSSimon Schubert   /* The contents won't be allocated for "ld -r" or objcopy.  */
28685796c8dcSSimon Schubert   gas = TRUE;
28695796c8dcSSimon Schubert   if (sec->contents == NULL)
28705796c8dcSSimon Schubert     {
28715796c8dcSSimon Schubert       gas = FALSE;
28725796c8dcSSimon Schubert       sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);
28735796c8dcSSimon Schubert 
28745796c8dcSSimon Schubert       /* Arrange for the section to be written out.  */
28755796c8dcSSimon Schubert       elf_section_data (sec)->this_hdr.contents = sec->contents;
28765796c8dcSSimon Schubert       if (sec->contents == NULL)
28775796c8dcSSimon Schubert 	{
28785796c8dcSSimon Schubert 	  *failedptr = TRUE;
28795796c8dcSSimon Schubert 	  return;
28805796c8dcSSimon Schubert 	}
28815796c8dcSSimon Schubert     }
28825796c8dcSSimon Schubert 
28835796c8dcSSimon Schubert   loc = sec->contents + sec->size;
28845796c8dcSSimon Schubert 
28855796c8dcSSimon Schubert   /* Get the pointer to the first section in the group that gas
28865796c8dcSSimon Schubert      squirreled away here.  objcopy arranges for this to be set to the
28875796c8dcSSimon Schubert      start of the input section group.  */
28885796c8dcSSimon Schubert   first = elt = elf_next_in_group (sec);
28895796c8dcSSimon Schubert 
28905796c8dcSSimon Schubert   /* First element is a flag word.  Rest of section is elf section
28915796c8dcSSimon Schubert      indices for all the sections of the group.  Write them backwards
28925796c8dcSSimon Schubert      just to keep the group in the same order as given in .section
28935796c8dcSSimon Schubert      directives, not that it matters.  */
28945796c8dcSSimon Schubert   while (elt != NULL)
28955796c8dcSSimon Schubert     {
28965796c8dcSSimon Schubert       asection *s;
28975796c8dcSSimon Schubert 
28985796c8dcSSimon Schubert       s = elt;
28995796c8dcSSimon Schubert       if (!gas)
29005796c8dcSSimon Schubert 	s = s->output_section;
2901cf7f2e2dSJohn Marino       if (s != NULL
2902cf7f2e2dSJohn Marino 	  && !bfd_is_abs_section (s))
2903cf7f2e2dSJohn Marino 	{
2904cf7f2e2dSJohn Marino 	  unsigned int idx = elf_section_data (s)->this_idx;
2905cf7f2e2dSJohn Marino 
2906cf7f2e2dSJohn Marino 	  loc -= 4;
29075796c8dcSSimon Schubert 	  H_PUT_32 (abfd, idx, loc);
29085796c8dcSSimon Schubert 	}
29095796c8dcSSimon Schubert       elt = elf_next_in_group (elt);
29105796c8dcSSimon Schubert       if (elt == first)
29115796c8dcSSimon Schubert 	break;
29125796c8dcSSimon Schubert     }
29135796c8dcSSimon Schubert 
29145796c8dcSSimon Schubert   if ((loc -= 4) != sec->contents)
29155796c8dcSSimon Schubert     abort ();
29165796c8dcSSimon Schubert 
29175796c8dcSSimon Schubert   H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
29185796c8dcSSimon Schubert }
29195796c8dcSSimon Schubert 
29205796c8dcSSimon Schubert /* Assign all ELF section numbers.  The dummy first section is handled here
29215796c8dcSSimon Schubert    too.  The link/info pointers for the standard section types are filled
29225796c8dcSSimon Schubert    in here too, while we're at it.  */
29235796c8dcSSimon Schubert 
29245796c8dcSSimon Schubert static bfd_boolean
assign_section_numbers(bfd * abfd,struct bfd_link_info * link_info)29255796c8dcSSimon Schubert assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
29265796c8dcSSimon Schubert {
29275796c8dcSSimon Schubert   struct elf_obj_tdata *t = elf_tdata (abfd);
29285796c8dcSSimon Schubert   asection *sec;
29295796c8dcSSimon Schubert   unsigned int section_number, secn;
29305796c8dcSSimon Schubert   Elf_Internal_Shdr **i_shdrp;
29315796c8dcSSimon Schubert   struct bfd_elf_section_data *d;
29325796c8dcSSimon Schubert   bfd_boolean need_symtab;
29335796c8dcSSimon Schubert 
29345796c8dcSSimon Schubert   section_number = 1;
29355796c8dcSSimon Schubert 
29365796c8dcSSimon Schubert   _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
29375796c8dcSSimon Schubert 
29385796c8dcSSimon Schubert   /* SHT_GROUP sections are in relocatable files only.  */
29395796c8dcSSimon Schubert   if (link_info == NULL || link_info->relocatable)
29405796c8dcSSimon Schubert     {
29415796c8dcSSimon Schubert       /* Put SHT_GROUP sections first.  */
29425796c8dcSSimon Schubert       for (sec = abfd->sections; sec != NULL; sec = sec->next)
29435796c8dcSSimon Schubert 	{
29445796c8dcSSimon Schubert 	  d = elf_section_data (sec);
29455796c8dcSSimon Schubert 
29465796c8dcSSimon Schubert 	  if (d->this_hdr.sh_type == SHT_GROUP)
29475796c8dcSSimon Schubert 	    {
29485796c8dcSSimon Schubert 	      if (sec->flags & SEC_LINKER_CREATED)
29495796c8dcSSimon Schubert 		{
29505796c8dcSSimon Schubert 		  /* Remove the linker created SHT_GROUP sections.  */
29515796c8dcSSimon Schubert 		  bfd_section_list_remove (abfd, sec);
29525796c8dcSSimon Schubert 		  abfd->section_count--;
29535796c8dcSSimon Schubert 		}
29545796c8dcSSimon Schubert 	      else
29555796c8dcSSimon Schubert 		d->this_idx = section_number++;
29565796c8dcSSimon Schubert 	    }
29575796c8dcSSimon Schubert 	}
29585796c8dcSSimon Schubert     }
29595796c8dcSSimon Schubert 
29605796c8dcSSimon Schubert   for (sec = abfd->sections; sec; sec = sec->next)
29615796c8dcSSimon Schubert     {
29625796c8dcSSimon Schubert       d = elf_section_data (sec);
29635796c8dcSSimon Schubert 
29645796c8dcSSimon Schubert       if (d->this_hdr.sh_type != SHT_GROUP)
29655796c8dcSSimon Schubert 	d->this_idx = section_number++;
29665796c8dcSSimon Schubert       _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
2967c50c785cSJohn Marino       if (d->rel.hdr)
29685796c8dcSSimon Schubert 	{
2969c50c785cSJohn Marino 	  d->rel.idx = section_number++;
2970c50c785cSJohn Marino 	  _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
29715796c8dcSSimon Schubert 	}
2972c50c785cSJohn Marino       else
2973c50c785cSJohn Marino 	d->rel.idx = 0;
29745796c8dcSSimon Schubert 
2975c50c785cSJohn Marino       if (d->rela.hdr)
29765796c8dcSSimon Schubert 	{
2977c50c785cSJohn Marino 	  d->rela.idx = section_number++;
2978c50c785cSJohn Marino 	  _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
29795796c8dcSSimon Schubert 	}
29805796c8dcSSimon Schubert       else
2981c50c785cSJohn Marino 	d->rela.idx = 0;
29825796c8dcSSimon Schubert     }
29835796c8dcSSimon Schubert 
2984*ef5ccd6cSJohn Marino   elf_shstrtab_sec (abfd) = section_number++;
29855796c8dcSSimon Schubert   _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
2986*ef5ccd6cSJohn Marino   elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
29875796c8dcSSimon Schubert 
29885796c8dcSSimon Schubert   need_symtab = (bfd_get_symcount (abfd) > 0
29895796c8dcSSimon Schubert 		|| (link_info == NULL
29905796c8dcSSimon Schubert 		    && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
29915796c8dcSSimon Schubert 			== HAS_RELOC)));
29925796c8dcSSimon Schubert   if (need_symtab)
29935796c8dcSSimon Schubert     {
2994*ef5ccd6cSJohn Marino       elf_onesymtab (abfd) = section_number++;
29955796c8dcSSimon Schubert       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
29965796c8dcSSimon Schubert       if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
29975796c8dcSSimon Schubert 	{
2998*ef5ccd6cSJohn Marino 	  elf_symtab_shndx (abfd) = section_number++;
29995796c8dcSSimon Schubert 	  t->symtab_shndx_hdr.sh_name
30005796c8dcSSimon Schubert 	    = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
30015796c8dcSSimon Schubert 						  ".symtab_shndx", FALSE);
30025796c8dcSSimon Schubert 	  if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
30035796c8dcSSimon Schubert 	    return FALSE;
30045796c8dcSSimon Schubert 	}
3005*ef5ccd6cSJohn Marino       elf_strtab_sec (abfd) = section_number++;
30065796c8dcSSimon Schubert       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
30075796c8dcSSimon Schubert     }
30085796c8dcSSimon Schubert 
3009*ef5ccd6cSJohn Marino   if (section_number >= SHN_LORESERVE)
3010*ef5ccd6cSJohn Marino     {
3011*ef5ccd6cSJohn Marino       _bfd_error_handler (_("%B: too many sections: %u"),
3012*ef5ccd6cSJohn Marino 			  abfd, section_number);
3013*ef5ccd6cSJohn Marino       return FALSE;
3014*ef5ccd6cSJohn Marino     }
3015*ef5ccd6cSJohn Marino 
30165796c8dcSSimon Schubert   _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
30175796c8dcSSimon Schubert   t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
30185796c8dcSSimon Schubert 
30195796c8dcSSimon Schubert   elf_numsections (abfd) = section_number;
30205796c8dcSSimon Schubert   elf_elfheader (abfd)->e_shnum = section_number;
30215796c8dcSSimon Schubert 
30225796c8dcSSimon Schubert   /* Set up the list of section header pointers, in agreement with the
30235796c8dcSSimon Schubert      indices.  */
30245796c8dcSSimon Schubert   i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc2 (abfd, section_number,
30255796c8dcSSimon Schubert                                                 sizeof (Elf_Internal_Shdr *));
30265796c8dcSSimon Schubert   if (i_shdrp == NULL)
30275796c8dcSSimon Schubert     return FALSE;
30285796c8dcSSimon Schubert 
30295796c8dcSSimon Schubert   i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd,
30305796c8dcSSimon Schubert                                                  sizeof (Elf_Internal_Shdr));
30315796c8dcSSimon Schubert   if (i_shdrp[0] == NULL)
30325796c8dcSSimon Schubert     {
30335796c8dcSSimon Schubert       bfd_release (abfd, i_shdrp);
30345796c8dcSSimon Schubert       return FALSE;
30355796c8dcSSimon Schubert     }
30365796c8dcSSimon Schubert 
30375796c8dcSSimon Schubert   elf_elfsections (abfd) = i_shdrp;
30385796c8dcSSimon Schubert 
3039*ef5ccd6cSJohn Marino   i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr;
30405796c8dcSSimon Schubert   if (need_symtab)
30415796c8dcSSimon Schubert     {
3042*ef5ccd6cSJohn Marino       i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
30435796c8dcSSimon Schubert       if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
30445796c8dcSSimon Schubert 	{
3045*ef5ccd6cSJohn Marino 	  i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr;
3046*ef5ccd6cSJohn Marino 	  t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd);
30475796c8dcSSimon Schubert 	}
3048*ef5ccd6cSJohn Marino       i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
3049*ef5ccd6cSJohn Marino       t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
30505796c8dcSSimon Schubert     }
30515796c8dcSSimon Schubert 
30525796c8dcSSimon Schubert   for (sec = abfd->sections; sec; sec = sec->next)
30535796c8dcSSimon Schubert     {
30545796c8dcSSimon Schubert       asection *s;
30555796c8dcSSimon Schubert       const char *name;
30565796c8dcSSimon Schubert 
3057cf7f2e2dSJohn Marino       d = elf_section_data (sec);
3058cf7f2e2dSJohn Marino 
30595796c8dcSSimon Schubert       i_shdrp[d->this_idx] = &d->this_hdr;
3060c50c785cSJohn Marino       if (d->rel.idx != 0)
3061c50c785cSJohn Marino 	i_shdrp[d->rel.idx] = d->rel.hdr;
3062c50c785cSJohn Marino       if (d->rela.idx != 0)
3063c50c785cSJohn Marino 	i_shdrp[d->rela.idx] = d->rela.hdr;
30645796c8dcSSimon Schubert 
30655796c8dcSSimon Schubert       /* Fill in the sh_link and sh_info fields while we're at it.  */
30665796c8dcSSimon Schubert 
30675796c8dcSSimon Schubert       /* sh_link of a reloc section is the section index of the symbol
30685796c8dcSSimon Schubert 	 table.  sh_info is the section index of the section to which
30695796c8dcSSimon Schubert 	 the relocation entries apply.  */
3070c50c785cSJohn Marino       if (d->rel.idx != 0)
30715796c8dcSSimon Schubert 	{
3072*ef5ccd6cSJohn Marino 	  d->rel.hdr->sh_link = elf_onesymtab (abfd);
3073c50c785cSJohn Marino 	  d->rel.hdr->sh_info = d->this_idx;
30745796c8dcSSimon Schubert 	}
3075c50c785cSJohn Marino       if (d->rela.idx != 0)
30765796c8dcSSimon Schubert 	{
3077*ef5ccd6cSJohn Marino 	  d->rela.hdr->sh_link = elf_onesymtab (abfd);
3078c50c785cSJohn Marino 	  d->rela.hdr->sh_info = d->this_idx;
30795796c8dcSSimon Schubert 	}
30805796c8dcSSimon Schubert 
30815796c8dcSSimon Schubert       /* We need to set up sh_link for SHF_LINK_ORDER.  */
30825796c8dcSSimon Schubert       if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
30835796c8dcSSimon Schubert 	{
30845796c8dcSSimon Schubert 	  s = elf_linked_to_section (sec);
30855796c8dcSSimon Schubert 	  if (s)
30865796c8dcSSimon Schubert 	    {
30875796c8dcSSimon Schubert 	      /* elf_linked_to_section points to the input section.  */
30885796c8dcSSimon Schubert 	      if (link_info != NULL)
30895796c8dcSSimon Schubert 		{
30905796c8dcSSimon Schubert 		  /* Check discarded linkonce section.  */
3091*ef5ccd6cSJohn Marino 		  if (discarded_section (s))
30925796c8dcSSimon Schubert 		    {
30935796c8dcSSimon Schubert 		      asection *kept;
30945796c8dcSSimon Schubert 		      (*_bfd_error_handler)
30955796c8dcSSimon Schubert 			(_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
30965796c8dcSSimon Schubert 			 abfd, d->this_hdr.bfd_section,
30975796c8dcSSimon Schubert 			 s, s->owner);
30985796c8dcSSimon Schubert 		      /* Point to the kept section if it has the same
30995796c8dcSSimon Schubert 			 size as the discarded one.  */
31005796c8dcSSimon Schubert 		      kept = _bfd_elf_check_kept_section (s, link_info);
31015796c8dcSSimon Schubert 		      if (kept == NULL)
31025796c8dcSSimon Schubert 			{
31035796c8dcSSimon Schubert 			  bfd_set_error (bfd_error_bad_value);
31045796c8dcSSimon Schubert 			  return FALSE;
31055796c8dcSSimon Schubert 			}
31065796c8dcSSimon Schubert 		      s = kept;
31075796c8dcSSimon Schubert 		    }
31085796c8dcSSimon Schubert 
31095796c8dcSSimon Schubert 		  s = s->output_section;
31105796c8dcSSimon Schubert 		  BFD_ASSERT (s != NULL);
31115796c8dcSSimon Schubert 		}
31125796c8dcSSimon Schubert 	      else
31135796c8dcSSimon Schubert 		{
31145796c8dcSSimon Schubert 		  /* Handle objcopy. */
31155796c8dcSSimon Schubert 		  if (s->output_section == NULL)
31165796c8dcSSimon Schubert 		    {
31175796c8dcSSimon Schubert 		      (*_bfd_error_handler)
31185796c8dcSSimon Schubert 			(_("%B: sh_link of section `%A' points to removed section `%A' of `%B'"),
31195796c8dcSSimon Schubert 			 abfd, d->this_hdr.bfd_section, s, s->owner);
31205796c8dcSSimon Schubert 		      bfd_set_error (bfd_error_bad_value);
31215796c8dcSSimon Schubert 		      return FALSE;
31225796c8dcSSimon Schubert 		    }
31235796c8dcSSimon Schubert 		  s = s->output_section;
31245796c8dcSSimon Schubert 		}
31255796c8dcSSimon Schubert 	      d->this_hdr.sh_link = elf_section_data (s)->this_idx;
31265796c8dcSSimon Schubert 	    }
31275796c8dcSSimon Schubert 	  else
31285796c8dcSSimon Schubert 	    {
31295796c8dcSSimon Schubert 	      /* PR 290:
31305796c8dcSSimon Schubert 		 The Intel C compiler generates SHT_IA_64_UNWIND with
31315796c8dcSSimon Schubert 		 SHF_LINK_ORDER.  But it doesn't set the sh_link or
31325796c8dcSSimon Schubert 		 sh_info fields.  Hence we could get the situation
31335796c8dcSSimon Schubert 		 where s is NULL.  */
31345796c8dcSSimon Schubert 	      const struct elf_backend_data *bed
31355796c8dcSSimon Schubert 		= get_elf_backend_data (abfd);
31365796c8dcSSimon Schubert 	      if (bed->link_order_error_handler)
31375796c8dcSSimon Schubert 		bed->link_order_error_handler
31385796c8dcSSimon Schubert 		  (_("%B: warning: sh_link not set for section `%A'"),
31395796c8dcSSimon Schubert 		   abfd, sec);
31405796c8dcSSimon Schubert 	    }
31415796c8dcSSimon Schubert 	}
31425796c8dcSSimon Schubert 
31435796c8dcSSimon Schubert       switch (d->this_hdr.sh_type)
31445796c8dcSSimon Schubert 	{
31455796c8dcSSimon Schubert 	case SHT_REL:
31465796c8dcSSimon Schubert 	case SHT_RELA:
31475796c8dcSSimon Schubert 	  /* A reloc section which we are treating as a normal BFD
31485796c8dcSSimon Schubert 	     section.  sh_link is the section index of the symbol
31495796c8dcSSimon Schubert 	     table.  sh_info is the section index of the section to
31505796c8dcSSimon Schubert 	     which the relocation entries apply.  We assume that an
31515796c8dcSSimon Schubert 	     allocated reloc section uses the dynamic symbol table.
31525796c8dcSSimon Schubert 	     FIXME: How can we be sure?  */
31535796c8dcSSimon Schubert 	  s = bfd_get_section_by_name (abfd, ".dynsym");
31545796c8dcSSimon Schubert 	  if (s != NULL)
31555796c8dcSSimon Schubert 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
31565796c8dcSSimon Schubert 
31575796c8dcSSimon Schubert 	  /* We look up the section the relocs apply to by name.  */
31585796c8dcSSimon Schubert 	  name = sec->name;
31595796c8dcSSimon Schubert 	  if (d->this_hdr.sh_type == SHT_REL)
31605796c8dcSSimon Schubert 	    name += 4;
31615796c8dcSSimon Schubert 	  else
31625796c8dcSSimon Schubert 	    name += 5;
31635796c8dcSSimon Schubert 	  s = bfd_get_section_by_name (abfd, name);
31645796c8dcSSimon Schubert 	  if (s != NULL)
31655796c8dcSSimon Schubert 	    d->this_hdr.sh_info = elf_section_data (s)->this_idx;
31665796c8dcSSimon Schubert 	  break;
31675796c8dcSSimon Schubert 
31685796c8dcSSimon Schubert 	case SHT_STRTAB:
31695796c8dcSSimon Schubert 	  /* We assume that a section named .stab*str is a stabs
31705796c8dcSSimon Schubert 	     string section.  We look for a section with the same name
31715796c8dcSSimon Schubert 	     but without the trailing ``str'', and set its sh_link
31725796c8dcSSimon Schubert 	     field to point to this section.  */
31735796c8dcSSimon Schubert 	  if (CONST_STRNEQ (sec->name, ".stab")
31745796c8dcSSimon Schubert 	      && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
31755796c8dcSSimon Schubert 	    {
31765796c8dcSSimon Schubert 	      size_t len;
31775796c8dcSSimon Schubert 	      char *alc;
31785796c8dcSSimon Schubert 
31795796c8dcSSimon Schubert 	      len = strlen (sec->name);
31805796c8dcSSimon Schubert 	      alc = (char *) bfd_malloc (len - 2);
31815796c8dcSSimon Schubert 	      if (alc == NULL)
31825796c8dcSSimon Schubert 		return FALSE;
31835796c8dcSSimon Schubert 	      memcpy (alc, sec->name, len - 3);
31845796c8dcSSimon Schubert 	      alc[len - 3] = '\0';
31855796c8dcSSimon Schubert 	      s = bfd_get_section_by_name (abfd, alc);
31865796c8dcSSimon Schubert 	      free (alc);
31875796c8dcSSimon Schubert 	      if (s != NULL)
31885796c8dcSSimon Schubert 		{
31895796c8dcSSimon Schubert 		  elf_section_data (s)->this_hdr.sh_link = d->this_idx;
31905796c8dcSSimon Schubert 
31915796c8dcSSimon Schubert 		  /* This is a .stab section.  */
31925796c8dcSSimon Schubert 		  if (elf_section_data (s)->this_hdr.sh_entsize == 0)
31935796c8dcSSimon Schubert 		    elf_section_data (s)->this_hdr.sh_entsize
31945796c8dcSSimon Schubert 		      = 4 + 2 * bfd_get_arch_size (abfd) / 8;
31955796c8dcSSimon Schubert 		}
31965796c8dcSSimon Schubert 	    }
31975796c8dcSSimon Schubert 	  break;
31985796c8dcSSimon Schubert 
31995796c8dcSSimon Schubert 	case SHT_DYNAMIC:
32005796c8dcSSimon Schubert 	case SHT_DYNSYM:
32015796c8dcSSimon Schubert 	case SHT_GNU_verneed:
32025796c8dcSSimon Schubert 	case SHT_GNU_verdef:
32035796c8dcSSimon Schubert 	  /* sh_link is the section header index of the string table
32045796c8dcSSimon Schubert 	     used for the dynamic entries, or the symbol table, or the
32055796c8dcSSimon Schubert 	     version strings.  */
32065796c8dcSSimon Schubert 	  s = bfd_get_section_by_name (abfd, ".dynstr");
32075796c8dcSSimon Schubert 	  if (s != NULL)
32085796c8dcSSimon Schubert 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
32095796c8dcSSimon Schubert 	  break;
32105796c8dcSSimon Schubert 
32115796c8dcSSimon Schubert 	case SHT_GNU_LIBLIST:
32125796c8dcSSimon Schubert 	  /* sh_link is the section header index of the prelink library
32135796c8dcSSimon Schubert 	     list used for the dynamic entries, or the symbol table, or
32145796c8dcSSimon Schubert 	     the version strings.  */
32155796c8dcSSimon Schubert 	  s = bfd_get_section_by_name (abfd, (sec->flags & SEC_ALLOC)
32165796c8dcSSimon Schubert 					     ? ".dynstr" : ".gnu.libstr");
32175796c8dcSSimon Schubert 	  if (s != NULL)
32185796c8dcSSimon Schubert 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
32195796c8dcSSimon Schubert 	  break;
32205796c8dcSSimon Schubert 
32215796c8dcSSimon Schubert 	case SHT_HASH:
32225796c8dcSSimon Schubert 	case SHT_GNU_HASH:
32235796c8dcSSimon Schubert 	case SHT_GNU_versym:
32245796c8dcSSimon Schubert 	  /* sh_link is the section header index of the symbol table
32255796c8dcSSimon Schubert 	     this hash table or version table is for.  */
32265796c8dcSSimon Schubert 	  s = bfd_get_section_by_name (abfd, ".dynsym");
32275796c8dcSSimon Schubert 	  if (s != NULL)
32285796c8dcSSimon Schubert 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
32295796c8dcSSimon Schubert 	  break;
32305796c8dcSSimon Schubert 
32315796c8dcSSimon Schubert 	case SHT_GROUP:
3232*ef5ccd6cSJohn Marino 	  d->this_hdr.sh_link = elf_onesymtab (abfd);
32335796c8dcSSimon Schubert 	}
32345796c8dcSSimon Schubert     }
32355796c8dcSSimon Schubert 
32365796c8dcSSimon Schubert   for (secn = 1; secn < section_number; ++secn)
32375796c8dcSSimon Schubert     if (i_shdrp[secn] == NULL)
32385796c8dcSSimon Schubert       i_shdrp[secn] = i_shdrp[0];
32395796c8dcSSimon Schubert     else
32405796c8dcSSimon Schubert       i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
32415796c8dcSSimon Schubert 						       i_shdrp[secn]->sh_name);
32425796c8dcSSimon Schubert   return TRUE;
32435796c8dcSSimon Schubert }
32445796c8dcSSimon Schubert 
32455796c8dcSSimon Schubert static bfd_boolean
sym_is_global(bfd * abfd,asymbol * sym)32465796c8dcSSimon Schubert sym_is_global (bfd *abfd, asymbol *sym)
32475796c8dcSSimon Schubert {
32485796c8dcSSimon Schubert   /* If the backend has a special mapping, use it.  */
32495796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
32505796c8dcSSimon Schubert   if (bed->elf_backend_sym_is_global)
32515796c8dcSSimon Schubert     return (*bed->elf_backend_sym_is_global) (abfd, sym);
32525796c8dcSSimon Schubert 
32535796c8dcSSimon Schubert   return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
32545796c8dcSSimon Schubert 	  || bfd_is_und_section (bfd_get_section (sym))
32555796c8dcSSimon Schubert 	  || bfd_is_com_section (bfd_get_section (sym)));
32565796c8dcSSimon Schubert }
32575796c8dcSSimon Schubert 
32585796c8dcSSimon Schubert /* Don't output section symbols for sections that are not going to be
3259*ef5ccd6cSJohn Marino    output, that are duplicates or there is no BFD section.  */
32605796c8dcSSimon Schubert 
32615796c8dcSSimon Schubert static bfd_boolean
ignore_section_sym(bfd * abfd,asymbol * sym)32625796c8dcSSimon Schubert ignore_section_sym (bfd *abfd, asymbol *sym)
32635796c8dcSSimon Schubert {
3264*ef5ccd6cSJohn Marino   elf_symbol_type *type_ptr;
3265*ef5ccd6cSJohn Marino 
3266*ef5ccd6cSJohn Marino   if ((sym->flags & BSF_SECTION_SYM) == 0)
3267*ef5ccd6cSJohn Marino     return FALSE;
3268*ef5ccd6cSJohn Marino 
3269*ef5ccd6cSJohn Marino   type_ptr = elf_symbol_from (abfd, sym);
3270*ef5ccd6cSJohn Marino   return ((type_ptr != NULL
3271*ef5ccd6cSJohn Marino 	   && type_ptr->internal_elf_sym.st_shndx != 0
3272*ef5ccd6cSJohn Marino 	   && bfd_is_abs_section (sym->section))
3273*ef5ccd6cSJohn Marino 	  || !(sym->section->owner == abfd
32745796c8dcSSimon Schubert 	       || (sym->section->output_section->owner == abfd
3275*ef5ccd6cSJohn Marino 		   && sym->section->output_offset == 0)
3276*ef5ccd6cSJohn Marino 	       || bfd_is_abs_section (sym->section)));
32775796c8dcSSimon Schubert }
32785796c8dcSSimon Schubert 
3279*ef5ccd6cSJohn Marino /* Map symbol from it's internal number to the external number, moving
3280*ef5ccd6cSJohn Marino    all local symbols to be at the head of the list.  */
3281*ef5ccd6cSJohn Marino 
32825796c8dcSSimon Schubert static bfd_boolean
elf_map_symbols(bfd * abfd,unsigned int * pnum_locals)3283*ef5ccd6cSJohn Marino elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
32845796c8dcSSimon Schubert {
32855796c8dcSSimon Schubert   unsigned int symcount = bfd_get_symcount (abfd);
32865796c8dcSSimon Schubert   asymbol **syms = bfd_get_outsymbols (abfd);
32875796c8dcSSimon Schubert   asymbol **sect_syms;
32885796c8dcSSimon Schubert   unsigned int num_locals = 0;
32895796c8dcSSimon Schubert   unsigned int num_globals = 0;
32905796c8dcSSimon Schubert   unsigned int num_locals2 = 0;
32915796c8dcSSimon Schubert   unsigned int num_globals2 = 0;
32925796c8dcSSimon Schubert   int max_index = 0;
32935796c8dcSSimon Schubert   unsigned int idx;
32945796c8dcSSimon Schubert   asection *asect;
32955796c8dcSSimon Schubert   asymbol **new_syms;
32965796c8dcSSimon Schubert 
32975796c8dcSSimon Schubert #ifdef DEBUG
32985796c8dcSSimon Schubert   fprintf (stderr, "elf_map_symbols\n");
32995796c8dcSSimon Schubert   fflush (stderr);
33005796c8dcSSimon Schubert #endif
33015796c8dcSSimon Schubert 
33025796c8dcSSimon Schubert   for (asect = abfd->sections; asect; asect = asect->next)
33035796c8dcSSimon Schubert     {
33045796c8dcSSimon Schubert       if (max_index < asect->index)
33055796c8dcSSimon Schubert 	max_index = asect->index;
33065796c8dcSSimon Schubert     }
33075796c8dcSSimon Schubert 
33085796c8dcSSimon Schubert   max_index++;
33095796c8dcSSimon Schubert   sect_syms = (asymbol **) bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
33105796c8dcSSimon Schubert   if (sect_syms == NULL)
33115796c8dcSSimon Schubert     return FALSE;
33125796c8dcSSimon Schubert   elf_section_syms (abfd) = sect_syms;
33135796c8dcSSimon Schubert   elf_num_section_syms (abfd) = max_index;
33145796c8dcSSimon Schubert 
33155796c8dcSSimon Schubert   /* Init sect_syms entries for any section symbols we have already
33165796c8dcSSimon Schubert      decided to output.  */
33175796c8dcSSimon Schubert   for (idx = 0; idx < symcount; idx++)
33185796c8dcSSimon Schubert     {
33195796c8dcSSimon Schubert       asymbol *sym = syms[idx];
33205796c8dcSSimon Schubert 
33215796c8dcSSimon Schubert       if ((sym->flags & BSF_SECTION_SYM) != 0
33225796c8dcSSimon Schubert 	  && sym->value == 0
3323*ef5ccd6cSJohn Marino 	  && !ignore_section_sym (abfd, sym)
3324*ef5ccd6cSJohn Marino 	  && !bfd_is_abs_section (sym->section))
33255796c8dcSSimon Schubert 	{
33265796c8dcSSimon Schubert 	  asection *sec = sym->section;
33275796c8dcSSimon Schubert 
33285796c8dcSSimon Schubert 	  if (sec->owner != abfd)
33295796c8dcSSimon Schubert 	    sec = sec->output_section;
33305796c8dcSSimon Schubert 
33315796c8dcSSimon Schubert 	  sect_syms[sec->index] = syms[idx];
33325796c8dcSSimon Schubert 	}
33335796c8dcSSimon Schubert     }
33345796c8dcSSimon Schubert 
33355796c8dcSSimon Schubert   /* Classify all of the symbols.  */
33365796c8dcSSimon Schubert   for (idx = 0; idx < symcount; idx++)
33375796c8dcSSimon Schubert     {
3338*ef5ccd6cSJohn Marino       if (sym_is_global (abfd, syms[idx]))
33395796c8dcSSimon Schubert 	num_globals++;
3340*ef5ccd6cSJohn Marino       else if (!ignore_section_sym (abfd, syms[idx]))
3341*ef5ccd6cSJohn Marino 	num_locals++;
33425796c8dcSSimon Schubert     }
33435796c8dcSSimon Schubert 
33445796c8dcSSimon Schubert   /* We will be adding a section symbol for each normal BFD section.  Most
33455796c8dcSSimon Schubert      sections will already have a section symbol in outsymbols, but
33465796c8dcSSimon Schubert      eg. SHT_GROUP sections will not, and we need the section symbol mapped
33475796c8dcSSimon Schubert      at least in that case.  */
33485796c8dcSSimon Schubert   for (asect = abfd->sections; asect; asect = asect->next)
33495796c8dcSSimon Schubert     {
33505796c8dcSSimon Schubert       if (sect_syms[asect->index] == NULL)
33515796c8dcSSimon Schubert 	{
33525796c8dcSSimon Schubert 	  if (!sym_is_global (abfd, asect->symbol))
33535796c8dcSSimon Schubert 	    num_locals++;
33545796c8dcSSimon Schubert 	  else
33555796c8dcSSimon Schubert 	    num_globals++;
33565796c8dcSSimon Schubert 	}
33575796c8dcSSimon Schubert     }
33585796c8dcSSimon Schubert 
33595796c8dcSSimon Schubert   /* Now sort the symbols so the local symbols are first.  */
33605796c8dcSSimon Schubert   new_syms = (asymbol **) bfd_alloc2 (abfd, num_locals + num_globals,
33615796c8dcSSimon Schubert                                       sizeof (asymbol *));
33625796c8dcSSimon Schubert 
33635796c8dcSSimon Schubert   if (new_syms == NULL)
33645796c8dcSSimon Schubert     return FALSE;
33655796c8dcSSimon Schubert 
33665796c8dcSSimon Schubert   for (idx = 0; idx < symcount; idx++)
33675796c8dcSSimon Schubert     {
33685796c8dcSSimon Schubert       asymbol *sym = syms[idx];
33695796c8dcSSimon Schubert       unsigned int i;
33705796c8dcSSimon Schubert 
3371*ef5ccd6cSJohn Marino       if (sym_is_global (abfd, sym))
3372*ef5ccd6cSJohn Marino 	i = num_locals + num_globals2++;
3373*ef5ccd6cSJohn Marino       else if (!ignore_section_sym (abfd, sym))
33745796c8dcSSimon Schubert 	i = num_locals2++;
33755796c8dcSSimon Schubert       else
3376*ef5ccd6cSJohn Marino 	continue;
33775796c8dcSSimon Schubert       new_syms[i] = sym;
33785796c8dcSSimon Schubert       sym->udata.i = i + 1;
33795796c8dcSSimon Schubert     }
33805796c8dcSSimon Schubert   for (asect = abfd->sections; asect; asect = asect->next)
33815796c8dcSSimon Schubert     {
33825796c8dcSSimon Schubert       if (sect_syms[asect->index] == NULL)
33835796c8dcSSimon Schubert 	{
33845796c8dcSSimon Schubert 	  asymbol *sym = asect->symbol;
33855796c8dcSSimon Schubert 	  unsigned int i;
33865796c8dcSSimon Schubert 
33875796c8dcSSimon Schubert 	  sect_syms[asect->index] = sym;
33885796c8dcSSimon Schubert 	  if (!sym_is_global (abfd, sym))
33895796c8dcSSimon Schubert 	    i = num_locals2++;
33905796c8dcSSimon Schubert 	  else
33915796c8dcSSimon Schubert 	    i = num_locals + num_globals2++;
33925796c8dcSSimon Schubert 	  new_syms[i] = sym;
33935796c8dcSSimon Schubert 	  sym->udata.i = i + 1;
33945796c8dcSSimon Schubert 	}
33955796c8dcSSimon Schubert     }
33965796c8dcSSimon Schubert 
33975796c8dcSSimon Schubert   bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
33985796c8dcSSimon Schubert 
3399*ef5ccd6cSJohn Marino   *pnum_locals = num_locals;
34005796c8dcSSimon Schubert   return TRUE;
34015796c8dcSSimon Schubert }
34025796c8dcSSimon Schubert 
34035796c8dcSSimon Schubert /* Align to the maximum file alignment that could be required for any
34045796c8dcSSimon Schubert    ELF data structure.  */
34055796c8dcSSimon Schubert 
34065796c8dcSSimon Schubert static inline file_ptr
align_file_position(file_ptr off,int align)34075796c8dcSSimon Schubert align_file_position (file_ptr off, int align)
34085796c8dcSSimon Schubert {
34095796c8dcSSimon Schubert   return (off + align - 1) & ~(align - 1);
34105796c8dcSSimon Schubert }
34115796c8dcSSimon Schubert 
34125796c8dcSSimon Schubert /* Assign a file position to a section, optionally aligning to the
34135796c8dcSSimon Schubert    required section alignment.  */
34145796c8dcSSimon Schubert 
34155796c8dcSSimon Schubert file_ptr
_bfd_elf_assign_file_position_for_section(Elf_Internal_Shdr * i_shdrp,file_ptr offset,bfd_boolean align)34165796c8dcSSimon Schubert _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
34175796c8dcSSimon Schubert 					   file_ptr offset,
34185796c8dcSSimon Schubert 					   bfd_boolean align)
34195796c8dcSSimon Schubert {
34205796c8dcSSimon Schubert   if (align && i_shdrp->sh_addralign > 1)
34215796c8dcSSimon Schubert     offset = BFD_ALIGN (offset, i_shdrp->sh_addralign);
34225796c8dcSSimon Schubert   i_shdrp->sh_offset = offset;
34235796c8dcSSimon Schubert   if (i_shdrp->bfd_section != NULL)
34245796c8dcSSimon Schubert     i_shdrp->bfd_section->filepos = offset;
34255796c8dcSSimon Schubert   if (i_shdrp->sh_type != SHT_NOBITS)
34265796c8dcSSimon Schubert     offset += i_shdrp->sh_size;
34275796c8dcSSimon Schubert   return offset;
34285796c8dcSSimon Schubert }
34295796c8dcSSimon Schubert 
34305796c8dcSSimon Schubert /* Compute the file positions we are going to put the sections at, and
34315796c8dcSSimon Schubert    otherwise prepare to begin writing out the ELF file.  If LINK_INFO
34325796c8dcSSimon Schubert    is not NULL, this is being called by the ELF backend linker.  */
34335796c8dcSSimon Schubert 
34345796c8dcSSimon Schubert bfd_boolean
_bfd_elf_compute_section_file_positions(bfd * abfd,struct bfd_link_info * link_info)34355796c8dcSSimon Schubert _bfd_elf_compute_section_file_positions (bfd *abfd,
34365796c8dcSSimon Schubert 					 struct bfd_link_info *link_info)
34375796c8dcSSimon Schubert {
34385796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3439c50c785cSJohn Marino   struct fake_section_arg fsargs;
34405796c8dcSSimon Schubert   bfd_boolean failed;
34415796c8dcSSimon Schubert   struct bfd_strtab_hash *strtab = NULL;
34425796c8dcSSimon Schubert   Elf_Internal_Shdr *shstrtab_hdr;
34435796c8dcSSimon Schubert   bfd_boolean need_symtab;
34445796c8dcSSimon Schubert 
34455796c8dcSSimon Schubert   if (abfd->output_has_begun)
34465796c8dcSSimon Schubert     return TRUE;
34475796c8dcSSimon Schubert 
34485796c8dcSSimon Schubert   /* Do any elf backend specific processing first.  */
34495796c8dcSSimon Schubert   if (bed->elf_backend_begin_write_processing)
34505796c8dcSSimon Schubert     (*bed->elf_backend_begin_write_processing) (abfd, link_info);
34515796c8dcSSimon Schubert 
34525796c8dcSSimon Schubert   if (! prep_headers (abfd))
34535796c8dcSSimon Schubert     return FALSE;
34545796c8dcSSimon Schubert 
34555796c8dcSSimon Schubert   /* Post process the headers if necessary.  */
34565796c8dcSSimon Schubert   if (bed->elf_backend_post_process_headers)
34575796c8dcSSimon Schubert     (*bed->elf_backend_post_process_headers) (abfd, link_info);
34585796c8dcSSimon Schubert 
3459c50c785cSJohn Marino   fsargs.failed = FALSE;
3460c50c785cSJohn Marino   fsargs.link_info = link_info;
3461c50c785cSJohn Marino   bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
3462c50c785cSJohn Marino   if (fsargs.failed)
34635796c8dcSSimon Schubert     return FALSE;
34645796c8dcSSimon Schubert 
34655796c8dcSSimon Schubert   if (!assign_section_numbers (abfd, link_info))
34665796c8dcSSimon Schubert     return FALSE;
34675796c8dcSSimon Schubert 
34685796c8dcSSimon Schubert   /* The backend linker builds symbol table information itself.  */
34695796c8dcSSimon Schubert   need_symtab = (link_info == NULL
34705796c8dcSSimon Schubert 		 && (bfd_get_symcount (abfd) > 0
34715796c8dcSSimon Schubert 		     || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
34725796c8dcSSimon Schubert 			 == HAS_RELOC)));
34735796c8dcSSimon Schubert   if (need_symtab)
34745796c8dcSSimon Schubert     {
34755796c8dcSSimon Schubert       /* Non-zero if doing a relocatable link.  */
34765796c8dcSSimon Schubert       int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
34775796c8dcSSimon Schubert 
34785796c8dcSSimon Schubert       if (! swap_out_syms (abfd, &strtab, relocatable_p))
34795796c8dcSSimon Schubert 	return FALSE;
34805796c8dcSSimon Schubert     }
34815796c8dcSSimon Schubert 
3482c50c785cSJohn Marino   failed = FALSE;
34835796c8dcSSimon Schubert   if (link_info == NULL)
34845796c8dcSSimon Schubert     {
34855796c8dcSSimon Schubert       bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
34865796c8dcSSimon Schubert       if (failed)
34875796c8dcSSimon Schubert 	return FALSE;
34885796c8dcSSimon Schubert     }
34895796c8dcSSimon Schubert 
34905796c8dcSSimon Schubert   shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
34915796c8dcSSimon Schubert   /* sh_name was set in prep_headers.  */
34925796c8dcSSimon Schubert   shstrtab_hdr->sh_type = SHT_STRTAB;
34935796c8dcSSimon Schubert   shstrtab_hdr->sh_flags = 0;
34945796c8dcSSimon Schubert   shstrtab_hdr->sh_addr = 0;
34955796c8dcSSimon Schubert   shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
34965796c8dcSSimon Schubert   shstrtab_hdr->sh_entsize = 0;
34975796c8dcSSimon Schubert   shstrtab_hdr->sh_link = 0;
34985796c8dcSSimon Schubert   shstrtab_hdr->sh_info = 0;
34995796c8dcSSimon Schubert   /* sh_offset is set in assign_file_positions_except_relocs.  */
35005796c8dcSSimon Schubert   shstrtab_hdr->sh_addralign = 1;
35015796c8dcSSimon Schubert 
35025796c8dcSSimon Schubert   if (!assign_file_positions_except_relocs (abfd, link_info))
35035796c8dcSSimon Schubert     return FALSE;
35045796c8dcSSimon Schubert 
35055796c8dcSSimon Schubert   if (need_symtab)
35065796c8dcSSimon Schubert     {
35075796c8dcSSimon Schubert       file_ptr off;
35085796c8dcSSimon Schubert       Elf_Internal_Shdr *hdr;
35095796c8dcSSimon Schubert 
3510*ef5ccd6cSJohn Marino       off = elf_next_file_pos (abfd);
35115796c8dcSSimon Schubert 
35125796c8dcSSimon Schubert       hdr = &elf_tdata (abfd)->symtab_hdr;
35135796c8dcSSimon Schubert       off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
35145796c8dcSSimon Schubert 
35155796c8dcSSimon Schubert       hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
35165796c8dcSSimon Schubert       if (hdr->sh_size != 0)
35175796c8dcSSimon Schubert 	off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
35185796c8dcSSimon Schubert 
35195796c8dcSSimon Schubert       hdr = &elf_tdata (abfd)->strtab_hdr;
35205796c8dcSSimon Schubert       off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
35215796c8dcSSimon Schubert 
3522*ef5ccd6cSJohn Marino       elf_next_file_pos (abfd) = off;
35235796c8dcSSimon Schubert 
35245796c8dcSSimon Schubert       /* Now that we know where the .strtab section goes, write it
35255796c8dcSSimon Schubert 	 out.  */
35265796c8dcSSimon Schubert       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
35275796c8dcSSimon Schubert 	  || ! _bfd_stringtab_emit (abfd, strtab))
35285796c8dcSSimon Schubert 	return FALSE;
35295796c8dcSSimon Schubert       _bfd_stringtab_free (strtab);
35305796c8dcSSimon Schubert     }
35315796c8dcSSimon Schubert 
35325796c8dcSSimon Schubert   abfd->output_has_begun = TRUE;
35335796c8dcSSimon Schubert 
35345796c8dcSSimon Schubert   return TRUE;
35355796c8dcSSimon Schubert }
35365796c8dcSSimon Schubert 
35375796c8dcSSimon Schubert /* Make an initial estimate of the size of the program header.  If we
35385796c8dcSSimon Schubert    get the number wrong here, we'll redo section placement.  */
35395796c8dcSSimon Schubert 
35405796c8dcSSimon Schubert static bfd_size_type
get_program_header_size(bfd * abfd,struct bfd_link_info * info)35415796c8dcSSimon Schubert get_program_header_size (bfd *abfd, struct bfd_link_info *info)
35425796c8dcSSimon Schubert {
35435796c8dcSSimon Schubert   size_t segs;
35445796c8dcSSimon Schubert   asection *s;
35455796c8dcSSimon Schubert   const struct elf_backend_data *bed;
35465796c8dcSSimon Schubert 
35475796c8dcSSimon Schubert   /* Assume we will need exactly two PT_LOAD segments: one for text
35485796c8dcSSimon Schubert      and one for data.  */
35495796c8dcSSimon Schubert   segs = 2;
35505796c8dcSSimon Schubert 
35515796c8dcSSimon Schubert   s = bfd_get_section_by_name (abfd, ".interp");
35525796c8dcSSimon Schubert   if (s != NULL && (s->flags & SEC_LOAD) != 0)
35535796c8dcSSimon Schubert     {
35545796c8dcSSimon Schubert       /* If we have a loadable interpreter section, we need a
35555796c8dcSSimon Schubert 	 PT_INTERP segment.  In this case, assume we also need a
35565796c8dcSSimon Schubert 	 PT_PHDR segment, although that may not be true for all
35575796c8dcSSimon Schubert 	 targets.  */
35585796c8dcSSimon Schubert       segs += 2;
35595796c8dcSSimon Schubert     }
35605796c8dcSSimon Schubert 
35615796c8dcSSimon Schubert   if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
35625796c8dcSSimon Schubert     {
35635796c8dcSSimon Schubert       /* We need a PT_DYNAMIC segment.  */
35645796c8dcSSimon Schubert       ++segs;
35655796c8dcSSimon Schubert     }
35665796c8dcSSimon Schubert 
35675796c8dcSSimon Schubert   if (info != NULL && info->relro)
35685796c8dcSSimon Schubert     {
35695796c8dcSSimon Schubert       /* We need a PT_GNU_RELRO segment.  */
35705796c8dcSSimon Schubert       ++segs;
35715796c8dcSSimon Schubert     }
35725796c8dcSSimon Schubert 
3573*ef5ccd6cSJohn Marino   if (elf_eh_frame_hdr (abfd))
35745796c8dcSSimon Schubert     {
35755796c8dcSSimon Schubert       /* We need a PT_GNU_EH_FRAME segment.  */
35765796c8dcSSimon Schubert       ++segs;
35775796c8dcSSimon Schubert     }
35785796c8dcSSimon Schubert 
3579*ef5ccd6cSJohn Marino   if (elf_stack_flags (abfd))
35805796c8dcSSimon Schubert     {
35815796c8dcSSimon Schubert       /* We need a PT_GNU_STACK segment.  */
35825796c8dcSSimon Schubert       ++segs;
35835796c8dcSSimon Schubert     }
35845796c8dcSSimon Schubert 
35855796c8dcSSimon Schubert   for (s = abfd->sections; s != NULL; s = s->next)
35865796c8dcSSimon Schubert     {
35875796c8dcSSimon Schubert       if ((s->flags & SEC_LOAD) != 0
35885796c8dcSSimon Schubert 	  && CONST_STRNEQ (s->name, ".note"))
35895796c8dcSSimon Schubert 	{
35905796c8dcSSimon Schubert 	  /* We need a PT_NOTE segment.  */
35915796c8dcSSimon Schubert 	  ++segs;
35925796c8dcSSimon Schubert 	  /* Try to create just one PT_NOTE segment
35935796c8dcSSimon Schubert 	     for all adjacent loadable .note* sections.
35945796c8dcSSimon Schubert 	     gABI requires that within a PT_NOTE segment
35955796c8dcSSimon Schubert 	     (and also inside of each SHT_NOTE section)
35965796c8dcSSimon Schubert 	     each note is padded to a multiple of 4 size,
35975796c8dcSSimon Schubert 	     so we check whether the sections are correctly
35985796c8dcSSimon Schubert 	     aligned.  */
35995796c8dcSSimon Schubert 	  if (s->alignment_power == 2)
36005796c8dcSSimon Schubert 	    while (s->next != NULL
36015796c8dcSSimon Schubert 		   && s->next->alignment_power == 2
36025796c8dcSSimon Schubert 		   && (s->next->flags & SEC_LOAD) != 0
36035796c8dcSSimon Schubert 		   && CONST_STRNEQ (s->next->name, ".note"))
36045796c8dcSSimon Schubert 	      s = s->next;
36055796c8dcSSimon Schubert 	}
36065796c8dcSSimon Schubert     }
36075796c8dcSSimon Schubert 
36085796c8dcSSimon Schubert   for (s = abfd->sections; s != NULL; s = s->next)
36095796c8dcSSimon Schubert     {
36105796c8dcSSimon Schubert       if (s->flags & SEC_THREAD_LOCAL)
36115796c8dcSSimon Schubert 	{
36125796c8dcSSimon Schubert 	  /* We need a PT_TLS segment.  */
36135796c8dcSSimon Schubert 	  ++segs;
36145796c8dcSSimon Schubert 	  break;
36155796c8dcSSimon Schubert 	}
36165796c8dcSSimon Schubert     }
36175796c8dcSSimon Schubert 
36185796c8dcSSimon Schubert   /* Let the backend count up any program headers it might need.  */
36195796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
36205796c8dcSSimon Schubert   if (bed->elf_backend_additional_program_headers)
36215796c8dcSSimon Schubert     {
36225796c8dcSSimon Schubert       int a;
36235796c8dcSSimon Schubert 
36245796c8dcSSimon Schubert       a = (*bed->elf_backend_additional_program_headers) (abfd, info);
36255796c8dcSSimon Schubert       if (a == -1)
36265796c8dcSSimon Schubert 	abort ();
36275796c8dcSSimon Schubert       segs += a;
36285796c8dcSSimon Schubert     }
36295796c8dcSSimon Schubert 
36305796c8dcSSimon Schubert   return segs * bed->s->sizeof_phdr;
36315796c8dcSSimon Schubert }
36325796c8dcSSimon Schubert 
36335796c8dcSSimon Schubert /* Find the segment that contains the output_section of section.  */
36345796c8dcSSimon Schubert 
36355796c8dcSSimon Schubert Elf_Internal_Phdr *
_bfd_elf_find_segment_containing_section(bfd * abfd,asection * section)36365796c8dcSSimon Schubert _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
36375796c8dcSSimon Schubert {
36385796c8dcSSimon Schubert   struct elf_segment_map *m;
36395796c8dcSSimon Schubert   Elf_Internal_Phdr *p;
36405796c8dcSSimon Schubert 
3641*ef5ccd6cSJohn Marino   for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr;
36425796c8dcSSimon Schubert        m != NULL;
36435796c8dcSSimon Schubert        m = m->next, p++)
36445796c8dcSSimon Schubert     {
36455796c8dcSSimon Schubert       int i;
36465796c8dcSSimon Schubert 
36475796c8dcSSimon Schubert       for (i = m->count - 1; i >= 0; i--)
36485796c8dcSSimon Schubert 	if (m->sections[i] == section)
36495796c8dcSSimon Schubert 	  return p;
36505796c8dcSSimon Schubert     }
36515796c8dcSSimon Schubert 
36525796c8dcSSimon Schubert   return NULL;
36535796c8dcSSimon Schubert }
36545796c8dcSSimon Schubert 
36555796c8dcSSimon Schubert /* Create a mapping from a set of sections to a program segment.  */
36565796c8dcSSimon Schubert 
36575796c8dcSSimon Schubert static struct elf_segment_map *
make_mapping(bfd * abfd,asection ** sections,unsigned int from,unsigned int to,bfd_boolean phdr)36585796c8dcSSimon Schubert make_mapping (bfd *abfd,
36595796c8dcSSimon Schubert 	      asection **sections,
36605796c8dcSSimon Schubert 	      unsigned int from,
36615796c8dcSSimon Schubert 	      unsigned int to,
36625796c8dcSSimon Schubert 	      bfd_boolean phdr)
36635796c8dcSSimon Schubert {
36645796c8dcSSimon Schubert   struct elf_segment_map *m;
36655796c8dcSSimon Schubert   unsigned int i;
36665796c8dcSSimon Schubert   asection **hdrpp;
36675796c8dcSSimon Schubert   bfd_size_type amt;
36685796c8dcSSimon Schubert 
36695796c8dcSSimon Schubert   amt = sizeof (struct elf_segment_map);
36705796c8dcSSimon Schubert   amt += (to - from - 1) * sizeof (asection *);
36715796c8dcSSimon Schubert   m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
36725796c8dcSSimon Schubert   if (m == NULL)
36735796c8dcSSimon Schubert     return NULL;
36745796c8dcSSimon Schubert   m->next = NULL;
36755796c8dcSSimon Schubert   m->p_type = PT_LOAD;
36765796c8dcSSimon Schubert   for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
36775796c8dcSSimon Schubert     m->sections[i - from] = *hdrpp;
36785796c8dcSSimon Schubert   m->count = to - from;
36795796c8dcSSimon Schubert 
36805796c8dcSSimon Schubert   if (from == 0 && phdr)
36815796c8dcSSimon Schubert     {
36825796c8dcSSimon Schubert       /* Include the headers in the first PT_LOAD segment.  */
36835796c8dcSSimon Schubert       m->includes_filehdr = 1;
36845796c8dcSSimon Schubert       m->includes_phdrs = 1;
36855796c8dcSSimon Schubert     }
36865796c8dcSSimon Schubert 
36875796c8dcSSimon Schubert   return m;
36885796c8dcSSimon Schubert }
36895796c8dcSSimon Schubert 
36905796c8dcSSimon Schubert /* Create the PT_DYNAMIC segment, which includes DYNSEC.  Returns NULL
36915796c8dcSSimon Schubert    on failure.  */
36925796c8dcSSimon Schubert 
36935796c8dcSSimon Schubert struct elf_segment_map *
_bfd_elf_make_dynamic_segment(bfd * abfd,asection * dynsec)36945796c8dcSSimon Schubert _bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
36955796c8dcSSimon Schubert {
36965796c8dcSSimon Schubert   struct elf_segment_map *m;
36975796c8dcSSimon Schubert 
36985796c8dcSSimon Schubert   m = (struct elf_segment_map *) bfd_zalloc (abfd,
36995796c8dcSSimon Schubert                                              sizeof (struct elf_segment_map));
37005796c8dcSSimon Schubert   if (m == NULL)
37015796c8dcSSimon Schubert     return NULL;
37025796c8dcSSimon Schubert   m->next = NULL;
37035796c8dcSSimon Schubert   m->p_type = PT_DYNAMIC;
37045796c8dcSSimon Schubert   m->count = 1;
37055796c8dcSSimon Schubert   m->sections[0] = dynsec;
37065796c8dcSSimon Schubert 
37075796c8dcSSimon Schubert   return m;
37085796c8dcSSimon Schubert }
37095796c8dcSSimon Schubert 
37105796c8dcSSimon Schubert /* Possibly add or remove segments from the segment map.  */
37115796c8dcSSimon Schubert 
37125796c8dcSSimon Schubert static bfd_boolean
elf_modify_segment_map(bfd * abfd,struct bfd_link_info * info,bfd_boolean remove_empty_load)37135796c8dcSSimon Schubert elf_modify_segment_map (bfd *abfd,
37145796c8dcSSimon Schubert 			struct bfd_link_info *info,
37155796c8dcSSimon Schubert 			bfd_boolean remove_empty_load)
37165796c8dcSSimon Schubert {
37175796c8dcSSimon Schubert   struct elf_segment_map **m;
37185796c8dcSSimon Schubert   const struct elf_backend_data *bed;
37195796c8dcSSimon Schubert 
37205796c8dcSSimon Schubert   /* The placement algorithm assumes that non allocated sections are
37215796c8dcSSimon Schubert      not in PT_LOAD segments.  We ensure this here by removing such
37225796c8dcSSimon Schubert      sections from the segment map.  We also remove excluded
37235796c8dcSSimon Schubert      sections.  Finally, any PT_LOAD segment without sections is
37245796c8dcSSimon Schubert      removed.  */
3725*ef5ccd6cSJohn Marino   m = &elf_seg_map (abfd);
37265796c8dcSSimon Schubert   while (*m)
37275796c8dcSSimon Schubert     {
37285796c8dcSSimon Schubert       unsigned int i, new_count;
37295796c8dcSSimon Schubert 
37305796c8dcSSimon Schubert       for (new_count = 0, i = 0; i < (*m)->count; i++)
37315796c8dcSSimon Schubert 	{
37325796c8dcSSimon Schubert 	  if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
37335796c8dcSSimon Schubert 	      && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
37345796c8dcSSimon Schubert 		  || (*m)->p_type != PT_LOAD))
37355796c8dcSSimon Schubert 	    {
37365796c8dcSSimon Schubert 	      (*m)->sections[new_count] = (*m)->sections[i];
37375796c8dcSSimon Schubert 	      new_count++;
37385796c8dcSSimon Schubert 	    }
37395796c8dcSSimon Schubert 	}
37405796c8dcSSimon Schubert       (*m)->count = new_count;
37415796c8dcSSimon Schubert 
37425796c8dcSSimon Schubert       if (remove_empty_load && (*m)->p_type == PT_LOAD && (*m)->count == 0)
37435796c8dcSSimon Schubert 	*m = (*m)->next;
37445796c8dcSSimon Schubert       else
37455796c8dcSSimon Schubert 	m = &(*m)->next;
37465796c8dcSSimon Schubert     }
37475796c8dcSSimon Schubert 
37485796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
37495796c8dcSSimon Schubert   if (bed->elf_backend_modify_segment_map != NULL)
37505796c8dcSSimon Schubert     {
37515796c8dcSSimon Schubert       if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
37525796c8dcSSimon Schubert 	return FALSE;
37535796c8dcSSimon Schubert     }
37545796c8dcSSimon Schubert 
37555796c8dcSSimon Schubert   return TRUE;
37565796c8dcSSimon Schubert }
37575796c8dcSSimon Schubert 
37585796c8dcSSimon Schubert /* Set up a mapping from BFD sections to program segments.  */
37595796c8dcSSimon Schubert 
37605796c8dcSSimon Schubert bfd_boolean
_bfd_elf_map_sections_to_segments(bfd * abfd,struct bfd_link_info * info)37615796c8dcSSimon Schubert _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
37625796c8dcSSimon Schubert {
37635796c8dcSSimon Schubert   unsigned int count;
37645796c8dcSSimon Schubert   struct elf_segment_map *m;
37655796c8dcSSimon Schubert   asection **sections = NULL;
37665796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
37675796c8dcSSimon Schubert   bfd_boolean no_user_phdrs;
37685796c8dcSSimon Schubert 
3769*ef5ccd6cSJohn Marino   no_user_phdrs = elf_seg_map (abfd) == NULL;
3770*ef5ccd6cSJohn Marino 
3771*ef5ccd6cSJohn Marino   if (info != NULL)
3772*ef5ccd6cSJohn Marino     info->user_phdrs = !no_user_phdrs;
3773*ef5ccd6cSJohn Marino 
37745796c8dcSSimon Schubert   if (no_user_phdrs && bfd_count_sections (abfd) != 0)
37755796c8dcSSimon Schubert     {
37765796c8dcSSimon Schubert       asection *s;
37775796c8dcSSimon Schubert       unsigned int i;
37785796c8dcSSimon Schubert       struct elf_segment_map *mfirst;
37795796c8dcSSimon Schubert       struct elf_segment_map **pm;
37805796c8dcSSimon Schubert       asection *last_hdr;
37815796c8dcSSimon Schubert       bfd_vma last_size;
37825796c8dcSSimon Schubert       unsigned int phdr_index;
37835796c8dcSSimon Schubert       bfd_vma maxpagesize;
37845796c8dcSSimon Schubert       asection **hdrpp;
37855796c8dcSSimon Schubert       bfd_boolean phdr_in_segment = TRUE;
37865796c8dcSSimon Schubert       bfd_boolean writable;
37875796c8dcSSimon Schubert       int tls_count = 0;
37885796c8dcSSimon Schubert       asection *first_tls = NULL;
37895796c8dcSSimon Schubert       asection *dynsec, *eh_frame_hdr;
37905796c8dcSSimon Schubert       bfd_size_type amt;
3791c50c785cSJohn Marino       bfd_vma addr_mask, wrap_to = 0;
37925796c8dcSSimon Schubert 
37935796c8dcSSimon Schubert       /* Select the allocated sections, and sort them.  */
37945796c8dcSSimon Schubert 
37955796c8dcSSimon Schubert       sections = (asection **) bfd_malloc2 (bfd_count_sections (abfd),
37965796c8dcSSimon Schubert                                             sizeof (asection *));
37975796c8dcSSimon Schubert       if (sections == NULL)
37985796c8dcSSimon Schubert 	goto error_return;
37995796c8dcSSimon Schubert 
3800c50c785cSJohn Marino       /* Calculate top address, avoiding undefined behaviour of shift
3801c50c785cSJohn Marino 	 left operator when shift count is equal to size of type
3802c50c785cSJohn Marino 	 being shifted.  */
3803c50c785cSJohn Marino       addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1;
3804c50c785cSJohn Marino       addr_mask = (addr_mask << 1) + 1;
3805c50c785cSJohn Marino 
38065796c8dcSSimon Schubert       i = 0;
38075796c8dcSSimon Schubert       for (s = abfd->sections; s != NULL; s = s->next)
38085796c8dcSSimon Schubert 	{
38095796c8dcSSimon Schubert 	  if ((s->flags & SEC_ALLOC) != 0)
38105796c8dcSSimon Schubert 	    {
38115796c8dcSSimon Schubert 	      sections[i] = s;
38125796c8dcSSimon Schubert 	      ++i;
3813c50c785cSJohn Marino 	      /* A wrapping section potentially clashes with header.  */
3814c50c785cSJohn Marino 	      if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask))
3815c50c785cSJohn Marino 		wrap_to = (s->lma + s->size) & addr_mask;
38165796c8dcSSimon Schubert 	    }
38175796c8dcSSimon Schubert 	}
38185796c8dcSSimon Schubert       BFD_ASSERT (i <= bfd_count_sections (abfd));
38195796c8dcSSimon Schubert       count = i;
38205796c8dcSSimon Schubert 
38215796c8dcSSimon Schubert       qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);
38225796c8dcSSimon Schubert 
38235796c8dcSSimon Schubert       /* Build the mapping.  */
38245796c8dcSSimon Schubert 
38255796c8dcSSimon Schubert       mfirst = NULL;
38265796c8dcSSimon Schubert       pm = &mfirst;
38275796c8dcSSimon Schubert 
38285796c8dcSSimon Schubert       /* If we have a .interp section, then create a PT_PHDR segment for
38295796c8dcSSimon Schubert 	 the program headers and a PT_INTERP segment for the .interp
38305796c8dcSSimon Schubert 	 section.  */
38315796c8dcSSimon Schubert       s = bfd_get_section_by_name (abfd, ".interp");
38325796c8dcSSimon Schubert       if (s != NULL && (s->flags & SEC_LOAD) != 0)
38335796c8dcSSimon Schubert 	{
38345796c8dcSSimon Schubert 	  amt = sizeof (struct elf_segment_map);
38355796c8dcSSimon Schubert 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
38365796c8dcSSimon Schubert 	  if (m == NULL)
38375796c8dcSSimon Schubert 	    goto error_return;
38385796c8dcSSimon Schubert 	  m->next = NULL;
38395796c8dcSSimon Schubert 	  m->p_type = PT_PHDR;
38405796c8dcSSimon Schubert 	  /* FIXME: UnixWare and Solaris set PF_X, Irix 5 does not.  */
38415796c8dcSSimon Schubert 	  m->p_flags = PF_R | PF_X;
38425796c8dcSSimon Schubert 	  m->p_flags_valid = 1;
38435796c8dcSSimon Schubert 	  m->includes_phdrs = 1;
38445796c8dcSSimon Schubert 
38455796c8dcSSimon Schubert 	  *pm = m;
38465796c8dcSSimon Schubert 	  pm = &m->next;
38475796c8dcSSimon Schubert 
38485796c8dcSSimon Schubert 	  amt = sizeof (struct elf_segment_map);
38495796c8dcSSimon Schubert 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
38505796c8dcSSimon Schubert 	  if (m == NULL)
38515796c8dcSSimon Schubert 	    goto error_return;
38525796c8dcSSimon Schubert 	  m->next = NULL;
38535796c8dcSSimon Schubert 	  m->p_type = PT_INTERP;
38545796c8dcSSimon Schubert 	  m->count = 1;
38555796c8dcSSimon Schubert 	  m->sections[0] = s;
38565796c8dcSSimon Schubert 
38575796c8dcSSimon Schubert 	  *pm = m;
38585796c8dcSSimon Schubert 	  pm = &m->next;
38595796c8dcSSimon Schubert 	}
38605796c8dcSSimon Schubert 
38615796c8dcSSimon Schubert       /* Look through the sections.  We put sections in the same program
38625796c8dcSSimon Schubert 	 segment when the start of the second section can be placed within
38635796c8dcSSimon Schubert 	 a few bytes of the end of the first section.  */
38645796c8dcSSimon Schubert       last_hdr = NULL;
38655796c8dcSSimon Schubert       last_size = 0;
38665796c8dcSSimon Schubert       phdr_index = 0;
38675796c8dcSSimon Schubert       maxpagesize = bed->maxpagesize;
38685796c8dcSSimon Schubert       writable = FALSE;
38695796c8dcSSimon Schubert       dynsec = bfd_get_section_by_name (abfd, ".dynamic");
38705796c8dcSSimon Schubert       if (dynsec != NULL
38715796c8dcSSimon Schubert 	  && (dynsec->flags & SEC_LOAD) == 0)
38725796c8dcSSimon Schubert 	dynsec = NULL;
38735796c8dcSSimon Schubert 
38745796c8dcSSimon Schubert       /* Deal with -Ttext or something similar such that the first section
38755796c8dcSSimon Schubert 	 is not adjacent to the program headers.  This is an
38765796c8dcSSimon Schubert 	 approximation, since at this point we don't know exactly how many
38775796c8dcSSimon Schubert 	 program headers we will need.  */
38785796c8dcSSimon Schubert       if (count > 0)
38795796c8dcSSimon Schubert 	{
3880*ef5ccd6cSJohn Marino 	  bfd_size_type phdr_size = elf_program_header_size (abfd);
38815796c8dcSSimon Schubert 
38825796c8dcSSimon Schubert 	  if (phdr_size == (bfd_size_type) -1)
38835796c8dcSSimon Schubert 	    phdr_size = get_program_header_size (abfd, info);
3884*ef5ccd6cSJohn Marino 	  phdr_size += bed->s->sizeof_ehdr;
38855796c8dcSSimon Schubert 	  if ((abfd->flags & D_PAGED) == 0
3886c50c785cSJohn Marino 	      || (sections[0]->lma & addr_mask) < phdr_size
3887c50c785cSJohn Marino 	      || ((sections[0]->lma & addr_mask) % maxpagesize
3888c50c785cSJohn Marino 		  < phdr_size % maxpagesize)
3889c50c785cSJohn Marino 	      || (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to)
38905796c8dcSSimon Schubert 	    phdr_in_segment = FALSE;
38915796c8dcSSimon Schubert 	}
38925796c8dcSSimon Schubert 
38935796c8dcSSimon Schubert       for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
38945796c8dcSSimon Schubert 	{
38955796c8dcSSimon Schubert 	  asection *hdr;
38965796c8dcSSimon Schubert 	  bfd_boolean new_segment;
38975796c8dcSSimon Schubert 
38985796c8dcSSimon Schubert 	  hdr = *hdrpp;
38995796c8dcSSimon Schubert 
39005796c8dcSSimon Schubert 	  /* See if this section and the last one will fit in the same
39015796c8dcSSimon Schubert 	     segment.  */
39025796c8dcSSimon Schubert 
39035796c8dcSSimon Schubert 	  if (last_hdr == NULL)
39045796c8dcSSimon Schubert 	    {
39055796c8dcSSimon Schubert 	      /* If we don't have a segment yet, then we don't need a new
39065796c8dcSSimon Schubert 		 one (we build the last one after this loop).  */
39075796c8dcSSimon Schubert 	      new_segment = FALSE;
39085796c8dcSSimon Schubert 	    }
39095796c8dcSSimon Schubert 	  else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
39105796c8dcSSimon Schubert 	    {
39115796c8dcSSimon Schubert 	      /* If this section has a different relation between the
39125796c8dcSSimon Schubert 		 virtual address and the load address, then we need a new
39135796c8dcSSimon Schubert 		 segment.  */
39145796c8dcSSimon Schubert 	      new_segment = TRUE;
39155796c8dcSSimon Schubert 	    }
3916c50c785cSJohn Marino 	  else if (hdr->lma < last_hdr->lma + last_size
3917c50c785cSJohn Marino 		   || last_hdr->lma + last_size < last_hdr->lma)
3918c50c785cSJohn Marino 	    {
3919c50c785cSJohn Marino 	      /* If this section has a load address that makes it overlap
3920c50c785cSJohn Marino 		 the previous section, then we need a new segment.  */
3921c50c785cSJohn Marino 	      new_segment = TRUE;
3922c50c785cSJohn Marino 	    }
39235796c8dcSSimon Schubert 	  /* In the next test we have to be careful when last_hdr->lma is close
39245796c8dcSSimon Schubert 	     to the end of the address space.  If the aligned address wraps
39255796c8dcSSimon Schubert 	     around to the start of the address space, then there are no more
39265796c8dcSSimon Schubert 	     pages left in memory and it is OK to assume that the current
39275796c8dcSSimon Schubert 	     section can be included in the current segment.  */
39285796c8dcSSimon Schubert 	  else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
39295796c8dcSSimon Schubert 		    > last_hdr->lma)
39305796c8dcSSimon Schubert 		   && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) + maxpagesize
39315796c8dcSSimon Schubert 		       <= hdr->lma))
39325796c8dcSSimon Schubert 	    {
39335796c8dcSSimon Schubert 	      /* If putting this section in this segment would force us to
39345796c8dcSSimon Schubert 		 skip a page in the segment, then we need a new segment.  */
39355796c8dcSSimon Schubert 	      new_segment = TRUE;
39365796c8dcSSimon Schubert 	    }
39375796c8dcSSimon Schubert 	  else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
39385796c8dcSSimon Schubert 		   && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
39395796c8dcSSimon Schubert 	    {
39405796c8dcSSimon Schubert 	      /* We don't want to put a loadable section after a
39415796c8dcSSimon Schubert 		 nonloadable section in the same segment.
39425796c8dcSSimon Schubert 		 Consider .tbss sections as loadable for this purpose.  */
39435796c8dcSSimon Schubert 	      new_segment = TRUE;
39445796c8dcSSimon Schubert 	    }
39455796c8dcSSimon Schubert 	  else if ((abfd->flags & D_PAGED) == 0)
39465796c8dcSSimon Schubert 	    {
39475796c8dcSSimon Schubert 	      /* If the file is not demand paged, which means that we
39485796c8dcSSimon Schubert 		 don't require the sections to be correctly aligned in the
39495796c8dcSSimon Schubert 		 file, then there is no other reason for a new segment.  */
39505796c8dcSSimon Schubert 	      new_segment = FALSE;
39515796c8dcSSimon Schubert 	    }
39525796c8dcSSimon Schubert 	  else if (! writable
39535796c8dcSSimon Schubert 		   && (hdr->flags & SEC_READONLY) == 0
3954c50c785cSJohn Marino 		   && (((last_hdr->lma + last_size - 1) & -maxpagesize)
3955c50c785cSJohn Marino 		       != (hdr->lma & -maxpagesize)))
39565796c8dcSSimon Schubert 	    {
39575796c8dcSSimon Schubert 	      /* We don't want to put a writable section in a read only
39585796c8dcSSimon Schubert 		 segment, unless they are on the same page in memory
39595796c8dcSSimon Schubert 		 anyhow.  We already know that the last section does not
39605796c8dcSSimon Schubert 		 bring us past the current section on the page, so the
39615796c8dcSSimon Schubert 		 only case in which the new section is not on the same
39625796c8dcSSimon Schubert 		 page as the previous section is when the previous section
39635796c8dcSSimon Schubert 		 ends precisely on a page boundary.  */
39645796c8dcSSimon Schubert 	      new_segment = TRUE;
39655796c8dcSSimon Schubert 	    }
39665796c8dcSSimon Schubert 	  else
39675796c8dcSSimon Schubert 	    {
39685796c8dcSSimon Schubert 	      /* Otherwise, we can use the same segment.  */
39695796c8dcSSimon Schubert 	      new_segment = FALSE;
39705796c8dcSSimon Schubert 	    }
39715796c8dcSSimon Schubert 
39725796c8dcSSimon Schubert 	  /* Allow interested parties a chance to override our decision.  */
39735796c8dcSSimon Schubert 	  if (last_hdr != NULL
39745796c8dcSSimon Schubert 	      && info != NULL
39755796c8dcSSimon Schubert 	      && info->callbacks->override_segment_assignment != NULL)
39765796c8dcSSimon Schubert 	    new_segment
39775796c8dcSSimon Schubert 	      = info->callbacks->override_segment_assignment (info, abfd, hdr,
39785796c8dcSSimon Schubert 							      last_hdr,
39795796c8dcSSimon Schubert 							      new_segment);
39805796c8dcSSimon Schubert 
39815796c8dcSSimon Schubert 	  if (! new_segment)
39825796c8dcSSimon Schubert 	    {
39835796c8dcSSimon Schubert 	      if ((hdr->flags & SEC_READONLY) == 0)
39845796c8dcSSimon Schubert 		writable = TRUE;
39855796c8dcSSimon Schubert 	      last_hdr = hdr;
39865796c8dcSSimon Schubert 	      /* .tbss sections effectively have zero size.  */
39875796c8dcSSimon Schubert 	      if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
39885796c8dcSSimon Schubert 		  != SEC_THREAD_LOCAL)
39895796c8dcSSimon Schubert 		last_size = hdr->size;
39905796c8dcSSimon Schubert 	      else
39915796c8dcSSimon Schubert 		last_size = 0;
39925796c8dcSSimon Schubert 	      continue;
39935796c8dcSSimon Schubert 	    }
39945796c8dcSSimon Schubert 
39955796c8dcSSimon Schubert 	  /* We need a new program segment.  We must create a new program
39965796c8dcSSimon Schubert 	     header holding all the sections from phdr_index until hdr.  */
39975796c8dcSSimon Schubert 
39985796c8dcSSimon Schubert 	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
39995796c8dcSSimon Schubert 	  if (m == NULL)
40005796c8dcSSimon Schubert 	    goto error_return;
40015796c8dcSSimon Schubert 
40025796c8dcSSimon Schubert 	  *pm = m;
40035796c8dcSSimon Schubert 	  pm = &m->next;
40045796c8dcSSimon Schubert 
40055796c8dcSSimon Schubert 	  if ((hdr->flags & SEC_READONLY) == 0)
40065796c8dcSSimon Schubert 	    writable = TRUE;
40075796c8dcSSimon Schubert 	  else
40085796c8dcSSimon Schubert 	    writable = FALSE;
40095796c8dcSSimon Schubert 
40105796c8dcSSimon Schubert 	  last_hdr = hdr;
40115796c8dcSSimon Schubert 	  /* .tbss sections effectively have zero size.  */
40125796c8dcSSimon Schubert 	  if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
40135796c8dcSSimon Schubert 	    last_size = hdr->size;
40145796c8dcSSimon Schubert 	  else
40155796c8dcSSimon Schubert 	    last_size = 0;
40165796c8dcSSimon Schubert 	  phdr_index = i;
40175796c8dcSSimon Schubert 	  phdr_in_segment = FALSE;
40185796c8dcSSimon Schubert 	}
40195796c8dcSSimon Schubert 
4020a45ae5f8SJohn Marino       /* Create a final PT_LOAD program segment, but not if it's just
4021a45ae5f8SJohn Marino 	 for .tbss.  */
4022a45ae5f8SJohn Marino       if (last_hdr != NULL
4023a45ae5f8SJohn Marino 	  && (i - phdr_index != 1
4024a45ae5f8SJohn Marino 	      || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
4025a45ae5f8SJohn Marino 		  != SEC_THREAD_LOCAL)))
40265796c8dcSSimon Schubert 	{
40275796c8dcSSimon Schubert 	  m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
40285796c8dcSSimon Schubert 	  if (m == NULL)
40295796c8dcSSimon Schubert 	    goto error_return;
40305796c8dcSSimon Schubert 
40315796c8dcSSimon Schubert 	  *pm = m;
40325796c8dcSSimon Schubert 	  pm = &m->next;
40335796c8dcSSimon Schubert 	}
40345796c8dcSSimon Schubert 
40355796c8dcSSimon Schubert       /* If there is a .dynamic section, throw in a PT_DYNAMIC segment.  */
40365796c8dcSSimon Schubert       if (dynsec != NULL)
40375796c8dcSSimon Schubert 	{
40385796c8dcSSimon Schubert 	  m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
40395796c8dcSSimon Schubert 	  if (m == NULL)
40405796c8dcSSimon Schubert 	    goto error_return;
40415796c8dcSSimon Schubert 	  *pm = m;
40425796c8dcSSimon Schubert 	  pm = &m->next;
40435796c8dcSSimon Schubert 	}
40445796c8dcSSimon Schubert 
40455796c8dcSSimon Schubert       /* For each batch of consecutive loadable .note sections,
40465796c8dcSSimon Schubert 	 add a PT_NOTE segment.  We don't use bfd_get_section_by_name,
40475796c8dcSSimon Schubert 	 because if we link together nonloadable .note sections and
40485796c8dcSSimon Schubert 	 loadable .note sections, we will generate two .note sections
40495796c8dcSSimon Schubert 	 in the output file.  FIXME: Using names for section types is
40505796c8dcSSimon Schubert 	 bogus anyhow.  */
40515796c8dcSSimon Schubert       for (s = abfd->sections; s != NULL; s = s->next)
40525796c8dcSSimon Schubert 	{
40535796c8dcSSimon Schubert 	  if ((s->flags & SEC_LOAD) != 0
40545796c8dcSSimon Schubert 	      && CONST_STRNEQ (s->name, ".note"))
40555796c8dcSSimon Schubert 	    {
40565796c8dcSSimon Schubert 	      asection *s2;
4057cf7f2e2dSJohn Marino 
4058cf7f2e2dSJohn Marino 	      count = 1;
40595796c8dcSSimon Schubert 	      amt = sizeof (struct elf_segment_map);
40605796c8dcSSimon Schubert 	      if (s->alignment_power == 2)
40615796c8dcSSimon Schubert 		for (s2 = s; s2->next != NULL; s2 = s2->next)
40625796c8dcSSimon Schubert 		  {
40635796c8dcSSimon Schubert 		    if (s2->next->alignment_power == 2
40645796c8dcSSimon Schubert 			&& (s2->next->flags & SEC_LOAD) != 0
40655796c8dcSSimon Schubert 			&& CONST_STRNEQ (s2->next->name, ".note")
4066c50c785cSJohn Marino 			&& align_power (s2->lma + s2->size, 2)
4067c50c785cSJohn Marino 			   == s2->next->lma)
40685796c8dcSSimon Schubert 		      count++;
40695796c8dcSSimon Schubert 		    else
40705796c8dcSSimon Schubert 		      break;
40715796c8dcSSimon Schubert 		  }
40725796c8dcSSimon Schubert 	      amt += (count - 1) * sizeof (asection *);
40735796c8dcSSimon Schubert 	      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
40745796c8dcSSimon Schubert 	      if (m == NULL)
40755796c8dcSSimon Schubert 		goto error_return;
40765796c8dcSSimon Schubert 	      m->next = NULL;
40775796c8dcSSimon Schubert 	      m->p_type = PT_NOTE;
40785796c8dcSSimon Schubert 	      m->count = count;
40795796c8dcSSimon Schubert 	      while (count > 1)
40805796c8dcSSimon Schubert 		{
40815796c8dcSSimon Schubert 		  m->sections[m->count - count--] = s;
40825796c8dcSSimon Schubert 		  BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
40835796c8dcSSimon Schubert 		  s = s->next;
40845796c8dcSSimon Schubert 		}
40855796c8dcSSimon Schubert 	      m->sections[m->count - 1] = s;
40865796c8dcSSimon Schubert 	      BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
40875796c8dcSSimon Schubert 	      *pm = m;
40885796c8dcSSimon Schubert 	      pm = &m->next;
40895796c8dcSSimon Schubert 	    }
40905796c8dcSSimon Schubert 	  if (s->flags & SEC_THREAD_LOCAL)
40915796c8dcSSimon Schubert 	    {
40925796c8dcSSimon Schubert 	      if (! tls_count)
40935796c8dcSSimon Schubert 		first_tls = s;
40945796c8dcSSimon Schubert 	      tls_count++;
40955796c8dcSSimon Schubert 	    }
40965796c8dcSSimon Schubert 	}
40975796c8dcSSimon Schubert 
40985796c8dcSSimon Schubert       /* If there are any SHF_TLS output sections, add PT_TLS segment.  */
40995796c8dcSSimon Schubert       if (tls_count > 0)
41005796c8dcSSimon Schubert 	{
41015796c8dcSSimon Schubert 	  amt = sizeof (struct elf_segment_map);
41025796c8dcSSimon Schubert 	  amt += (tls_count - 1) * sizeof (asection *);
41035796c8dcSSimon Schubert 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41045796c8dcSSimon Schubert 	  if (m == NULL)
41055796c8dcSSimon Schubert 	    goto error_return;
41065796c8dcSSimon Schubert 	  m->next = NULL;
41075796c8dcSSimon Schubert 	  m->p_type = PT_TLS;
41085796c8dcSSimon Schubert 	  m->count = tls_count;
41095796c8dcSSimon Schubert 	  /* Mandated PF_R.  */
41105796c8dcSSimon Schubert 	  m->p_flags = PF_R;
41115796c8dcSSimon Schubert 	  m->p_flags_valid = 1;
4112cf7f2e2dSJohn Marino 	  for (i = 0; i < (unsigned int) tls_count; ++i)
41135796c8dcSSimon Schubert 	    {
41145796c8dcSSimon Schubert 	      BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
41155796c8dcSSimon Schubert 	      m->sections[i] = first_tls;
41165796c8dcSSimon Schubert 	      first_tls = first_tls->next;
41175796c8dcSSimon Schubert 	    }
41185796c8dcSSimon Schubert 
41195796c8dcSSimon Schubert 	  *pm = m;
41205796c8dcSSimon Schubert 	  pm = &m->next;
41215796c8dcSSimon Schubert 	}
41225796c8dcSSimon Schubert 
41235796c8dcSSimon Schubert       /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
41245796c8dcSSimon Schubert 	 segment.  */
4125*ef5ccd6cSJohn Marino       eh_frame_hdr = elf_eh_frame_hdr (abfd);
41265796c8dcSSimon Schubert       if (eh_frame_hdr != NULL
41275796c8dcSSimon Schubert 	  && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
41285796c8dcSSimon Schubert 	{
41295796c8dcSSimon Schubert 	  amt = sizeof (struct elf_segment_map);
41305796c8dcSSimon Schubert 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41315796c8dcSSimon Schubert 	  if (m == NULL)
41325796c8dcSSimon Schubert 	    goto error_return;
41335796c8dcSSimon Schubert 	  m->next = NULL;
41345796c8dcSSimon Schubert 	  m->p_type = PT_GNU_EH_FRAME;
41355796c8dcSSimon Schubert 	  m->count = 1;
41365796c8dcSSimon Schubert 	  m->sections[0] = eh_frame_hdr->output_section;
41375796c8dcSSimon Schubert 
41385796c8dcSSimon Schubert 	  *pm = m;
41395796c8dcSSimon Schubert 	  pm = &m->next;
41405796c8dcSSimon Schubert 	}
41415796c8dcSSimon Schubert 
4142*ef5ccd6cSJohn Marino       if (elf_stack_flags (abfd))
41435796c8dcSSimon Schubert 	{
41445796c8dcSSimon Schubert 	  amt = sizeof (struct elf_segment_map);
41455796c8dcSSimon Schubert 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41465796c8dcSSimon Schubert 	  if (m == NULL)
41475796c8dcSSimon Schubert 	    goto error_return;
41485796c8dcSSimon Schubert 	  m->next = NULL;
41495796c8dcSSimon Schubert 	  m->p_type = PT_GNU_STACK;
4150*ef5ccd6cSJohn Marino 	  m->p_flags = elf_stack_flags (abfd);
4151*ef5ccd6cSJohn Marino 	  m->p_align = bed->stack_align;
41525796c8dcSSimon Schubert 	  m->p_flags_valid = 1;
4153*ef5ccd6cSJohn Marino 	  m->p_align_valid = m->p_align != 0;
4154*ef5ccd6cSJohn Marino 	  if (info->stacksize > 0)
4155*ef5ccd6cSJohn Marino 	    {
4156*ef5ccd6cSJohn Marino 	      m->p_size = info->stacksize;
4157*ef5ccd6cSJohn Marino 	      m->p_size_valid = 1;
4158*ef5ccd6cSJohn Marino 	    }
41595796c8dcSSimon Schubert 
41605796c8dcSSimon Schubert 	  *pm = m;
41615796c8dcSSimon Schubert 	  pm = &m->next;
41625796c8dcSSimon Schubert 	}
41635796c8dcSSimon Schubert 
41645796c8dcSSimon Schubert       if (info != NULL && info->relro)
41655796c8dcSSimon Schubert 	{
41665796c8dcSSimon Schubert 	  for (m = mfirst; m != NULL; m = m->next)
41675796c8dcSSimon Schubert 	    {
4168*ef5ccd6cSJohn Marino 	      if (m->p_type == PT_LOAD
4169*ef5ccd6cSJohn Marino 		  && m->count != 0
4170*ef5ccd6cSJohn Marino 		  && m->sections[0]->vma >= info->relro_start
4171*ef5ccd6cSJohn Marino 		  && m->sections[0]->vma < info->relro_end)
41725796c8dcSSimon Schubert 		{
4173*ef5ccd6cSJohn Marino 		  i = m->count;
4174*ef5ccd6cSJohn Marino 		  while (--i != (unsigned) -1)
4175*ef5ccd6cSJohn Marino 		    if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS))
4176*ef5ccd6cSJohn Marino 			== (SEC_LOAD | SEC_HAS_CONTENTS))
4177*ef5ccd6cSJohn Marino 		      break;
41785796c8dcSSimon Schubert 
4179*ef5ccd6cSJohn Marino 		  if (i == (unsigned) -1)
4180*ef5ccd6cSJohn Marino 		    continue;
4181*ef5ccd6cSJohn Marino 
4182*ef5ccd6cSJohn Marino 		  if (m->sections[i]->vma + m->sections[i]->size
4183*ef5ccd6cSJohn Marino 		      >= info->relro_end)
41845796c8dcSSimon Schubert 		    break;
41855796c8dcSSimon Schubert 		}
41865796c8dcSSimon Schubert 	    }
41875796c8dcSSimon Schubert 
41885796c8dcSSimon Schubert 	  /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
41895796c8dcSSimon Schubert 	  if (m != NULL)
41905796c8dcSSimon Schubert 	    {
41915796c8dcSSimon Schubert 	      amt = sizeof (struct elf_segment_map);
41925796c8dcSSimon Schubert 	      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
41935796c8dcSSimon Schubert 	      if (m == NULL)
41945796c8dcSSimon Schubert 		goto error_return;
41955796c8dcSSimon Schubert 	      m->next = NULL;
41965796c8dcSSimon Schubert 	      m->p_type = PT_GNU_RELRO;
41975796c8dcSSimon Schubert 	      m->p_flags = PF_R;
41985796c8dcSSimon Schubert 	      m->p_flags_valid = 1;
41995796c8dcSSimon Schubert 
42005796c8dcSSimon Schubert 	      *pm = m;
42015796c8dcSSimon Schubert 	      pm = &m->next;
42025796c8dcSSimon Schubert 	    }
42035796c8dcSSimon Schubert 	}
42045796c8dcSSimon Schubert 
42055796c8dcSSimon Schubert       free (sections);
4206*ef5ccd6cSJohn Marino       elf_seg_map (abfd) = mfirst;
42075796c8dcSSimon Schubert     }
42085796c8dcSSimon Schubert 
42095796c8dcSSimon Schubert   if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
42105796c8dcSSimon Schubert     return FALSE;
42115796c8dcSSimon Schubert 
4212*ef5ccd6cSJohn Marino   for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
42135796c8dcSSimon Schubert     ++count;
4214*ef5ccd6cSJohn Marino   elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;
42155796c8dcSSimon Schubert 
42165796c8dcSSimon Schubert   return TRUE;
42175796c8dcSSimon Schubert 
42185796c8dcSSimon Schubert  error_return:
42195796c8dcSSimon Schubert   if (sections != NULL)
42205796c8dcSSimon Schubert     free (sections);
42215796c8dcSSimon Schubert   return FALSE;
42225796c8dcSSimon Schubert }
42235796c8dcSSimon Schubert 
42245796c8dcSSimon Schubert /* Sort sections by address.  */
42255796c8dcSSimon Schubert 
42265796c8dcSSimon Schubert static int
elf_sort_sections(const void * arg1,const void * arg2)42275796c8dcSSimon Schubert elf_sort_sections (const void *arg1, const void *arg2)
42285796c8dcSSimon Schubert {
42295796c8dcSSimon Schubert   const asection *sec1 = *(const asection **) arg1;
42305796c8dcSSimon Schubert   const asection *sec2 = *(const asection **) arg2;
42315796c8dcSSimon Schubert   bfd_size_type size1, size2;
42325796c8dcSSimon Schubert 
42335796c8dcSSimon Schubert   /* Sort by LMA first, since this is the address used to
42345796c8dcSSimon Schubert      place the section into a segment.  */
42355796c8dcSSimon Schubert   if (sec1->lma < sec2->lma)
42365796c8dcSSimon Schubert     return -1;
42375796c8dcSSimon Schubert   else if (sec1->lma > sec2->lma)
42385796c8dcSSimon Schubert     return 1;
42395796c8dcSSimon Schubert 
42405796c8dcSSimon Schubert   /* Then sort by VMA.  Normally the LMA and the VMA will be
42415796c8dcSSimon Schubert      the same, and this will do nothing.  */
42425796c8dcSSimon Schubert   if (sec1->vma < sec2->vma)
42435796c8dcSSimon Schubert     return -1;
42445796c8dcSSimon Schubert   else if (sec1->vma > sec2->vma)
42455796c8dcSSimon Schubert     return 1;
42465796c8dcSSimon Schubert 
42475796c8dcSSimon Schubert   /* Put !SEC_LOAD sections after SEC_LOAD ones.  */
42485796c8dcSSimon Schubert 
42495796c8dcSSimon Schubert #define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
42505796c8dcSSimon Schubert 
42515796c8dcSSimon Schubert   if (TOEND (sec1))
42525796c8dcSSimon Schubert     {
42535796c8dcSSimon Schubert       if (TOEND (sec2))
42545796c8dcSSimon Schubert 	{
42555796c8dcSSimon Schubert 	  /* If the indicies are the same, do not return 0
42565796c8dcSSimon Schubert 	     here, but continue to try the next comparison.  */
42575796c8dcSSimon Schubert 	  if (sec1->target_index - sec2->target_index != 0)
42585796c8dcSSimon Schubert 	    return sec1->target_index - sec2->target_index;
42595796c8dcSSimon Schubert 	}
42605796c8dcSSimon Schubert       else
42615796c8dcSSimon Schubert 	return 1;
42625796c8dcSSimon Schubert     }
42635796c8dcSSimon Schubert   else if (TOEND (sec2))
42645796c8dcSSimon Schubert     return -1;
42655796c8dcSSimon Schubert 
42665796c8dcSSimon Schubert #undef TOEND
42675796c8dcSSimon Schubert 
42685796c8dcSSimon Schubert   /* Sort by size, to put zero sized sections
42695796c8dcSSimon Schubert      before others at the same address.  */
42705796c8dcSSimon Schubert 
42715796c8dcSSimon Schubert   size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
42725796c8dcSSimon Schubert   size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;
42735796c8dcSSimon Schubert 
42745796c8dcSSimon Schubert   if (size1 < size2)
42755796c8dcSSimon Schubert     return -1;
42765796c8dcSSimon Schubert   if (size1 > size2)
42775796c8dcSSimon Schubert     return 1;
42785796c8dcSSimon Schubert 
42795796c8dcSSimon Schubert   return sec1->target_index - sec2->target_index;
42805796c8dcSSimon Schubert }
42815796c8dcSSimon Schubert 
42825796c8dcSSimon Schubert /* Ian Lance Taylor writes:
42835796c8dcSSimon Schubert 
42845796c8dcSSimon Schubert    We shouldn't be using % with a negative signed number.  That's just
42855796c8dcSSimon Schubert    not good.  We have to make sure either that the number is not
42865796c8dcSSimon Schubert    negative, or that the number has an unsigned type.  When the types
42875796c8dcSSimon Schubert    are all the same size they wind up as unsigned.  When file_ptr is a
42885796c8dcSSimon Schubert    larger signed type, the arithmetic winds up as signed long long,
42895796c8dcSSimon Schubert    which is wrong.
42905796c8dcSSimon Schubert 
42915796c8dcSSimon Schubert    What we're trying to say here is something like ``increase OFF by
42925796c8dcSSimon Schubert    the least amount that will cause it to be equal to the VMA modulo
42935796c8dcSSimon Schubert    the page size.''  */
42945796c8dcSSimon Schubert /* In other words, something like:
42955796c8dcSSimon Schubert 
42965796c8dcSSimon Schubert    vma_offset = m->sections[0]->vma % bed->maxpagesize;
42975796c8dcSSimon Schubert    off_offset = off % bed->maxpagesize;
42985796c8dcSSimon Schubert    if (vma_offset < off_offset)
42995796c8dcSSimon Schubert      adjustment = vma_offset + bed->maxpagesize - off_offset;
43005796c8dcSSimon Schubert    else
43015796c8dcSSimon Schubert      adjustment = vma_offset - off_offset;
43025796c8dcSSimon Schubert 
43035796c8dcSSimon Schubert    which can can be collapsed into the expression below.  */
43045796c8dcSSimon Schubert 
43055796c8dcSSimon Schubert static file_ptr
vma_page_aligned_bias(bfd_vma vma,ufile_ptr off,bfd_vma maxpagesize)43065796c8dcSSimon Schubert vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
43075796c8dcSSimon Schubert {
43085796c8dcSSimon Schubert   return ((vma - off) % maxpagesize);
43095796c8dcSSimon Schubert }
43105796c8dcSSimon Schubert 
43115796c8dcSSimon Schubert static void
print_segment_map(const struct elf_segment_map * m)43125796c8dcSSimon Schubert print_segment_map (const struct elf_segment_map *m)
43135796c8dcSSimon Schubert {
43145796c8dcSSimon Schubert   unsigned int j;
43155796c8dcSSimon Schubert   const char *pt = get_segment_type (m->p_type);
43165796c8dcSSimon Schubert   char buf[32];
43175796c8dcSSimon Schubert 
43185796c8dcSSimon Schubert   if (pt == NULL)
43195796c8dcSSimon Schubert     {
43205796c8dcSSimon Schubert       if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC)
43215796c8dcSSimon Schubert 	sprintf (buf, "LOPROC+%7.7x",
43225796c8dcSSimon Schubert 		 (unsigned int) (m->p_type - PT_LOPROC));
43235796c8dcSSimon Schubert       else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS)
43245796c8dcSSimon Schubert 	sprintf (buf, "LOOS+%7.7x",
43255796c8dcSSimon Schubert 		 (unsigned int) (m->p_type - PT_LOOS));
43265796c8dcSSimon Schubert       else
43275796c8dcSSimon Schubert 	snprintf (buf, sizeof (buf), "%8.8x",
43285796c8dcSSimon Schubert 		  (unsigned int) m->p_type);
43295796c8dcSSimon Schubert       pt = buf;
43305796c8dcSSimon Schubert     }
4331c50c785cSJohn Marino   fflush (stdout);
43325796c8dcSSimon Schubert   fprintf (stderr, "%s:", pt);
43335796c8dcSSimon Schubert   for (j = 0; j < m->count; j++)
43345796c8dcSSimon Schubert     fprintf (stderr, " %s", m->sections [j]->name);
43355796c8dcSSimon Schubert   putc ('\n',stderr);
4336c50c785cSJohn Marino   fflush (stderr);
43375796c8dcSSimon Schubert }
43385796c8dcSSimon Schubert 
4339cf7f2e2dSJohn Marino static bfd_boolean
write_zeros(bfd * abfd,file_ptr pos,bfd_size_type len)4340cf7f2e2dSJohn Marino write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len)
4341cf7f2e2dSJohn Marino {
4342cf7f2e2dSJohn Marino   void *buf;
4343cf7f2e2dSJohn Marino   bfd_boolean ret;
4344cf7f2e2dSJohn Marino 
4345cf7f2e2dSJohn Marino   if (bfd_seek (abfd, pos, SEEK_SET) != 0)
4346cf7f2e2dSJohn Marino     return FALSE;
4347cf7f2e2dSJohn Marino   buf = bfd_zmalloc (len);
4348cf7f2e2dSJohn Marino   if (buf == NULL)
4349cf7f2e2dSJohn Marino     return FALSE;
4350cf7f2e2dSJohn Marino   ret = bfd_bwrite (buf, len, abfd) == len;
4351cf7f2e2dSJohn Marino   free (buf);
4352cf7f2e2dSJohn Marino   return ret;
4353cf7f2e2dSJohn Marino }
4354cf7f2e2dSJohn Marino 
43555796c8dcSSimon Schubert /* Assign file positions to the sections based on the mapping from
43565796c8dcSSimon Schubert    sections to segments.  This function also sets up some fields in
43575796c8dcSSimon Schubert    the file header.  */
43585796c8dcSSimon Schubert 
43595796c8dcSSimon Schubert static bfd_boolean
assign_file_positions_for_load_sections(bfd * abfd,struct bfd_link_info * link_info)43605796c8dcSSimon Schubert assign_file_positions_for_load_sections (bfd *abfd,
43615796c8dcSSimon Schubert 					 struct bfd_link_info *link_info)
43625796c8dcSSimon Schubert {
43635796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
43645796c8dcSSimon Schubert   struct elf_segment_map *m;
43655796c8dcSSimon Schubert   Elf_Internal_Phdr *phdrs;
43665796c8dcSSimon Schubert   Elf_Internal_Phdr *p;
43675796c8dcSSimon Schubert   file_ptr off;
43685796c8dcSSimon Schubert   bfd_size_type maxpagesize;
43695796c8dcSSimon Schubert   unsigned int alloc;
43705796c8dcSSimon Schubert   unsigned int i, j;
43715796c8dcSSimon Schubert   bfd_vma header_pad = 0;
43725796c8dcSSimon Schubert 
43735796c8dcSSimon Schubert   if (link_info == NULL
43745796c8dcSSimon Schubert       && !_bfd_elf_map_sections_to_segments (abfd, link_info))
43755796c8dcSSimon Schubert     return FALSE;
43765796c8dcSSimon Schubert 
43775796c8dcSSimon Schubert   alloc = 0;
4378*ef5ccd6cSJohn Marino   for (m = elf_seg_map (abfd); m != NULL; m = m->next)
43795796c8dcSSimon Schubert     {
43805796c8dcSSimon Schubert       ++alloc;
43815796c8dcSSimon Schubert       if (m->header_size)
43825796c8dcSSimon Schubert 	header_pad = m->header_size;
43835796c8dcSSimon Schubert     }
43845796c8dcSSimon Schubert 
4385c50c785cSJohn Marino   if (alloc)
4386c50c785cSJohn Marino     {
43875796c8dcSSimon Schubert       elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
43885796c8dcSSimon Schubert       elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
4389c50c785cSJohn Marino     }
4390c50c785cSJohn Marino   else
4391c50c785cSJohn Marino     {
4392c50c785cSJohn Marino       /* PR binutils/12467.  */
4393c50c785cSJohn Marino       elf_elfheader (abfd)->e_phoff = 0;
4394c50c785cSJohn Marino       elf_elfheader (abfd)->e_phentsize = 0;
4395c50c785cSJohn Marino     }
4396c50c785cSJohn Marino 
43975796c8dcSSimon Schubert   elf_elfheader (abfd)->e_phnum = alloc;
43985796c8dcSSimon Schubert 
4399*ef5ccd6cSJohn Marino   if (elf_program_header_size (abfd) == (bfd_size_type) -1)
4400*ef5ccd6cSJohn Marino     elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr;
44015796c8dcSSimon Schubert   else
4402*ef5ccd6cSJohn Marino     BFD_ASSERT (elf_program_header_size (abfd)
44035796c8dcSSimon Schubert 		>= alloc * bed->s->sizeof_phdr);
44045796c8dcSSimon Schubert 
44055796c8dcSSimon Schubert   if (alloc == 0)
44065796c8dcSSimon Schubert     {
4407*ef5ccd6cSJohn Marino       elf_next_file_pos (abfd) = bed->s->sizeof_ehdr;
44085796c8dcSSimon Schubert       return TRUE;
44095796c8dcSSimon Schubert     }
44105796c8dcSSimon Schubert 
4411*ef5ccd6cSJohn Marino   /* We're writing the size in elf_program_header_size (abfd),
44125796c8dcSSimon Schubert      see assign_file_positions_except_relocs, so make sure we have
44135796c8dcSSimon Schubert      that amount allocated, with trailing space cleared.
4414*ef5ccd6cSJohn Marino      The variable alloc contains the computed need, while
4415*ef5ccd6cSJohn Marino      elf_program_header_size (abfd) contains the size used for the
44165796c8dcSSimon Schubert      layout.
44175796c8dcSSimon Schubert      See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
44185796c8dcSSimon Schubert      where the layout is forced to according to a larger size in the
44195796c8dcSSimon Schubert      last iterations for the testcase ld-elf/header.  */
4420*ef5ccd6cSJohn Marino   BFD_ASSERT (elf_program_header_size (abfd) % bed->s->sizeof_phdr
44215796c8dcSSimon Schubert 	      == 0);
44225796c8dcSSimon Schubert   phdrs = (Elf_Internal_Phdr *)
44235796c8dcSSimon Schubert      bfd_zalloc2 (abfd,
4424*ef5ccd6cSJohn Marino                   (elf_program_header_size (abfd) / bed->s->sizeof_phdr),
44255796c8dcSSimon Schubert                   sizeof (Elf_Internal_Phdr));
44265796c8dcSSimon Schubert   elf_tdata (abfd)->phdr = phdrs;
44275796c8dcSSimon Schubert   if (phdrs == NULL)
44285796c8dcSSimon Schubert     return FALSE;
44295796c8dcSSimon Schubert 
44305796c8dcSSimon Schubert   maxpagesize = 1;
44315796c8dcSSimon Schubert   if ((abfd->flags & D_PAGED) != 0)
44325796c8dcSSimon Schubert     maxpagesize = bed->maxpagesize;
44335796c8dcSSimon Schubert 
44345796c8dcSSimon Schubert   off = bed->s->sizeof_ehdr;
44355796c8dcSSimon Schubert   off += alloc * bed->s->sizeof_phdr;
44365796c8dcSSimon Schubert   if (header_pad < (bfd_vma) off)
44375796c8dcSSimon Schubert     header_pad = 0;
44385796c8dcSSimon Schubert   else
44395796c8dcSSimon Schubert     header_pad -= off;
44405796c8dcSSimon Schubert   off += header_pad;
44415796c8dcSSimon Schubert 
4442*ef5ccd6cSJohn Marino   for (m = elf_seg_map (abfd), p = phdrs, j = 0;
44435796c8dcSSimon Schubert        m != NULL;
44445796c8dcSSimon Schubert        m = m->next, p++, j++)
44455796c8dcSSimon Schubert     {
44465796c8dcSSimon Schubert       asection **secpp;
44475796c8dcSSimon Schubert       bfd_vma off_adjust;
44485796c8dcSSimon Schubert       bfd_boolean no_contents;
44495796c8dcSSimon Schubert 
44505796c8dcSSimon Schubert       /* If elf_segment_map is not from map_sections_to_segments, the
44515796c8dcSSimon Schubert 	 sections may not be correctly ordered.  NOTE: sorting should
44525796c8dcSSimon Schubert 	 not be done to the PT_NOTE section of a corefile, which may
44535796c8dcSSimon Schubert 	 contain several pseudo-sections artificially created by bfd.
44545796c8dcSSimon Schubert 	 Sorting these pseudo-sections breaks things badly.  */
44555796c8dcSSimon Schubert       if (m->count > 1
44565796c8dcSSimon Schubert 	  && !(elf_elfheader (abfd)->e_type == ET_CORE
44575796c8dcSSimon Schubert 	       && m->p_type == PT_NOTE))
44585796c8dcSSimon Schubert 	qsort (m->sections, (size_t) m->count, sizeof (asection *),
44595796c8dcSSimon Schubert 	       elf_sort_sections);
44605796c8dcSSimon Schubert 
44615796c8dcSSimon Schubert       /* An ELF segment (described by Elf_Internal_Phdr) may contain a
44625796c8dcSSimon Schubert 	 number of sections with contents contributing to both p_filesz
44635796c8dcSSimon Schubert 	 and p_memsz, followed by a number of sections with no contents
44645796c8dcSSimon Schubert 	 that just contribute to p_memsz.  In this loop, OFF tracks next
44655796c8dcSSimon Schubert 	 available file offset for PT_LOAD and PT_NOTE segments.  */
44665796c8dcSSimon Schubert       p->p_type = m->p_type;
44675796c8dcSSimon Schubert       p->p_flags = m->p_flags;
44685796c8dcSSimon Schubert 
44695796c8dcSSimon Schubert       if (m->count == 0)
44705796c8dcSSimon Schubert 	p->p_vaddr = 0;
44715796c8dcSSimon Schubert       else
44725796c8dcSSimon Schubert 	p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset;
44735796c8dcSSimon Schubert 
44745796c8dcSSimon Schubert       if (m->p_paddr_valid)
44755796c8dcSSimon Schubert 	p->p_paddr = m->p_paddr;
44765796c8dcSSimon Schubert       else if (m->count == 0)
44775796c8dcSSimon Schubert 	p->p_paddr = 0;
44785796c8dcSSimon Schubert       else
44795796c8dcSSimon Schubert 	p->p_paddr = m->sections[0]->lma - m->p_vaddr_offset;
44805796c8dcSSimon Schubert 
44815796c8dcSSimon Schubert       if (p->p_type == PT_LOAD
44825796c8dcSSimon Schubert 	  && (abfd->flags & D_PAGED) != 0)
44835796c8dcSSimon Schubert 	{
44845796c8dcSSimon Schubert 	  /* p_align in demand paged PT_LOAD segments effectively stores
44855796c8dcSSimon Schubert 	     the maximum page size.  When copying an executable with
44865796c8dcSSimon Schubert 	     objcopy, we set m->p_align from the input file.  Use this
44875796c8dcSSimon Schubert 	     value for maxpagesize rather than bed->maxpagesize, which
44885796c8dcSSimon Schubert 	     may be different.  Note that we use maxpagesize for PT_TLS
44895796c8dcSSimon Schubert 	     segment alignment later in this function, so we are relying
44905796c8dcSSimon Schubert 	     on at least one PT_LOAD segment appearing before a PT_TLS
44915796c8dcSSimon Schubert 	     segment.  */
44925796c8dcSSimon Schubert 	  if (m->p_align_valid)
44935796c8dcSSimon Schubert 	    maxpagesize = m->p_align;
44945796c8dcSSimon Schubert 
44955796c8dcSSimon Schubert 	  p->p_align = maxpagesize;
44965796c8dcSSimon Schubert 	}
44975796c8dcSSimon Schubert       else if (m->p_align_valid)
44985796c8dcSSimon Schubert 	p->p_align = m->p_align;
44995796c8dcSSimon Schubert       else if (m->count == 0)
45005796c8dcSSimon Schubert 	p->p_align = 1 << bed->s->log_file_align;
45015796c8dcSSimon Schubert       else
45025796c8dcSSimon Schubert 	p->p_align = 0;
45035796c8dcSSimon Schubert 
45045796c8dcSSimon Schubert       no_contents = FALSE;
45055796c8dcSSimon Schubert       off_adjust = 0;
45065796c8dcSSimon Schubert       if (p->p_type == PT_LOAD
45075796c8dcSSimon Schubert 	  && m->count > 0)
45085796c8dcSSimon Schubert 	{
45095796c8dcSSimon Schubert 	  bfd_size_type align;
45105796c8dcSSimon Schubert 	  unsigned int align_power = 0;
45115796c8dcSSimon Schubert 
45125796c8dcSSimon Schubert 	  if (m->p_align_valid)
45135796c8dcSSimon Schubert 	    align = p->p_align;
45145796c8dcSSimon Schubert 	  else
45155796c8dcSSimon Schubert 	    {
45165796c8dcSSimon Schubert 	      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
45175796c8dcSSimon Schubert 		{
45185796c8dcSSimon Schubert 		  unsigned int secalign;
45195796c8dcSSimon Schubert 
45205796c8dcSSimon Schubert 		  secalign = bfd_get_section_alignment (abfd, *secpp);
45215796c8dcSSimon Schubert 		  if (secalign > align_power)
45225796c8dcSSimon Schubert 		    align_power = secalign;
45235796c8dcSSimon Schubert 		}
45245796c8dcSSimon Schubert 	      align = (bfd_size_type) 1 << align_power;
45255796c8dcSSimon Schubert 	      if (align < maxpagesize)
45265796c8dcSSimon Schubert 		align = maxpagesize;
45275796c8dcSSimon Schubert 	    }
45285796c8dcSSimon Schubert 
45295796c8dcSSimon Schubert 	  for (i = 0; i < m->count; i++)
45305796c8dcSSimon Schubert 	    if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
45315796c8dcSSimon Schubert 	      /* If we aren't making room for this section, then
45325796c8dcSSimon Schubert 		 it must be SHT_NOBITS regardless of what we've
45335796c8dcSSimon Schubert 		 set via struct bfd_elf_special_section.  */
45345796c8dcSSimon Schubert 	      elf_section_type (m->sections[i]) = SHT_NOBITS;
45355796c8dcSSimon Schubert 
45365796c8dcSSimon Schubert 	  /* Find out whether this segment contains any loadable
45375796c8dcSSimon Schubert 	     sections.  */
45385796c8dcSSimon Schubert 	  no_contents = TRUE;
45395796c8dcSSimon Schubert 	  for (i = 0; i < m->count; i++)
45405796c8dcSSimon Schubert 	    if (elf_section_type (m->sections[i]) != SHT_NOBITS)
45415796c8dcSSimon Schubert 	      {
45425796c8dcSSimon Schubert 		no_contents = FALSE;
45435796c8dcSSimon Schubert 		break;
45445796c8dcSSimon Schubert 	      }
45455796c8dcSSimon Schubert 
4546c50c785cSJohn Marino 	  off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align);
45475796c8dcSSimon Schubert 	  off += off_adjust;
45485796c8dcSSimon Schubert 	  if (no_contents)
45495796c8dcSSimon Schubert 	    {
45505796c8dcSSimon Schubert 	      /* We shouldn't need to align the segment on disk since
45515796c8dcSSimon Schubert 		 the segment doesn't need file space, but the gABI
45525796c8dcSSimon Schubert 		 arguably requires the alignment and glibc ld.so
45535796c8dcSSimon Schubert 		 checks it.  So to comply with the alignment
45545796c8dcSSimon Schubert 		 requirement but not waste file space, we adjust
45555796c8dcSSimon Schubert 		 p_offset for just this segment.  (OFF_ADJUST is
45565796c8dcSSimon Schubert 		 subtracted from OFF later.)  This may put p_offset
45575796c8dcSSimon Schubert 		 past the end of file, but that shouldn't matter.  */
45585796c8dcSSimon Schubert 	    }
45595796c8dcSSimon Schubert 	  else
45605796c8dcSSimon Schubert 	    off_adjust = 0;
45615796c8dcSSimon Schubert 	}
45625796c8dcSSimon Schubert       /* Make sure the .dynamic section is the first section in the
45635796c8dcSSimon Schubert 	 PT_DYNAMIC segment.  */
45645796c8dcSSimon Schubert       else if (p->p_type == PT_DYNAMIC
45655796c8dcSSimon Schubert 	       && m->count > 1
45665796c8dcSSimon Schubert 	       && strcmp (m->sections[0]->name, ".dynamic") != 0)
45675796c8dcSSimon Schubert 	{
45685796c8dcSSimon Schubert 	  _bfd_error_handler
45695796c8dcSSimon Schubert 	    (_("%B: The first section in the PT_DYNAMIC segment is not the .dynamic section"),
45705796c8dcSSimon Schubert 	     abfd);
45715796c8dcSSimon Schubert 	  bfd_set_error (bfd_error_bad_value);
45725796c8dcSSimon Schubert 	  return FALSE;
45735796c8dcSSimon Schubert 	}
45745796c8dcSSimon Schubert       /* Set the note section type to SHT_NOTE.  */
45755796c8dcSSimon Schubert       else if (p->p_type == PT_NOTE)
45765796c8dcSSimon Schubert 	for (i = 0; i < m->count; i++)
45775796c8dcSSimon Schubert 	  elf_section_type (m->sections[i]) = SHT_NOTE;
45785796c8dcSSimon Schubert 
45795796c8dcSSimon Schubert       p->p_offset = 0;
45805796c8dcSSimon Schubert       p->p_filesz = 0;
45815796c8dcSSimon Schubert       p->p_memsz = 0;
45825796c8dcSSimon Schubert 
45835796c8dcSSimon Schubert       if (m->includes_filehdr)
45845796c8dcSSimon Schubert 	{
45855796c8dcSSimon Schubert 	  if (!m->p_flags_valid)
45865796c8dcSSimon Schubert 	    p->p_flags |= PF_R;
45875796c8dcSSimon Schubert 	  p->p_filesz = bed->s->sizeof_ehdr;
45885796c8dcSSimon Schubert 	  p->p_memsz = bed->s->sizeof_ehdr;
45895796c8dcSSimon Schubert 	  if (m->count > 0)
45905796c8dcSSimon Schubert 	    {
45915796c8dcSSimon Schubert 	      if (p->p_vaddr < (bfd_vma) off)
45925796c8dcSSimon Schubert 		{
45935796c8dcSSimon Schubert 		  (*_bfd_error_handler)
45945796c8dcSSimon Schubert 		    (_("%B: Not enough room for program headers, try linking with -N"),
45955796c8dcSSimon Schubert 		     abfd);
45965796c8dcSSimon Schubert 		  bfd_set_error (bfd_error_bad_value);
45975796c8dcSSimon Schubert 		  return FALSE;
45985796c8dcSSimon Schubert 		}
45995796c8dcSSimon Schubert 
46005796c8dcSSimon Schubert 	      p->p_vaddr -= off;
46015796c8dcSSimon Schubert 	      if (!m->p_paddr_valid)
46025796c8dcSSimon Schubert 		p->p_paddr -= off;
46035796c8dcSSimon Schubert 	    }
46045796c8dcSSimon Schubert 	}
46055796c8dcSSimon Schubert 
46065796c8dcSSimon Schubert       if (m->includes_phdrs)
46075796c8dcSSimon Schubert 	{
46085796c8dcSSimon Schubert 	  if (!m->p_flags_valid)
46095796c8dcSSimon Schubert 	    p->p_flags |= PF_R;
46105796c8dcSSimon Schubert 
46115796c8dcSSimon Schubert 	  if (!m->includes_filehdr)
46125796c8dcSSimon Schubert 	    {
46135796c8dcSSimon Schubert 	      p->p_offset = bed->s->sizeof_ehdr;
46145796c8dcSSimon Schubert 
46155796c8dcSSimon Schubert 	      if (m->count > 0)
46165796c8dcSSimon Schubert 		{
46175796c8dcSSimon Schubert 		  p->p_vaddr -= off - p->p_offset;
46185796c8dcSSimon Schubert 		  if (!m->p_paddr_valid)
46195796c8dcSSimon Schubert 		    p->p_paddr -= off - p->p_offset;
46205796c8dcSSimon Schubert 		}
46215796c8dcSSimon Schubert 	    }
46225796c8dcSSimon Schubert 
46235796c8dcSSimon Schubert 	  p->p_filesz += alloc * bed->s->sizeof_phdr;
46245796c8dcSSimon Schubert 	  p->p_memsz += alloc * bed->s->sizeof_phdr;
46255796c8dcSSimon Schubert 	  if (m->count)
46265796c8dcSSimon Schubert 	    {
46275796c8dcSSimon Schubert 	      p->p_filesz += header_pad;
46285796c8dcSSimon Schubert 	      p->p_memsz += header_pad;
46295796c8dcSSimon Schubert 	    }
46305796c8dcSSimon Schubert 	}
46315796c8dcSSimon Schubert 
46325796c8dcSSimon Schubert       if (p->p_type == PT_LOAD
46335796c8dcSSimon Schubert 	  || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
46345796c8dcSSimon Schubert 	{
46355796c8dcSSimon Schubert 	  if (!m->includes_filehdr && !m->includes_phdrs)
46365796c8dcSSimon Schubert 	    p->p_offset = off;
46375796c8dcSSimon Schubert 	  else
46385796c8dcSSimon Schubert 	    {
46395796c8dcSSimon Schubert 	      file_ptr adjust;
46405796c8dcSSimon Schubert 
46415796c8dcSSimon Schubert 	      adjust = off - (p->p_offset + p->p_filesz);
46425796c8dcSSimon Schubert 	      if (!no_contents)
46435796c8dcSSimon Schubert 		p->p_filesz += adjust;
46445796c8dcSSimon Schubert 	      p->p_memsz += adjust;
46455796c8dcSSimon Schubert 	    }
46465796c8dcSSimon Schubert 	}
46475796c8dcSSimon Schubert 
46485796c8dcSSimon Schubert       /* Set up p_filesz, p_memsz, p_align and p_flags from the section
46495796c8dcSSimon Schubert 	 maps.  Set filepos for sections in PT_LOAD segments, and in
46505796c8dcSSimon Schubert 	 core files, for sections in PT_NOTE segments.
46515796c8dcSSimon Schubert 	 assign_file_positions_for_non_load_sections will set filepos
46525796c8dcSSimon Schubert 	 for other sections and update p_filesz for other segments.  */
46535796c8dcSSimon Schubert       for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
46545796c8dcSSimon Schubert 	{
46555796c8dcSSimon Schubert 	  asection *sec;
46565796c8dcSSimon Schubert 	  bfd_size_type align;
46575796c8dcSSimon Schubert 	  Elf_Internal_Shdr *this_hdr;
46585796c8dcSSimon Schubert 
46595796c8dcSSimon Schubert 	  sec = *secpp;
46605796c8dcSSimon Schubert 	  this_hdr = &elf_section_data (sec)->this_hdr;
46615796c8dcSSimon Schubert 	  align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
46625796c8dcSSimon Schubert 
46635796c8dcSSimon Schubert 	  if ((p->p_type == PT_LOAD
46645796c8dcSSimon Schubert 	       || p->p_type == PT_TLS)
46655796c8dcSSimon Schubert 	      && (this_hdr->sh_type != SHT_NOBITS
46665796c8dcSSimon Schubert 		  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
46675796c8dcSSimon Schubert 		      && ((this_hdr->sh_flags & SHF_TLS) == 0
46685796c8dcSSimon Schubert 			  || p->p_type == PT_TLS))))
46695796c8dcSSimon Schubert 	    {
4670c50c785cSJohn Marino 	      bfd_vma p_start = p->p_paddr;
4671c50c785cSJohn Marino 	      bfd_vma p_end = p_start + p->p_memsz;
4672c50c785cSJohn Marino 	      bfd_vma s_start = sec->lma;
4673c50c785cSJohn Marino 	      bfd_vma adjust = s_start - p_end;
46745796c8dcSSimon Schubert 
4675c50c785cSJohn Marino 	      if (adjust != 0
4676c50c785cSJohn Marino 		  && (s_start < p_end
4677c50c785cSJohn Marino 		      || p_end < p_start))
46785796c8dcSSimon Schubert 		{
46795796c8dcSSimon Schubert 		  (*_bfd_error_handler)
4680c50c785cSJohn Marino 		    (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
4681c50c785cSJohn Marino 		     (unsigned long) s_start, (unsigned long) p_end);
46825796c8dcSSimon Schubert 		  adjust = 0;
4683c50c785cSJohn Marino 		  sec->lma = p_end;
46845796c8dcSSimon Schubert 		}
46855796c8dcSSimon Schubert 	      p->p_memsz += adjust;
46865796c8dcSSimon Schubert 
46875796c8dcSSimon Schubert 	      if (this_hdr->sh_type != SHT_NOBITS)
46885796c8dcSSimon Schubert 		{
4689cf7f2e2dSJohn Marino 		  if (p->p_filesz + adjust < p->p_memsz)
4690cf7f2e2dSJohn Marino 		    {
4691cf7f2e2dSJohn Marino 		      /* We have a PROGBITS section following NOBITS ones.
4692cf7f2e2dSJohn Marino 		         Allocate file space for the NOBITS section(s) and
4693cf7f2e2dSJohn Marino 			 zero it.  */
4694cf7f2e2dSJohn Marino 		      adjust = p->p_memsz - p->p_filesz;
4695cf7f2e2dSJohn Marino 		      if (!write_zeros (abfd, off, adjust))
4696cf7f2e2dSJohn Marino 			return FALSE;
4697cf7f2e2dSJohn Marino 		    }
46985796c8dcSSimon Schubert 		  off += adjust;
46995796c8dcSSimon Schubert 		  p->p_filesz += adjust;
47005796c8dcSSimon Schubert 		}
47015796c8dcSSimon Schubert 	    }
47025796c8dcSSimon Schubert 
47035796c8dcSSimon Schubert 	  if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
47045796c8dcSSimon Schubert 	    {
47055796c8dcSSimon Schubert 	      /* The section at i == 0 is the one that actually contains
47065796c8dcSSimon Schubert 		 everything.  */
47075796c8dcSSimon Schubert 	      if (i == 0)
47085796c8dcSSimon Schubert 		{
47095796c8dcSSimon Schubert 		  this_hdr->sh_offset = sec->filepos = off;
47105796c8dcSSimon Schubert 		  off += this_hdr->sh_size;
47115796c8dcSSimon Schubert 		  p->p_filesz = this_hdr->sh_size;
47125796c8dcSSimon Schubert 		  p->p_memsz = 0;
47135796c8dcSSimon Schubert 		  p->p_align = 1;
47145796c8dcSSimon Schubert 		}
47155796c8dcSSimon Schubert 	      else
47165796c8dcSSimon Schubert 		{
47175796c8dcSSimon Schubert 		  /* The rest are fake sections that shouldn't be written.  */
47185796c8dcSSimon Schubert 		  sec->filepos = 0;
47195796c8dcSSimon Schubert 		  sec->size = 0;
47205796c8dcSSimon Schubert 		  sec->flags = 0;
47215796c8dcSSimon Schubert 		  continue;
47225796c8dcSSimon Schubert 		}
47235796c8dcSSimon Schubert 	    }
47245796c8dcSSimon Schubert 	  else
47255796c8dcSSimon Schubert 	    {
47265796c8dcSSimon Schubert 	      if (p->p_type == PT_LOAD)
47275796c8dcSSimon Schubert 		{
47285796c8dcSSimon Schubert 		  this_hdr->sh_offset = sec->filepos = off;
47295796c8dcSSimon Schubert 		  if (this_hdr->sh_type != SHT_NOBITS)
47305796c8dcSSimon Schubert 		    off += this_hdr->sh_size;
47315796c8dcSSimon Schubert 		}
4732a45ae5f8SJohn Marino 	      else if (this_hdr->sh_type == SHT_NOBITS
4733a45ae5f8SJohn Marino 		       && (this_hdr->sh_flags & SHF_TLS) != 0
4734a45ae5f8SJohn Marino 		       && this_hdr->sh_offset == 0)
4735a45ae5f8SJohn Marino 		{
4736a45ae5f8SJohn Marino 		  /* This is a .tbss section that didn't get a PT_LOAD.
4737a45ae5f8SJohn Marino 		     (See _bfd_elf_map_sections_to_segments "Create a
4738a45ae5f8SJohn Marino 		     final PT_LOAD".)  Set sh_offset to the value it
4739a45ae5f8SJohn Marino 		     would have if we had created a zero p_filesz and
4740a45ae5f8SJohn Marino 		     p_memsz PT_LOAD header for the section.  This
4741a45ae5f8SJohn Marino 		     also makes the PT_TLS header have the same
4742a45ae5f8SJohn Marino 		     p_offset value.  */
4743a45ae5f8SJohn Marino 		  bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
4744a45ae5f8SJohn Marino 							  off, align);
4745a45ae5f8SJohn Marino 		  this_hdr->sh_offset = sec->filepos = off + adjust;
4746a45ae5f8SJohn Marino 		}
47475796c8dcSSimon Schubert 
47485796c8dcSSimon Schubert 	      if (this_hdr->sh_type != SHT_NOBITS)
47495796c8dcSSimon Schubert 		{
47505796c8dcSSimon Schubert 		  p->p_filesz += this_hdr->sh_size;
47515796c8dcSSimon Schubert 		  /* A load section without SHF_ALLOC is something like
47525796c8dcSSimon Schubert 		     a note section in a PT_NOTE segment.  These take
47535796c8dcSSimon Schubert 		     file space but are not loaded into memory.  */
47545796c8dcSSimon Schubert 		  if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
47555796c8dcSSimon Schubert 		    p->p_memsz += this_hdr->sh_size;
47565796c8dcSSimon Schubert 		}
47575796c8dcSSimon Schubert 	      else if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
47585796c8dcSSimon Schubert 		{
47595796c8dcSSimon Schubert 		  if (p->p_type == PT_TLS)
47605796c8dcSSimon Schubert 		    p->p_memsz += this_hdr->sh_size;
47615796c8dcSSimon Schubert 
47625796c8dcSSimon Schubert 		  /* .tbss is special.  It doesn't contribute to p_memsz of
47635796c8dcSSimon Schubert 		     normal segments.  */
47645796c8dcSSimon Schubert 		  else if ((this_hdr->sh_flags & SHF_TLS) == 0)
47655796c8dcSSimon Schubert 		    p->p_memsz += this_hdr->sh_size;
47665796c8dcSSimon Schubert 		}
47675796c8dcSSimon Schubert 
47685796c8dcSSimon Schubert 	      if (align > p->p_align
47695796c8dcSSimon Schubert 		  && !m->p_align_valid
47705796c8dcSSimon Schubert 		  && (p->p_type != PT_LOAD
47715796c8dcSSimon Schubert 		      || (abfd->flags & D_PAGED) == 0))
47725796c8dcSSimon Schubert 		p->p_align = align;
47735796c8dcSSimon Schubert 	    }
47745796c8dcSSimon Schubert 
47755796c8dcSSimon Schubert 	  if (!m->p_flags_valid)
47765796c8dcSSimon Schubert 	    {
47775796c8dcSSimon Schubert 	      p->p_flags |= PF_R;
47785796c8dcSSimon Schubert 	      if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
47795796c8dcSSimon Schubert 		p->p_flags |= PF_X;
47805796c8dcSSimon Schubert 	      if ((this_hdr->sh_flags & SHF_WRITE) != 0)
47815796c8dcSSimon Schubert 		p->p_flags |= PF_W;
47825796c8dcSSimon Schubert 	    }
47835796c8dcSSimon Schubert 	}
47845796c8dcSSimon Schubert       off -= off_adjust;
47855796c8dcSSimon Schubert 
47865796c8dcSSimon Schubert       /* Check that all sections are in a PT_LOAD segment.
47875796c8dcSSimon Schubert 	 Don't check funky gdb generated core files.  */
47885796c8dcSSimon Schubert       if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core)
4789cf7f2e2dSJohn Marino 	{
4790cf7f2e2dSJohn Marino 	  bfd_boolean check_vma = TRUE;
4791cf7f2e2dSJohn Marino 
4792cf7f2e2dSJohn Marino 	  for (i = 1; i < m->count; i++)
4793cf7f2e2dSJohn Marino 	    if (m->sections[i]->vma == m->sections[i - 1]->vma
4794cf7f2e2dSJohn Marino 		&& ELF_SECTION_SIZE (&(elf_section_data (m->sections[i])
4795cf7f2e2dSJohn Marino 				       ->this_hdr), p) != 0
4796cf7f2e2dSJohn Marino 		&& ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1])
4797cf7f2e2dSJohn Marino 				       ->this_hdr), p) != 0)
4798cf7f2e2dSJohn Marino 	      {
4799cf7f2e2dSJohn Marino 		/* Looks like we have overlays packed into the segment.  */
4800cf7f2e2dSJohn Marino 		check_vma = FALSE;
4801cf7f2e2dSJohn Marino 		break;
4802cf7f2e2dSJohn Marino 	      }
4803cf7f2e2dSJohn Marino 
4804cf7f2e2dSJohn Marino 	  for (i = 0; i < m->count; i++)
48055796c8dcSSimon Schubert 	    {
48065796c8dcSSimon Schubert 	      Elf_Internal_Shdr *this_hdr;
48075796c8dcSSimon Schubert 	      asection *sec;
48085796c8dcSSimon Schubert 
4809cf7f2e2dSJohn Marino 	      sec = m->sections[i];
48105796c8dcSSimon Schubert 	      this_hdr = &(elf_section_data(sec)->this_hdr);
4811a45ae5f8SJohn Marino 	      if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
4812a45ae5f8SJohn Marino 		  && !ELF_TBSS_SPECIAL (this_hdr, p))
48135796c8dcSSimon Schubert 		{
48145796c8dcSSimon Schubert 		  (*_bfd_error_handler)
48155796c8dcSSimon Schubert 		    (_("%B: section `%A' can't be allocated in segment %d"),
48165796c8dcSSimon Schubert 		     abfd, sec, j);
48175796c8dcSSimon Schubert 		  print_segment_map (m);
4818cf7f2e2dSJohn Marino 		}
48195796c8dcSSimon Schubert 	    }
48205796c8dcSSimon Schubert 	}
48215796c8dcSSimon Schubert     }
48225796c8dcSSimon Schubert 
4823*ef5ccd6cSJohn Marino   elf_next_file_pos (abfd) = off;
48245796c8dcSSimon Schubert   return TRUE;
48255796c8dcSSimon Schubert }
48265796c8dcSSimon Schubert 
48275796c8dcSSimon Schubert /* Assign file positions for the other sections.  */
48285796c8dcSSimon Schubert 
48295796c8dcSSimon Schubert static bfd_boolean
assign_file_positions_for_non_load_sections(bfd * abfd,struct bfd_link_info * link_info)48305796c8dcSSimon Schubert assign_file_positions_for_non_load_sections (bfd *abfd,
48315796c8dcSSimon Schubert 					     struct bfd_link_info *link_info)
48325796c8dcSSimon Schubert {
48335796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
48345796c8dcSSimon Schubert   Elf_Internal_Shdr **i_shdrpp;
48355796c8dcSSimon Schubert   Elf_Internal_Shdr **hdrpp;
48365796c8dcSSimon Schubert   Elf_Internal_Phdr *phdrs;
48375796c8dcSSimon Schubert   Elf_Internal_Phdr *p;
48385796c8dcSSimon Schubert   struct elf_segment_map *m;
4839*ef5ccd6cSJohn Marino   struct elf_segment_map *hdrs_segment;
48405796c8dcSSimon Schubert   bfd_vma filehdr_vaddr, filehdr_paddr;
48415796c8dcSSimon Schubert   bfd_vma phdrs_vaddr, phdrs_paddr;
48425796c8dcSSimon Schubert   file_ptr off;
48435796c8dcSSimon Schubert   unsigned int num_sec;
48445796c8dcSSimon Schubert   unsigned int i;
48455796c8dcSSimon Schubert   unsigned int count;
48465796c8dcSSimon Schubert 
48475796c8dcSSimon Schubert   i_shdrpp = elf_elfsections (abfd);
48485796c8dcSSimon Schubert   num_sec = elf_numsections (abfd);
4849*ef5ccd6cSJohn Marino   off = elf_next_file_pos (abfd);
48505796c8dcSSimon Schubert   for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
48515796c8dcSSimon Schubert     {
48525796c8dcSSimon Schubert       Elf_Internal_Shdr *hdr;
48535796c8dcSSimon Schubert 
48545796c8dcSSimon Schubert       hdr = *hdrpp;
48555796c8dcSSimon Schubert       if (hdr->bfd_section != NULL
48565796c8dcSSimon Schubert 	  && (hdr->bfd_section->filepos != 0
48575796c8dcSSimon Schubert 	      || (hdr->sh_type == SHT_NOBITS
48585796c8dcSSimon Schubert 		  && hdr->contents == NULL)))
48595796c8dcSSimon Schubert 	BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
48605796c8dcSSimon Schubert       else if ((hdr->sh_flags & SHF_ALLOC) != 0)
48615796c8dcSSimon Schubert 	{
4862*ef5ccd6cSJohn Marino 	  if (hdr->sh_size != 0)
4863c50c785cSJohn Marino 	    (*_bfd_error_handler)
48645796c8dcSSimon Schubert 	      (_("%B: warning: allocated section `%s' not in segment"),
48655796c8dcSSimon Schubert 	       abfd,
48665796c8dcSSimon Schubert 	       (hdr->bfd_section == NULL
48675796c8dcSSimon Schubert 		? "*unknown*"
4868c50c785cSJohn Marino 		: hdr->bfd_section->name));
48695796c8dcSSimon Schubert 	  /* We don't need to page align empty sections.  */
48705796c8dcSSimon Schubert 	  if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
48715796c8dcSSimon Schubert 	    off += vma_page_aligned_bias (hdr->sh_addr, off,
48725796c8dcSSimon Schubert 					  bed->maxpagesize);
48735796c8dcSSimon Schubert 	  else
48745796c8dcSSimon Schubert 	    off += vma_page_aligned_bias (hdr->sh_addr, off,
48755796c8dcSSimon Schubert 					  hdr->sh_addralign);
48765796c8dcSSimon Schubert 	  off = _bfd_elf_assign_file_position_for_section (hdr, off,
48775796c8dcSSimon Schubert 							   FALSE);
48785796c8dcSSimon Schubert 	}
48795796c8dcSSimon Schubert       else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
48805796c8dcSSimon Schubert 		&& hdr->bfd_section == NULL)
4881*ef5ccd6cSJohn Marino 	       || hdr == i_shdrpp[elf_onesymtab (abfd)]
4882*ef5ccd6cSJohn Marino 	       || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
4883*ef5ccd6cSJohn Marino 	       || hdr == i_shdrpp[elf_strtab_sec (abfd)])
48845796c8dcSSimon Schubert 	hdr->sh_offset = -1;
48855796c8dcSSimon Schubert       else
48865796c8dcSSimon Schubert 	off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
48875796c8dcSSimon Schubert     }
48885796c8dcSSimon Schubert 
48895796c8dcSSimon Schubert   /* Now that we have set the section file positions, we can set up
48905796c8dcSSimon Schubert      the file positions for the non PT_LOAD segments.  */
48915796c8dcSSimon Schubert   count = 0;
48925796c8dcSSimon Schubert   filehdr_vaddr = 0;
48935796c8dcSSimon Schubert   filehdr_paddr = 0;
48945796c8dcSSimon Schubert   phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
48955796c8dcSSimon Schubert   phdrs_paddr = 0;
4896*ef5ccd6cSJohn Marino   hdrs_segment = NULL;
48975796c8dcSSimon Schubert   phdrs = elf_tdata (abfd)->phdr;
4898*ef5ccd6cSJohn Marino   for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
48995796c8dcSSimon Schubert     {
49005796c8dcSSimon Schubert       ++count;
49015796c8dcSSimon Schubert       if (p->p_type != PT_LOAD)
49025796c8dcSSimon Schubert 	continue;
49035796c8dcSSimon Schubert 
49045796c8dcSSimon Schubert       if (m->includes_filehdr)
49055796c8dcSSimon Schubert 	{
49065796c8dcSSimon Schubert 	  filehdr_vaddr = p->p_vaddr;
49075796c8dcSSimon Schubert 	  filehdr_paddr = p->p_paddr;
49085796c8dcSSimon Schubert 	}
49095796c8dcSSimon Schubert       if (m->includes_phdrs)
49105796c8dcSSimon Schubert 	{
49115796c8dcSSimon Schubert 	  phdrs_vaddr = p->p_vaddr;
49125796c8dcSSimon Schubert 	  phdrs_paddr = p->p_paddr;
49135796c8dcSSimon Schubert 	  if (m->includes_filehdr)
49145796c8dcSSimon Schubert 	    {
4915*ef5ccd6cSJohn Marino 	      hdrs_segment = m;
49165796c8dcSSimon Schubert 	      phdrs_vaddr += bed->s->sizeof_ehdr;
49175796c8dcSSimon Schubert 	      phdrs_paddr += bed->s->sizeof_ehdr;
49185796c8dcSSimon Schubert 	    }
49195796c8dcSSimon Schubert 	}
49205796c8dcSSimon Schubert     }
49215796c8dcSSimon Schubert 
4922*ef5ccd6cSJohn Marino   if (hdrs_segment != NULL && link_info != NULL)
4923*ef5ccd6cSJohn Marino     {
4924*ef5ccd6cSJohn Marino       /* There is a segment that contains both the file headers and the
4925*ef5ccd6cSJohn Marino 	 program headers, so provide a symbol __ehdr_start pointing there.
4926*ef5ccd6cSJohn Marino 	 A program can use this to examine itself robustly.  */
4927*ef5ccd6cSJohn Marino 
4928*ef5ccd6cSJohn Marino       struct elf_link_hash_entry *hash
4929*ef5ccd6cSJohn Marino 	= elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
4930*ef5ccd6cSJohn Marino 				FALSE, FALSE, TRUE);
4931*ef5ccd6cSJohn Marino       /* If the symbol was referenced and not defined, define it.  */
4932*ef5ccd6cSJohn Marino       if (hash != NULL
4933*ef5ccd6cSJohn Marino 	  && (hash->root.type == bfd_link_hash_new
4934*ef5ccd6cSJohn Marino 	      || hash->root.type == bfd_link_hash_undefined
4935*ef5ccd6cSJohn Marino 	      || hash->root.type == bfd_link_hash_undefweak
4936*ef5ccd6cSJohn Marino 	      || hash->root.type == bfd_link_hash_common))
4937*ef5ccd6cSJohn Marino 	{
4938*ef5ccd6cSJohn Marino 	  asection *s = NULL;
4939*ef5ccd6cSJohn Marino 	  if (hdrs_segment->count != 0)
4940*ef5ccd6cSJohn Marino 	    /* The segment contains sections, so use the first one.  */
4941*ef5ccd6cSJohn Marino 	    s = hdrs_segment->sections[0];
4942*ef5ccd6cSJohn Marino 	  else
4943*ef5ccd6cSJohn Marino 	    /* Use the first (i.e. lowest-addressed) section in any segment.  */
4944*ef5ccd6cSJohn Marino 	    for (m = elf_seg_map (abfd); m != NULL; m = m->next)
4945*ef5ccd6cSJohn Marino 	      if (m->count != 0)
4946*ef5ccd6cSJohn Marino 		{
4947*ef5ccd6cSJohn Marino 		  s = m->sections[0];
4948*ef5ccd6cSJohn Marino 		  break;
4949*ef5ccd6cSJohn Marino 		}
4950*ef5ccd6cSJohn Marino 
4951*ef5ccd6cSJohn Marino 	  if (s != NULL)
4952*ef5ccd6cSJohn Marino 	    {
4953*ef5ccd6cSJohn Marino 	      hash->root.u.def.value = filehdr_vaddr - s->vma;
4954*ef5ccd6cSJohn Marino 	      hash->root.u.def.section = s;
4955*ef5ccd6cSJohn Marino 	    }
4956*ef5ccd6cSJohn Marino 	  else
4957*ef5ccd6cSJohn Marino 	    {
4958*ef5ccd6cSJohn Marino 	      hash->root.u.def.value = filehdr_vaddr;
4959*ef5ccd6cSJohn Marino 	      hash->root.u.def.section = bfd_abs_section_ptr;
4960*ef5ccd6cSJohn Marino 	    }
4961*ef5ccd6cSJohn Marino 
4962*ef5ccd6cSJohn Marino 	  hash->root.type = bfd_link_hash_defined;
4963*ef5ccd6cSJohn Marino 	  hash->def_regular = 1;
4964*ef5ccd6cSJohn Marino 	  hash->non_elf = 0;
4965*ef5ccd6cSJohn Marino 	}
4966*ef5ccd6cSJohn Marino     }
4967*ef5ccd6cSJohn Marino 
4968*ef5ccd6cSJohn Marino   for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
49695796c8dcSSimon Schubert     {
49705796c8dcSSimon Schubert       if (p->p_type == PT_GNU_RELRO)
49715796c8dcSSimon Schubert 	{
49725796c8dcSSimon Schubert 	  const Elf_Internal_Phdr *lp;
4973*ef5ccd6cSJohn Marino 	  struct elf_segment_map *lm;
49745796c8dcSSimon Schubert 
49755796c8dcSSimon Schubert 	  if (link_info != NULL)
49765796c8dcSSimon Schubert 	    {
49775796c8dcSSimon Schubert 	      /* During linking the range of the RELRO segment is passed
49785796c8dcSSimon Schubert 		 in link_info.  */
4979*ef5ccd6cSJohn Marino 	      for (lm = elf_seg_map (abfd), lp = phdrs;
4980*ef5ccd6cSJohn Marino 		   lm != NULL;
4981*ef5ccd6cSJohn Marino 		   lm = lm->next, lp++)
49825796c8dcSSimon Schubert 		{
49835796c8dcSSimon Schubert 		  if (lp->p_type == PT_LOAD
49845796c8dcSSimon Schubert 		      && lp->p_vaddr < link_info->relro_end
4985*ef5ccd6cSJohn Marino 		      && lp->p_vaddr + lp->p_filesz >= link_info->relro_end
4986*ef5ccd6cSJohn Marino 		      && lm->count != 0
4987*ef5ccd6cSJohn Marino 		      && lm->sections[0]->vma >= link_info->relro_start)
49885796c8dcSSimon Schubert 		    break;
49895796c8dcSSimon Schubert 		}
4990*ef5ccd6cSJohn Marino 
4991*ef5ccd6cSJohn Marino 	      /* PR ld/14207.  If the RELRO segment doesn't fit in the
4992*ef5ccd6cSJohn Marino 		 LOAD segment, it should be removed.  */
4993*ef5ccd6cSJohn Marino 	      BFD_ASSERT (lm != NULL);
49945796c8dcSSimon Schubert 	    }
49955796c8dcSSimon Schubert 	  else
49965796c8dcSSimon Schubert 	    {
49975796c8dcSSimon Schubert 	      /* Otherwise we are copying an executable or shared
49985796c8dcSSimon Schubert 		 library, but we need to use the same linker logic.  */
49995796c8dcSSimon Schubert 	      for (lp = phdrs; lp < phdrs + count; ++lp)
50005796c8dcSSimon Schubert 		{
50015796c8dcSSimon Schubert 		  if (lp->p_type == PT_LOAD
50025796c8dcSSimon Schubert 		      && lp->p_paddr == p->p_paddr)
50035796c8dcSSimon Schubert 		    break;
50045796c8dcSSimon Schubert 		}
50055796c8dcSSimon Schubert 	    }
50065796c8dcSSimon Schubert 
50075796c8dcSSimon Schubert 	  if (lp < phdrs + count)
50085796c8dcSSimon Schubert 	    {
50095796c8dcSSimon Schubert 	      p->p_vaddr = lp->p_vaddr;
50105796c8dcSSimon Schubert 	      p->p_paddr = lp->p_paddr;
50115796c8dcSSimon Schubert 	      p->p_offset = lp->p_offset;
50125796c8dcSSimon Schubert 	      if (link_info != NULL)
50135796c8dcSSimon Schubert 		p->p_filesz = link_info->relro_end - lp->p_vaddr;
50145796c8dcSSimon Schubert 	      else if (m->p_size_valid)
50155796c8dcSSimon Schubert 		p->p_filesz = m->p_size;
50165796c8dcSSimon Schubert 	      else
50175796c8dcSSimon Schubert 		abort ();
50185796c8dcSSimon Schubert 	      p->p_memsz = p->p_filesz;
5019*ef5ccd6cSJohn Marino 	      /* Preserve the alignment and flags if they are valid. The
5020*ef5ccd6cSJohn Marino 	         gold linker generates RW/4 for the PT_GNU_RELRO section.
5021*ef5ccd6cSJohn Marino 		 It is better for objcopy/strip to honor these attributes
5022*ef5ccd6cSJohn Marino 		 otherwise gdb will choke when using separate debug files.
5023*ef5ccd6cSJohn Marino 	       */
5024*ef5ccd6cSJohn Marino 	      if (!m->p_align_valid)
50255796c8dcSSimon Schubert 		p->p_align = 1;
5026*ef5ccd6cSJohn Marino 	      if (!m->p_flags_valid)
50275796c8dcSSimon Schubert 		p->p_flags = (lp->p_flags & ~PF_W);
50285796c8dcSSimon Schubert 	    }
50295796c8dcSSimon Schubert 	  else
50305796c8dcSSimon Schubert 	    {
50315796c8dcSSimon Schubert 	      memset (p, 0, sizeof *p);
50325796c8dcSSimon Schubert 	      p->p_type = PT_NULL;
50335796c8dcSSimon Schubert 	    }
50345796c8dcSSimon Schubert 	}
5035*ef5ccd6cSJohn Marino       else if (p->p_type == PT_GNU_STACK)
5036*ef5ccd6cSJohn Marino 	{
5037*ef5ccd6cSJohn Marino 	  if (m->p_size_valid)
5038*ef5ccd6cSJohn Marino 	    p->p_memsz = m->p_size;
5039*ef5ccd6cSJohn Marino 	}
50405796c8dcSSimon Schubert       else if (m->count != 0)
50415796c8dcSSimon Schubert 	{
50425796c8dcSSimon Schubert 	  if (p->p_type != PT_LOAD
50435796c8dcSSimon Schubert 	      && (p->p_type != PT_NOTE
50445796c8dcSSimon Schubert 		  || bfd_get_format (abfd) != bfd_core))
50455796c8dcSSimon Schubert 	    {
50465796c8dcSSimon Schubert 	      BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
50475796c8dcSSimon Schubert 
5048a45ae5f8SJohn Marino 	      p->p_filesz = 0;
50495796c8dcSSimon Schubert 	      p->p_offset = m->sections[0]->filepos;
5050a45ae5f8SJohn Marino 	      for (i = m->count; i-- != 0;)
5051a45ae5f8SJohn Marino 		{
5052a45ae5f8SJohn Marino 		  asection *sect = m->sections[i];
5053a45ae5f8SJohn Marino 		  Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
5054a45ae5f8SJohn Marino 		  if (hdr->sh_type != SHT_NOBITS)
5055a45ae5f8SJohn Marino 		    {
5056a45ae5f8SJohn Marino 		      p->p_filesz = (sect->filepos - m->sections[0]->filepos
5057a45ae5f8SJohn Marino 				     + hdr->sh_size);
5058a45ae5f8SJohn Marino 		      break;
5059a45ae5f8SJohn Marino 		    }
5060a45ae5f8SJohn Marino 		}
50615796c8dcSSimon Schubert 	    }
50625796c8dcSSimon Schubert 	}
50635796c8dcSSimon Schubert       else if (m->includes_filehdr)
50645796c8dcSSimon Schubert 	{
50655796c8dcSSimon Schubert 	  p->p_vaddr = filehdr_vaddr;
50665796c8dcSSimon Schubert 	  if (! m->p_paddr_valid)
50675796c8dcSSimon Schubert 	    p->p_paddr = filehdr_paddr;
50685796c8dcSSimon Schubert 	}
50695796c8dcSSimon Schubert       else if (m->includes_phdrs)
50705796c8dcSSimon Schubert 	{
50715796c8dcSSimon Schubert 	  p->p_vaddr = phdrs_vaddr;
50725796c8dcSSimon Schubert 	  if (! m->p_paddr_valid)
50735796c8dcSSimon Schubert 	    p->p_paddr = phdrs_paddr;
50745796c8dcSSimon Schubert 	}
50755796c8dcSSimon Schubert     }
50765796c8dcSSimon Schubert 
5077*ef5ccd6cSJohn Marino   elf_next_file_pos (abfd) = off;
50785796c8dcSSimon Schubert 
50795796c8dcSSimon Schubert   return TRUE;
50805796c8dcSSimon Schubert }
50815796c8dcSSimon Schubert 
50825796c8dcSSimon Schubert /* Work out the file positions of all the sections.  This is called by
50835796c8dcSSimon Schubert    _bfd_elf_compute_section_file_positions.  All the section sizes and
50845796c8dcSSimon Schubert    VMAs must be known before this is called.
50855796c8dcSSimon Schubert 
50865796c8dcSSimon Schubert    Reloc sections come in two flavours: Those processed specially as
50875796c8dcSSimon Schubert    "side-channel" data attached to a section to which they apply, and
50885796c8dcSSimon Schubert    those that bfd doesn't process as relocations.  The latter sort are
50895796c8dcSSimon Schubert    stored in a normal bfd section by bfd_section_from_shdr.   We don't
50905796c8dcSSimon Schubert    consider the former sort here, unless they form part of the loadable
50915796c8dcSSimon Schubert    image.  Reloc sections not assigned here will be handled later by
50925796c8dcSSimon Schubert    assign_file_positions_for_relocs.
50935796c8dcSSimon Schubert 
50945796c8dcSSimon Schubert    We also don't set the positions of the .symtab and .strtab here.  */
50955796c8dcSSimon Schubert 
50965796c8dcSSimon Schubert static bfd_boolean
assign_file_positions_except_relocs(bfd * abfd,struct bfd_link_info * link_info)50975796c8dcSSimon Schubert assign_file_positions_except_relocs (bfd *abfd,
50985796c8dcSSimon Schubert 				     struct bfd_link_info *link_info)
50995796c8dcSSimon Schubert {
51005796c8dcSSimon Schubert   struct elf_obj_tdata *tdata = elf_tdata (abfd);
51015796c8dcSSimon Schubert   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
51025796c8dcSSimon Schubert   file_ptr off;
51035796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
51045796c8dcSSimon Schubert 
51055796c8dcSSimon Schubert   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
51065796c8dcSSimon Schubert       && bfd_get_format (abfd) != bfd_core)
51075796c8dcSSimon Schubert     {
51085796c8dcSSimon Schubert       Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
51095796c8dcSSimon Schubert       unsigned int num_sec = elf_numsections (abfd);
51105796c8dcSSimon Schubert       Elf_Internal_Shdr **hdrpp;
51115796c8dcSSimon Schubert       unsigned int i;
51125796c8dcSSimon Schubert 
51135796c8dcSSimon Schubert       /* Start after the ELF header.  */
51145796c8dcSSimon Schubert       off = i_ehdrp->e_ehsize;
51155796c8dcSSimon Schubert 
51165796c8dcSSimon Schubert       /* We are not creating an executable, which means that we are
51175796c8dcSSimon Schubert 	 not creating a program header, and that the actual order of
51185796c8dcSSimon Schubert 	 the sections in the file is unimportant.  */
51195796c8dcSSimon Schubert       for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
51205796c8dcSSimon Schubert 	{
51215796c8dcSSimon Schubert 	  Elf_Internal_Shdr *hdr;
51225796c8dcSSimon Schubert 
51235796c8dcSSimon Schubert 	  hdr = *hdrpp;
51245796c8dcSSimon Schubert 	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
51255796c8dcSSimon Schubert 	       && hdr->bfd_section == NULL)
5126*ef5ccd6cSJohn Marino 	      || i == elf_onesymtab (abfd)
5127*ef5ccd6cSJohn Marino 	      || i == elf_symtab_shndx (abfd)
5128*ef5ccd6cSJohn Marino 	      || i == elf_strtab_sec (abfd))
51295796c8dcSSimon Schubert 	    {
51305796c8dcSSimon Schubert 	      hdr->sh_offset = -1;
51315796c8dcSSimon Schubert 	    }
51325796c8dcSSimon Schubert 	  else
51335796c8dcSSimon Schubert 	    off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
51345796c8dcSSimon Schubert 	}
51355796c8dcSSimon Schubert     }
51365796c8dcSSimon Schubert   else
51375796c8dcSSimon Schubert     {
51385796c8dcSSimon Schubert       unsigned int alloc;
51395796c8dcSSimon Schubert 
51405796c8dcSSimon Schubert       /* Assign file positions for the loaded sections based on the
51415796c8dcSSimon Schubert 	 assignment of sections to segments.  */
51425796c8dcSSimon Schubert       if (!assign_file_positions_for_load_sections (abfd, link_info))
51435796c8dcSSimon Schubert 	return FALSE;
51445796c8dcSSimon Schubert 
51455796c8dcSSimon Schubert       /* And for non-load sections.  */
51465796c8dcSSimon Schubert       if (!assign_file_positions_for_non_load_sections (abfd, link_info))
51475796c8dcSSimon Schubert 	return FALSE;
51485796c8dcSSimon Schubert 
51495796c8dcSSimon Schubert       if (bed->elf_backend_modify_program_headers != NULL)
51505796c8dcSSimon Schubert 	{
51515796c8dcSSimon Schubert 	  if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
51525796c8dcSSimon Schubert 	    return FALSE;
51535796c8dcSSimon Schubert 	}
51545796c8dcSSimon Schubert 
51555796c8dcSSimon Schubert       /* Write out the program headers.  */
5156*ef5ccd6cSJohn Marino       alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
51575796c8dcSSimon Schubert       if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
51585796c8dcSSimon Schubert 	  || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
51595796c8dcSSimon Schubert 	return FALSE;
51605796c8dcSSimon Schubert 
5161*ef5ccd6cSJohn Marino       off = elf_next_file_pos (abfd);
51625796c8dcSSimon Schubert     }
51635796c8dcSSimon Schubert 
51645796c8dcSSimon Schubert   /* Place the section headers.  */
51655796c8dcSSimon Schubert   off = align_file_position (off, 1 << bed->s->log_file_align);
51665796c8dcSSimon Schubert   i_ehdrp->e_shoff = off;
51675796c8dcSSimon Schubert   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
51685796c8dcSSimon Schubert 
5169*ef5ccd6cSJohn Marino   elf_next_file_pos (abfd) = off;
51705796c8dcSSimon Schubert 
51715796c8dcSSimon Schubert   return TRUE;
51725796c8dcSSimon Schubert }
51735796c8dcSSimon Schubert 
51745796c8dcSSimon Schubert static bfd_boolean
prep_headers(bfd * abfd)51755796c8dcSSimon Schubert prep_headers (bfd *abfd)
51765796c8dcSSimon Schubert {
5177cf7f2e2dSJohn Marino   Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form.  */
51785796c8dcSSimon Schubert   struct elf_strtab_hash *shstrtab;
51795796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
51805796c8dcSSimon Schubert 
51815796c8dcSSimon Schubert   i_ehdrp = elf_elfheader (abfd);
51825796c8dcSSimon Schubert 
51835796c8dcSSimon Schubert   shstrtab = _bfd_elf_strtab_init ();
51845796c8dcSSimon Schubert   if (shstrtab == NULL)
51855796c8dcSSimon Schubert     return FALSE;
51865796c8dcSSimon Schubert 
51875796c8dcSSimon Schubert   elf_shstrtab (abfd) = shstrtab;
51885796c8dcSSimon Schubert 
51895796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
51905796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
51915796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
51925796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;
51935796c8dcSSimon Schubert 
51945796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
51955796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_DATA] =
51965796c8dcSSimon Schubert     bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
51975796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
51985796c8dcSSimon Schubert 
51995796c8dcSSimon Schubert   if ((abfd->flags & DYNAMIC) != 0)
52005796c8dcSSimon Schubert     i_ehdrp->e_type = ET_DYN;
52015796c8dcSSimon Schubert   else if ((abfd->flags & EXEC_P) != 0)
52025796c8dcSSimon Schubert     i_ehdrp->e_type = ET_EXEC;
52035796c8dcSSimon Schubert   else if (bfd_get_format (abfd) == bfd_core)
52045796c8dcSSimon Schubert     i_ehdrp->e_type = ET_CORE;
52055796c8dcSSimon Schubert   else
52065796c8dcSSimon Schubert     i_ehdrp->e_type = ET_REL;
52075796c8dcSSimon Schubert 
52085796c8dcSSimon Schubert   switch (bfd_get_arch (abfd))
52095796c8dcSSimon Schubert     {
52105796c8dcSSimon Schubert     case bfd_arch_unknown:
52115796c8dcSSimon Schubert       i_ehdrp->e_machine = EM_NONE;
52125796c8dcSSimon Schubert       break;
52135796c8dcSSimon Schubert 
52145796c8dcSSimon Schubert       /* There used to be a long list of cases here, each one setting
52155796c8dcSSimon Schubert 	 e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
52165796c8dcSSimon Schubert 	 in the corresponding bfd definition.  To avoid duplication,
52175796c8dcSSimon Schubert 	 the switch was removed.  Machines that need special handling
52185796c8dcSSimon Schubert 	 can generally do it in elf_backend_final_write_processing(),
52195796c8dcSSimon Schubert 	 unless they need the information earlier than the final write.
52205796c8dcSSimon Schubert 	 Such need can generally be supplied by replacing the tests for
52215796c8dcSSimon Schubert 	 e_machine with the conditions used to determine it.  */
52225796c8dcSSimon Schubert     default:
52235796c8dcSSimon Schubert       i_ehdrp->e_machine = bed->elf_machine_code;
52245796c8dcSSimon Schubert     }
52255796c8dcSSimon Schubert 
52265796c8dcSSimon Schubert   i_ehdrp->e_version = bed->s->ev_current;
52275796c8dcSSimon Schubert   i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
52285796c8dcSSimon Schubert 
52295796c8dcSSimon Schubert   /* No program header, for now.  */
52305796c8dcSSimon Schubert   i_ehdrp->e_phoff = 0;
52315796c8dcSSimon Schubert   i_ehdrp->e_phentsize = 0;
52325796c8dcSSimon Schubert   i_ehdrp->e_phnum = 0;
52335796c8dcSSimon Schubert 
52345796c8dcSSimon Schubert   /* Each bfd section is section header entry.  */
52355796c8dcSSimon Schubert   i_ehdrp->e_entry = bfd_get_start_address (abfd);
52365796c8dcSSimon Schubert   i_ehdrp->e_shentsize = bed->s->sizeof_shdr;
52375796c8dcSSimon Schubert 
52385796c8dcSSimon Schubert   /* If we're building an executable, we'll need a program header table.  */
52395796c8dcSSimon Schubert   if (abfd->flags & EXEC_P)
52405796c8dcSSimon Schubert     /* It all happens later.  */
52415796c8dcSSimon Schubert     ;
52425796c8dcSSimon Schubert   else
52435796c8dcSSimon Schubert     {
52445796c8dcSSimon Schubert       i_ehdrp->e_phentsize = 0;
52455796c8dcSSimon Schubert       i_ehdrp->e_phoff = 0;
52465796c8dcSSimon Schubert     }
52475796c8dcSSimon Schubert 
52485796c8dcSSimon Schubert   elf_tdata (abfd)->symtab_hdr.sh_name =
52495796c8dcSSimon Schubert     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", FALSE);
52505796c8dcSSimon Schubert   elf_tdata (abfd)->strtab_hdr.sh_name =
52515796c8dcSSimon Schubert     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", FALSE);
52525796c8dcSSimon Schubert   elf_tdata (abfd)->shstrtab_hdr.sh_name =
52535796c8dcSSimon Schubert     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
52545796c8dcSSimon Schubert   if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
52555796c8dcSSimon Schubert       || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
52565796c8dcSSimon Schubert       || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
52575796c8dcSSimon Schubert     return FALSE;
52585796c8dcSSimon Schubert 
52595796c8dcSSimon Schubert   return TRUE;
52605796c8dcSSimon Schubert }
52615796c8dcSSimon Schubert 
52625796c8dcSSimon Schubert /* Assign file positions for all the reloc sections which are not part
52635796c8dcSSimon Schubert    of the loadable file image.  */
52645796c8dcSSimon Schubert 
52655796c8dcSSimon Schubert void
_bfd_elf_assign_file_positions_for_relocs(bfd * abfd)52665796c8dcSSimon Schubert _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
52675796c8dcSSimon Schubert {
52685796c8dcSSimon Schubert   file_ptr off;
52695796c8dcSSimon Schubert   unsigned int i, num_sec;
52705796c8dcSSimon Schubert   Elf_Internal_Shdr **shdrpp;
52715796c8dcSSimon Schubert 
5272*ef5ccd6cSJohn Marino   off = elf_next_file_pos (abfd);
52735796c8dcSSimon Schubert 
52745796c8dcSSimon Schubert   num_sec = elf_numsections (abfd);
52755796c8dcSSimon Schubert   for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
52765796c8dcSSimon Schubert     {
52775796c8dcSSimon Schubert       Elf_Internal_Shdr *shdrp;
52785796c8dcSSimon Schubert 
52795796c8dcSSimon Schubert       shdrp = *shdrpp;
52805796c8dcSSimon Schubert       if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
52815796c8dcSSimon Schubert 	  && shdrp->sh_offset == -1)
52825796c8dcSSimon Schubert 	off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
52835796c8dcSSimon Schubert     }
52845796c8dcSSimon Schubert 
5285*ef5ccd6cSJohn Marino   elf_next_file_pos (abfd) = off;
52865796c8dcSSimon Schubert }
52875796c8dcSSimon Schubert 
52885796c8dcSSimon Schubert bfd_boolean
_bfd_elf_write_object_contents(bfd * abfd)52895796c8dcSSimon Schubert _bfd_elf_write_object_contents (bfd *abfd)
52905796c8dcSSimon Schubert {
52915796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
52925796c8dcSSimon Schubert   Elf_Internal_Shdr **i_shdrp;
52935796c8dcSSimon Schubert   bfd_boolean failed;
52945796c8dcSSimon Schubert   unsigned int count, num_sec;
5295*ef5ccd6cSJohn Marino   struct elf_obj_tdata *t;
52965796c8dcSSimon Schubert 
52975796c8dcSSimon Schubert   if (! abfd->output_has_begun
52985796c8dcSSimon Schubert       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
52995796c8dcSSimon Schubert     return FALSE;
53005796c8dcSSimon Schubert 
53015796c8dcSSimon Schubert   i_shdrp = elf_elfsections (abfd);
53025796c8dcSSimon Schubert 
53035796c8dcSSimon Schubert   failed = FALSE;
53045796c8dcSSimon Schubert   bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
53055796c8dcSSimon Schubert   if (failed)
53065796c8dcSSimon Schubert     return FALSE;
53075796c8dcSSimon Schubert 
53085796c8dcSSimon Schubert   _bfd_elf_assign_file_positions_for_relocs (abfd);
53095796c8dcSSimon Schubert 
53105796c8dcSSimon Schubert   /* After writing the headers, we need to write the sections too...  */
53115796c8dcSSimon Schubert   num_sec = elf_numsections (abfd);
53125796c8dcSSimon Schubert   for (count = 1; count < num_sec; count++)
53135796c8dcSSimon Schubert     {
53145796c8dcSSimon Schubert       if (bed->elf_backend_section_processing)
53155796c8dcSSimon Schubert 	(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]);
53165796c8dcSSimon Schubert       if (i_shdrp[count]->contents)
53175796c8dcSSimon Schubert 	{
53185796c8dcSSimon Schubert 	  bfd_size_type amt = i_shdrp[count]->sh_size;
53195796c8dcSSimon Schubert 
53205796c8dcSSimon Schubert 	  if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
53215796c8dcSSimon Schubert 	      || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
53225796c8dcSSimon Schubert 	    return FALSE;
53235796c8dcSSimon Schubert 	}
53245796c8dcSSimon Schubert     }
53255796c8dcSSimon Schubert 
53265796c8dcSSimon Schubert   /* Write out the section header names.  */
5327*ef5ccd6cSJohn Marino   t = elf_tdata (abfd);
53285796c8dcSSimon Schubert   if (elf_shstrtab (abfd) != NULL
5329*ef5ccd6cSJohn Marino       && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0
53305796c8dcSSimon Schubert 	  || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
53315796c8dcSSimon Schubert     return FALSE;
53325796c8dcSSimon Schubert 
53335796c8dcSSimon Schubert   if (bed->elf_backend_final_write_processing)
5334*ef5ccd6cSJohn Marino     (*bed->elf_backend_final_write_processing) (abfd, elf_linker (abfd));
53355796c8dcSSimon Schubert 
53365796c8dcSSimon Schubert   if (!bed->s->write_shdrs_and_ehdr (abfd))
53375796c8dcSSimon Schubert     return FALSE;
53385796c8dcSSimon Schubert 
53395796c8dcSSimon Schubert   /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0].  */
5340*ef5ccd6cSJohn Marino   if (t->o->build_id.after_write_object_contents != NULL)
5341*ef5ccd6cSJohn Marino     return (*t->o->build_id.after_write_object_contents) (abfd);
53425796c8dcSSimon Schubert 
53435796c8dcSSimon Schubert   return TRUE;
53445796c8dcSSimon Schubert }
53455796c8dcSSimon Schubert 
53465796c8dcSSimon Schubert bfd_boolean
_bfd_elf_write_corefile_contents(bfd * abfd)53475796c8dcSSimon Schubert _bfd_elf_write_corefile_contents (bfd *abfd)
53485796c8dcSSimon Schubert {
53495796c8dcSSimon Schubert   /* Hopefully this can be done just like an object file.  */
53505796c8dcSSimon Schubert   return _bfd_elf_write_object_contents (abfd);
53515796c8dcSSimon Schubert }
53525796c8dcSSimon Schubert 
53535796c8dcSSimon Schubert /* Given a section, search the header to find them.  */
53545796c8dcSSimon Schubert 
53555796c8dcSSimon Schubert unsigned int
_bfd_elf_section_from_bfd_section(bfd * abfd,struct bfd_section * asect)53565796c8dcSSimon Schubert _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
53575796c8dcSSimon Schubert {
53585796c8dcSSimon Schubert   const struct elf_backend_data *bed;
5359cf7f2e2dSJohn Marino   unsigned int sec_index;
53605796c8dcSSimon Schubert 
53615796c8dcSSimon Schubert   if (elf_section_data (asect) != NULL
53625796c8dcSSimon Schubert       && elf_section_data (asect)->this_idx != 0)
53635796c8dcSSimon Schubert     return elf_section_data (asect)->this_idx;
53645796c8dcSSimon Schubert 
53655796c8dcSSimon Schubert   if (bfd_is_abs_section (asect))
5366cf7f2e2dSJohn Marino     sec_index = SHN_ABS;
53675796c8dcSSimon Schubert   else if (bfd_is_com_section (asect))
5368cf7f2e2dSJohn Marino     sec_index = SHN_COMMON;
53695796c8dcSSimon Schubert   else if (bfd_is_und_section (asect))
5370cf7f2e2dSJohn Marino     sec_index = SHN_UNDEF;
53715796c8dcSSimon Schubert   else
5372cf7f2e2dSJohn Marino     sec_index = SHN_BAD;
53735796c8dcSSimon Schubert 
53745796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
53755796c8dcSSimon Schubert   if (bed->elf_backend_section_from_bfd_section)
53765796c8dcSSimon Schubert     {
5377cf7f2e2dSJohn Marino       int retval = sec_index;
53785796c8dcSSimon Schubert 
53795796c8dcSSimon Schubert       if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
53805796c8dcSSimon Schubert 	return retval;
53815796c8dcSSimon Schubert     }
53825796c8dcSSimon Schubert 
5383cf7f2e2dSJohn Marino   if (sec_index == SHN_BAD)
53845796c8dcSSimon Schubert     bfd_set_error (bfd_error_nonrepresentable_section);
53855796c8dcSSimon Schubert 
5386cf7f2e2dSJohn Marino   return sec_index;
53875796c8dcSSimon Schubert }
53885796c8dcSSimon Schubert 
53895796c8dcSSimon Schubert /* Given a BFD symbol, return the index in the ELF symbol table, or -1
53905796c8dcSSimon Schubert    on error.  */
53915796c8dcSSimon Schubert 
53925796c8dcSSimon Schubert int
_bfd_elf_symbol_from_bfd_symbol(bfd * abfd,asymbol ** asym_ptr_ptr)53935796c8dcSSimon Schubert _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
53945796c8dcSSimon Schubert {
53955796c8dcSSimon Schubert   asymbol *asym_ptr = *asym_ptr_ptr;
53965796c8dcSSimon Schubert   int idx;
53975796c8dcSSimon Schubert   flagword flags = asym_ptr->flags;
53985796c8dcSSimon Schubert 
53995796c8dcSSimon Schubert   /* When gas creates relocations against local labels, it creates its
54005796c8dcSSimon Schubert      own symbol for the section, but does put the symbol into the
54015796c8dcSSimon Schubert      symbol chain, so udata is 0.  When the linker is generating
54025796c8dcSSimon Schubert      relocatable output, this section symbol may be for one of the
54035796c8dcSSimon Schubert      input sections rather than the output section.  */
54045796c8dcSSimon Schubert   if (asym_ptr->udata.i == 0
54055796c8dcSSimon Schubert       && (flags & BSF_SECTION_SYM)
54065796c8dcSSimon Schubert       && asym_ptr->section)
54075796c8dcSSimon Schubert     {
54085796c8dcSSimon Schubert       asection *sec;
54095796c8dcSSimon Schubert       int indx;
54105796c8dcSSimon Schubert 
54115796c8dcSSimon Schubert       sec = asym_ptr->section;
54125796c8dcSSimon Schubert       if (sec->owner != abfd && sec->output_section != NULL)
54135796c8dcSSimon Schubert 	sec = sec->output_section;
54145796c8dcSSimon Schubert       if (sec->owner == abfd
54155796c8dcSSimon Schubert 	  && (indx = sec->index) < elf_num_section_syms (abfd)
54165796c8dcSSimon Schubert 	  && elf_section_syms (abfd)[indx] != NULL)
54175796c8dcSSimon Schubert 	asym_ptr->udata.i = elf_section_syms (abfd)[indx]->udata.i;
54185796c8dcSSimon Schubert     }
54195796c8dcSSimon Schubert 
54205796c8dcSSimon Schubert   idx = asym_ptr->udata.i;
54215796c8dcSSimon Schubert 
54225796c8dcSSimon Schubert   if (idx == 0)
54235796c8dcSSimon Schubert     {
54245796c8dcSSimon Schubert       /* This case can occur when using --strip-symbol on a symbol
54255796c8dcSSimon Schubert 	 which is used in a relocation entry.  */
54265796c8dcSSimon Schubert       (*_bfd_error_handler)
54275796c8dcSSimon Schubert 	(_("%B: symbol `%s' required but not present"),
54285796c8dcSSimon Schubert 	 abfd, bfd_asymbol_name (asym_ptr));
54295796c8dcSSimon Schubert       bfd_set_error (bfd_error_no_symbols);
54305796c8dcSSimon Schubert       return -1;
54315796c8dcSSimon Schubert     }
54325796c8dcSSimon Schubert 
54335796c8dcSSimon Schubert #if DEBUG & 4
54345796c8dcSSimon Schubert   {
54355796c8dcSSimon Schubert     fprintf (stderr,
5436c50c785cSJohn Marino 	     "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx\n",
5437c50c785cSJohn Marino 	     (long) asym_ptr, asym_ptr->name, idx, (long) flags);
54385796c8dcSSimon Schubert     fflush (stderr);
54395796c8dcSSimon Schubert   }
54405796c8dcSSimon Schubert #endif
54415796c8dcSSimon Schubert 
54425796c8dcSSimon Schubert   return idx;
54435796c8dcSSimon Schubert }
54445796c8dcSSimon Schubert 
54455796c8dcSSimon Schubert /* Rewrite program header information.  */
54465796c8dcSSimon Schubert 
54475796c8dcSSimon Schubert static bfd_boolean
rewrite_elf_program_header(bfd * ibfd,bfd * obfd)54485796c8dcSSimon Schubert rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
54495796c8dcSSimon Schubert {
54505796c8dcSSimon Schubert   Elf_Internal_Ehdr *iehdr;
54515796c8dcSSimon Schubert   struct elf_segment_map *map;
54525796c8dcSSimon Schubert   struct elf_segment_map *map_first;
54535796c8dcSSimon Schubert   struct elf_segment_map **pointer_to_map;
54545796c8dcSSimon Schubert   Elf_Internal_Phdr *segment;
54555796c8dcSSimon Schubert   asection *section;
54565796c8dcSSimon Schubert   unsigned int i;
54575796c8dcSSimon Schubert   unsigned int num_segments;
54585796c8dcSSimon Schubert   bfd_boolean phdr_included = FALSE;
54595796c8dcSSimon Schubert   bfd_boolean p_paddr_valid;
54605796c8dcSSimon Schubert   bfd_vma maxpagesize;
54615796c8dcSSimon Schubert   struct elf_segment_map *phdr_adjust_seg = NULL;
54625796c8dcSSimon Schubert   unsigned int phdr_adjust_num = 0;
54635796c8dcSSimon Schubert   const struct elf_backend_data *bed;
54645796c8dcSSimon Schubert 
54655796c8dcSSimon Schubert   bed = get_elf_backend_data (ibfd);
54665796c8dcSSimon Schubert   iehdr = elf_elfheader (ibfd);
54675796c8dcSSimon Schubert 
54685796c8dcSSimon Schubert   map_first = NULL;
54695796c8dcSSimon Schubert   pointer_to_map = &map_first;
54705796c8dcSSimon Schubert 
54715796c8dcSSimon Schubert   num_segments = elf_elfheader (ibfd)->e_phnum;
54725796c8dcSSimon Schubert   maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
54735796c8dcSSimon Schubert 
54745796c8dcSSimon Schubert   /* Returns the end address of the segment + 1.  */
54755796c8dcSSimon Schubert #define SEGMENT_END(segment, start)					\
54765796c8dcSSimon Schubert   (start + (segment->p_memsz > segment->p_filesz			\
54775796c8dcSSimon Schubert 	    ? segment->p_memsz : segment->p_filesz))
54785796c8dcSSimon Schubert 
54795796c8dcSSimon Schubert #define SECTION_SIZE(section, segment)					\
54805796c8dcSSimon Schubert   (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL))		\
54815796c8dcSSimon Schubert     != SEC_THREAD_LOCAL || segment->p_type == PT_TLS)			\
54825796c8dcSSimon Schubert    ? section->size : 0)
54835796c8dcSSimon Schubert 
54845796c8dcSSimon Schubert   /* Returns TRUE if the given section is contained within
54855796c8dcSSimon Schubert      the given segment.  VMA addresses are compared.  */
54865796c8dcSSimon Schubert #define IS_CONTAINED_BY_VMA(section, segment)				\
54875796c8dcSSimon Schubert   (section->vma >= segment->p_vaddr					\
54885796c8dcSSimon Schubert    && (section->vma + SECTION_SIZE (section, segment)			\
54895796c8dcSSimon Schubert        <= (SEGMENT_END (segment, segment->p_vaddr))))
54905796c8dcSSimon Schubert 
54915796c8dcSSimon Schubert   /* Returns TRUE if the given section is contained within
54925796c8dcSSimon Schubert      the given segment.  LMA addresses are compared.  */
54935796c8dcSSimon Schubert #define IS_CONTAINED_BY_LMA(section, segment, base)			\
54945796c8dcSSimon Schubert   (section->lma >= base							\
54955796c8dcSSimon Schubert    && (section->lma + SECTION_SIZE (section, segment)			\
54965796c8dcSSimon Schubert        <= SEGMENT_END (segment, base)))
54975796c8dcSSimon Schubert 
54985796c8dcSSimon Schubert   /* Handle PT_NOTE segment.  */
54995796c8dcSSimon Schubert #define IS_NOTE(p, s)							\
55005796c8dcSSimon Schubert   (p->p_type == PT_NOTE							\
55015796c8dcSSimon Schubert    && elf_section_type (s) == SHT_NOTE					\
55025796c8dcSSimon Schubert    && (bfd_vma) s->filepos >= p->p_offset				\
55035796c8dcSSimon Schubert    && ((bfd_vma) s->filepos + s->size					\
55045796c8dcSSimon Schubert        <= p->p_offset + p->p_filesz))
55055796c8dcSSimon Schubert 
55065796c8dcSSimon Schubert   /* Special case: corefile "NOTE" section containing regs, prpsinfo
55075796c8dcSSimon Schubert      etc.  */
55085796c8dcSSimon Schubert #define IS_COREFILE_NOTE(p, s)						\
55095796c8dcSSimon Schubert   (IS_NOTE (p, s)							\
55105796c8dcSSimon Schubert    && bfd_get_format (ibfd) == bfd_core					\
55115796c8dcSSimon Schubert    && s->vma == 0							\
55125796c8dcSSimon Schubert    && s->lma == 0)
55135796c8dcSSimon Schubert 
55145796c8dcSSimon Schubert   /* The complicated case when p_vaddr is 0 is to handle the Solaris
55155796c8dcSSimon Schubert      linker, which generates a PT_INTERP section with p_vaddr and
55165796c8dcSSimon Schubert      p_memsz set to 0.  */
55175796c8dcSSimon Schubert #define IS_SOLARIS_PT_INTERP(p, s)					\
55185796c8dcSSimon Schubert   (p->p_vaddr == 0							\
55195796c8dcSSimon Schubert    && p->p_paddr == 0							\
55205796c8dcSSimon Schubert    && p->p_memsz == 0							\
55215796c8dcSSimon Schubert    && p->p_filesz > 0							\
55225796c8dcSSimon Schubert    && (s->flags & SEC_HAS_CONTENTS) != 0				\
55235796c8dcSSimon Schubert    && s->size > 0							\
55245796c8dcSSimon Schubert    && (bfd_vma) s->filepos >= p->p_offset				\
55255796c8dcSSimon Schubert    && ((bfd_vma) s->filepos + s->size					\
55265796c8dcSSimon Schubert        <= p->p_offset + p->p_filesz))
55275796c8dcSSimon Schubert 
55285796c8dcSSimon Schubert   /* Decide if the given section should be included in the given segment.
55295796c8dcSSimon Schubert      A section will be included if:
55305796c8dcSSimon Schubert        1. It is within the address space of the segment -- we use the LMA
55315796c8dcSSimon Schubert 	  if that is set for the segment and the VMA otherwise,
55325796c8dcSSimon Schubert        2. It is an allocated section or a NOTE section in a PT_NOTE
55335796c8dcSSimon Schubert 	  segment.
55345796c8dcSSimon Schubert        3. There is an output section associated with it,
55355796c8dcSSimon Schubert        4. The section has not already been allocated to a previous segment.
55365796c8dcSSimon Schubert        5. PT_GNU_STACK segments do not include any sections.
55375796c8dcSSimon Schubert        6. PT_TLS segment includes only SHF_TLS sections.
55385796c8dcSSimon Schubert        7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
55395796c8dcSSimon Schubert        8. PT_DYNAMIC should not contain empty sections at the beginning
55405796c8dcSSimon Schubert 	  (with the possible exception of .dynamic).  */
55415796c8dcSSimon Schubert #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed)		\
55425796c8dcSSimon Schubert   ((((segment->p_paddr							\
55435796c8dcSSimon Schubert       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)	\
55445796c8dcSSimon Schubert       : IS_CONTAINED_BY_VMA (section, segment))				\
55455796c8dcSSimon Schubert      && (section->flags & SEC_ALLOC) != 0)				\
55465796c8dcSSimon Schubert     || IS_NOTE (segment, section))					\
55475796c8dcSSimon Schubert    && segment->p_type != PT_GNU_STACK					\
55485796c8dcSSimon Schubert    && (segment->p_type != PT_TLS					\
55495796c8dcSSimon Schubert        || (section->flags & SEC_THREAD_LOCAL))				\
55505796c8dcSSimon Schubert    && (segment->p_type == PT_LOAD					\
55515796c8dcSSimon Schubert        || segment->p_type == PT_TLS					\
55525796c8dcSSimon Schubert        || (section->flags & SEC_THREAD_LOCAL) == 0)			\
55535796c8dcSSimon Schubert    && (segment->p_type != PT_DYNAMIC					\
55545796c8dcSSimon Schubert        || SECTION_SIZE (section, segment) > 0				\
55555796c8dcSSimon Schubert        || (segment->p_paddr						\
55565796c8dcSSimon Schubert 	   ? segment->p_paddr != section->lma				\
55575796c8dcSSimon Schubert 	   : segment->p_vaddr != section->vma)				\
55585796c8dcSSimon Schubert        || (strcmp (bfd_get_section_name (ibfd, section), ".dynamic")	\
55595796c8dcSSimon Schubert 	   == 0))							\
55605796c8dcSSimon Schubert    && !section->segment_mark)
55615796c8dcSSimon Schubert 
55625796c8dcSSimon Schubert /* If the output section of a section in the input segment is NULL,
55635796c8dcSSimon Schubert    it is removed from the corresponding output segment.   */
55645796c8dcSSimon Schubert #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)		\
55655796c8dcSSimon Schubert   (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)		\
55665796c8dcSSimon Schubert    && section->output_section != NULL)
55675796c8dcSSimon Schubert 
55685796c8dcSSimon Schubert   /* Returns TRUE iff seg1 starts after the end of seg2.  */
55695796c8dcSSimon Schubert #define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)			\
55705796c8dcSSimon Schubert   (seg1->field >= SEGMENT_END (seg2, seg2->field))
55715796c8dcSSimon Schubert 
55725796c8dcSSimon Schubert   /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
55735796c8dcSSimon Schubert      their VMA address ranges and their LMA address ranges overlap.
55745796c8dcSSimon Schubert      It is possible to have overlapping VMA ranges without overlapping LMA
55755796c8dcSSimon Schubert      ranges.  RedBoot images for example can have both .data and .bss mapped
55765796c8dcSSimon Schubert      to the same VMA range, but with the .data section mapped to a different
55775796c8dcSSimon Schubert      LMA.  */
55785796c8dcSSimon Schubert #define SEGMENT_OVERLAPS(seg1, seg2)					\
55795796c8dcSSimon Schubert   (   !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr)			\
55805796c8dcSSimon Schubert 	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr))			\
55815796c8dcSSimon Schubert    && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr)			\
55825796c8dcSSimon Schubert 	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
55835796c8dcSSimon Schubert 
55845796c8dcSSimon Schubert   /* Initialise the segment mark field.  */
55855796c8dcSSimon Schubert   for (section = ibfd->sections; section != NULL; section = section->next)
55865796c8dcSSimon Schubert     section->segment_mark = FALSE;
55875796c8dcSSimon Schubert 
55885796c8dcSSimon Schubert   /* The Solaris linker creates program headers in which all the
55895796c8dcSSimon Schubert      p_paddr fields are zero.  When we try to objcopy or strip such a
55905796c8dcSSimon Schubert      file, we get confused.  Check for this case, and if we find it
55915796c8dcSSimon Schubert      don't set the p_paddr_valid fields.  */
55925796c8dcSSimon Schubert   p_paddr_valid = FALSE;
55935796c8dcSSimon Schubert   for (i = 0, segment = elf_tdata (ibfd)->phdr;
55945796c8dcSSimon Schubert        i < num_segments;
55955796c8dcSSimon Schubert        i++, segment++)
55965796c8dcSSimon Schubert     if (segment->p_paddr != 0)
55975796c8dcSSimon Schubert       {
55985796c8dcSSimon Schubert 	p_paddr_valid = TRUE;
55995796c8dcSSimon Schubert 	break;
56005796c8dcSSimon Schubert       }
56015796c8dcSSimon Schubert 
56025796c8dcSSimon Schubert   /* Scan through the segments specified in the program header
56035796c8dcSSimon Schubert      of the input BFD.  For this first scan we look for overlaps
56045796c8dcSSimon Schubert      in the loadable segments.  These can be created by weird
56055796c8dcSSimon Schubert      parameters to objcopy.  Also, fix some solaris weirdness.  */
56065796c8dcSSimon Schubert   for (i = 0, segment = elf_tdata (ibfd)->phdr;
56075796c8dcSSimon Schubert        i < num_segments;
56085796c8dcSSimon Schubert        i++, segment++)
56095796c8dcSSimon Schubert     {
56105796c8dcSSimon Schubert       unsigned int j;
56115796c8dcSSimon Schubert       Elf_Internal_Phdr *segment2;
56125796c8dcSSimon Schubert 
56135796c8dcSSimon Schubert       if (segment->p_type == PT_INTERP)
56145796c8dcSSimon Schubert 	for (section = ibfd->sections; section; section = section->next)
56155796c8dcSSimon Schubert 	  if (IS_SOLARIS_PT_INTERP (segment, section))
56165796c8dcSSimon Schubert 	    {
56175796c8dcSSimon Schubert 	      /* Mininal change so that the normal section to segment
56185796c8dcSSimon Schubert 		 assignment code will work.  */
56195796c8dcSSimon Schubert 	      segment->p_vaddr = section->vma;
56205796c8dcSSimon Schubert 	      break;
56215796c8dcSSimon Schubert 	    }
56225796c8dcSSimon Schubert 
56235796c8dcSSimon Schubert       if (segment->p_type != PT_LOAD)
56245796c8dcSSimon Schubert 	{
56255796c8dcSSimon Schubert 	  /* Remove PT_GNU_RELRO segment.  */
56265796c8dcSSimon Schubert 	  if (segment->p_type == PT_GNU_RELRO)
56275796c8dcSSimon Schubert 	    segment->p_type = PT_NULL;
56285796c8dcSSimon Schubert 	  continue;
56295796c8dcSSimon Schubert 	}
56305796c8dcSSimon Schubert 
56315796c8dcSSimon Schubert       /* Determine if this segment overlaps any previous segments.  */
56325796c8dcSSimon Schubert       for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
56335796c8dcSSimon Schubert 	{
56345796c8dcSSimon Schubert 	  bfd_signed_vma extra_length;
56355796c8dcSSimon Schubert 
56365796c8dcSSimon Schubert 	  if (segment2->p_type != PT_LOAD
56375796c8dcSSimon Schubert 	      || !SEGMENT_OVERLAPS (segment, segment2))
56385796c8dcSSimon Schubert 	    continue;
56395796c8dcSSimon Schubert 
56405796c8dcSSimon Schubert 	  /* Merge the two segments together.  */
56415796c8dcSSimon Schubert 	  if (segment2->p_vaddr < segment->p_vaddr)
56425796c8dcSSimon Schubert 	    {
56435796c8dcSSimon Schubert 	      /* Extend SEGMENT2 to include SEGMENT and then delete
56445796c8dcSSimon Schubert 		 SEGMENT.  */
56455796c8dcSSimon Schubert 	      extra_length = (SEGMENT_END (segment, segment->p_vaddr)
56465796c8dcSSimon Schubert 			      - SEGMENT_END (segment2, segment2->p_vaddr));
56475796c8dcSSimon Schubert 
56485796c8dcSSimon Schubert 	      if (extra_length > 0)
56495796c8dcSSimon Schubert 		{
56505796c8dcSSimon Schubert 		  segment2->p_memsz += extra_length;
56515796c8dcSSimon Schubert 		  segment2->p_filesz += extra_length;
56525796c8dcSSimon Schubert 		}
56535796c8dcSSimon Schubert 
56545796c8dcSSimon Schubert 	      segment->p_type = PT_NULL;
56555796c8dcSSimon Schubert 
56565796c8dcSSimon Schubert 	      /* Since we have deleted P we must restart the outer loop.  */
56575796c8dcSSimon Schubert 	      i = 0;
56585796c8dcSSimon Schubert 	      segment = elf_tdata (ibfd)->phdr;
56595796c8dcSSimon Schubert 	      break;
56605796c8dcSSimon Schubert 	    }
56615796c8dcSSimon Schubert 	  else
56625796c8dcSSimon Schubert 	    {
56635796c8dcSSimon Schubert 	      /* Extend SEGMENT to include SEGMENT2 and then delete
56645796c8dcSSimon Schubert 		 SEGMENT2.  */
56655796c8dcSSimon Schubert 	      extra_length = (SEGMENT_END (segment2, segment2->p_vaddr)
56665796c8dcSSimon Schubert 			      - SEGMENT_END (segment, segment->p_vaddr));
56675796c8dcSSimon Schubert 
56685796c8dcSSimon Schubert 	      if (extra_length > 0)
56695796c8dcSSimon Schubert 		{
56705796c8dcSSimon Schubert 		  segment->p_memsz += extra_length;
56715796c8dcSSimon Schubert 		  segment->p_filesz += extra_length;
56725796c8dcSSimon Schubert 		}
56735796c8dcSSimon Schubert 
56745796c8dcSSimon Schubert 	      segment2->p_type = PT_NULL;
56755796c8dcSSimon Schubert 	    }
56765796c8dcSSimon Schubert 	}
56775796c8dcSSimon Schubert     }
56785796c8dcSSimon Schubert 
56795796c8dcSSimon Schubert   /* The second scan attempts to assign sections to segments.  */
56805796c8dcSSimon Schubert   for (i = 0, segment = elf_tdata (ibfd)->phdr;
56815796c8dcSSimon Schubert        i < num_segments;
56825796c8dcSSimon Schubert        i++, segment++)
56835796c8dcSSimon Schubert     {
56845796c8dcSSimon Schubert       unsigned int section_count;
56855796c8dcSSimon Schubert       asection **sections;
56865796c8dcSSimon Schubert       asection *output_section;
56875796c8dcSSimon Schubert       unsigned int isec;
56885796c8dcSSimon Schubert       bfd_vma matching_lma;
56895796c8dcSSimon Schubert       bfd_vma suggested_lma;
56905796c8dcSSimon Schubert       unsigned int j;
56915796c8dcSSimon Schubert       bfd_size_type amt;
56925796c8dcSSimon Schubert       asection *first_section;
56935796c8dcSSimon Schubert       bfd_boolean first_matching_lma;
56945796c8dcSSimon Schubert       bfd_boolean first_suggested_lma;
56955796c8dcSSimon Schubert 
56965796c8dcSSimon Schubert       if (segment->p_type == PT_NULL)
56975796c8dcSSimon Schubert 	continue;
56985796c8dcSSimon Schubert 
56995796c8dcSSimon Schubert       first_section = NULL;
57005796c8dcSSimon Schubert       /* Compute how many sections might be placed into this segment.  */
57015796c8dcSSimon Schubert       for (section = ibfd->sections, section_count = 0;
57025796c8dcSSimon Schubert 	   section != NULL;
57035796c8dcSSimon Schubert 	   section = section->next)
57045796c8dcSSimon Schubert 	{
57055796c8dcSSimon Schubert 	  /* Find the first section in the input segment, which may be
57065796c8dcSSimon Schubert 	     removed from the corresponding output segment.   */
57075796c8dcSSimon Schubert 	  if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
57085796c8dcSSimon Schubert 	    {
57095796c8dcSSimon Schubert 	      if (first_section == NULL)
57105796c8dcSSimon Schubert 		first_section = section;
57115796c8dcSSimon Schubert 	      if (section->output_section != NULL)
57125796c8dcSSimon Schubert 		++section_count;
57135796c8dcSSimon Schubert 	    }
57145796c8dcSSimon Schubert 	}
57155796c8dcSSimon Schubert 
57165796c8dcSSimon Schubert       /* Allocate a segment map big enough to contain
57175796c8dcSSimon Schubert 	 all of the sections we have selected.  */
57185796c8dcSSimon Schubert       amt = sizeof (struct elf_segment_map);
57195796c8dcSSimon Schubert       amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
57205796c8dcSSimon Schubert       map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
57215796c8dcSSimon Schubert       if (map == NULL)
57225796c8dcSSimon Schubert 	return FALSE;
57235796c8dcSSimon Schubert 
57245796c8dcSSimon Schubert       /* Initialise the fields of the segment map.  Default to
57255796c8dcSSimon Schubert 	 using the physical address of the segment in the input BFD.  */
57265796c8dcSSimon Schubert       map->next = NULL;
57275796c8dcSSimon Schubert       map->p_type = segment->p_type;
57285796c8dcSSimon Schubert       map->p_flags = segment->p_flags;
57295796c8dcSSimon Schubert       map->p_flags_valid = 1;
57305796c8dcSSimon Schubert 
57315796c8dcSSimon Schubert       /* If the first section in the input segment is removed, there is
57325796c8dcSSimon Schubert 	 no need to preserve segment physical address in the corresponding
57335796c8dcSSimon Schubert 	 output segment.  */
57345796c8dcSSimon Schubert       if (!first_section || first_section->output_section != NULL)
57355796c8dcSSimon Schubert 	{
57365796c8dcSSimon Schubert 	  map->p_paddr = segment->p_paddr;
57375796c8dcSSimon Schubert 	  map->p_paddr_valid = p_paddr_valid;
57385796c8dcSSimon Schubert 	}
57395796c8dcSSimon Schubert 
57405796c8dcSSimon Schubert       /* Determine if this segment contains the ELF file header
57415796c8dcSSimon Schubert 	 and if it contains the program headers themselves.  */
57425796c8dcSSimon Schubert       map->includes_filehdr = (segment->p_offset == 0
57435796c8dcSSimon Schubert 			       && segment->p_filesz >= iehdr->e_ehsize);
57445796c8dcSSimon Schubert       map->includes_phdrs = 0;
57455796c8dcSSimon Schubert 
57465796c8dcSSimon Schubert       if (!phdr_included || segment->p_type != PT_LOAD)
57475796c8dcSSimon Schubert 	{
57485796c8dcSSimon Schubert 	  map->includes_phdrs =
57495796c8dcSSimon Schubert 	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
57505796c8dcSSimon Schubert 	     && (segment->p_offset + segment->p_filesz
57515796c8dcSSimon Schubert 		 >= ((bfd_vma) iehdr->e_phoff
57525796c8dcSSimon Schubert 		     + iehdr->e_phnum * iehdr->e_phentsize)));
57535796c8dcSSimon Schubert 
57545796c8dcSSimon Schubert 	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
57555796c8dcSSimon Schubert 	    phdr_included = TRUE;
57565796c8dcSSimon Schubert 	}
57575796c8dcSSimon Schubert 
57585796c8dcSSimon Schubert       if (section_count == 0)
57595796c8dcSSimon Schubert 	{
57605796c8dcSSimon Schubert 	  /* Special segments, such as the PT_PHDR segment, may contain
57615796c8dcSSimon Schubert 	     no sections, but ordinary, loadable segments should contain
57625796c8dcSSimon Schubert 	     something.  They are allowed by the ELF spec however, so only
57635796c8dcSSimon Schubert 	     a warning is produced.  */
57645796c8dcSSimon Schubert 	  if (segment->p_type == PT_LOAD)
57655796c8dcSSimon Schubert 	    (*_bfd_error_handler) (_("%B: warning: Empty loadable segment"
57665796c8dcSSimon Schubert 				     " detected, is this intentional ?\n"),
57675796c8dcSSimon Schubert 				   ibfd);
57685796c8dcSSimon Schubert 
57695796c8dcSSimon Schubert 	  map->count = 0;
57705796c8dcSSimon Schubert 	  *pointer_to_map = map;
57715796c8dcSSimon Schubert 	  pointer_to_map = &map->next;
57725796c8dcSSimon Schubert 
57735796c8dcSSimon Schubert 	  continue;
57745796c8dcSSimon Schubert 	}
57755796c8dcSSimon Schubert 
57765796c8dcSSimon Schubert       /* Now scan the sections in the input BFD again and attempt
57775796c8dcSSimon Schubert 	 to add their corresponding output sections to the segment map.
57785796c8dcSSimon Schubert 	 The problem here is how to handle an output section which has
57795796c8dcSSimon Schubert 	 been moved (ie had its LMA changed).  There are four possibilities:
57805796c8dcSSimon Schubert 
57815796c8dcSSimon Schubert 	 1. None of the sections have been moved.
57825796c8dcSSimon Schubert 	    In this case we can continue to use the segment LMA from the
57835796c8dcSSimon Schubert 	    input BFD.
57845796c8dcSSimon Schubert 
57855796c8dcSSimon Schubert 	 2. All of the sections have been moved by the same amount.
57865796c8dcSSimon Schubert 	    In this case we can change the segment's LMA to match the LMA
57875796c8dcSSimon Schubert 	    of the first section.
57885796c8dcSSimon Schubert 
57895796c8dcSSimon Schubert 	 3. Some of the sections have been moved, others have not.
57905796c8dcSSimon Schubert 	    In this case those sections which have not been moved can be
57915796c8dcSSimon Schubert 	    placed in the current segment which will have to have its size,
57925796c8dcSSimon Schubert 	    and possibly its LMA changed, and a new segment or segments will
57935796c8dcSSimon Schubert 	    have to be created to contain the other sections.
57945796c8dcSSimon Schubert 
57955796c8dcSSimon Schubert 	 4. The sections have been moved, but not by the same amount.
57965796c8dcSSimon Schubert 	    In this case we can change the segment's LMA to match the LMA
57975796c8dcSSimon Schubert 	    of the first section and we will have to create a new segment
57985796c8dcSSimon Schubert 	    or segments to contain the other sections.
57995796c8dcSSimon Schubert 
58005796c8dcSSimon Schubert 	 In order to save time, we allocate an array to hold the section
58015796c8dcSSimon Schubert 	 pointers that we are interested in.  As these sections get assigned
58025796c8dcSSimon Schubert 	 to a segment, they are removed from this array.  */
58035796c8dcSSimon Schubert 
58045796c8dcSSimon Schubert       sections = (asection **) bfd_malloc2 (section_count, sizeof (asection *));
58055796c8dcSSimon Schubert       if (sections == NULL)
58065796c8dcSSimon Schubert 	return FALSE;
58075796c8dcSSimon Schubert 
58085796c8dcSSimon Schubert       /* Step One: Scan for segment vs section LMA conflicts.
58095796c8dcSSimon Schubert 	 Also add the sections to the section array allocated above.
58105796c8dcSSimon Schubert 	 Also add the sections to the current segment.  In the common
58115796c8dcSSimon Schubert 	 case, where the sections have not been moved, this means that
58125796c8dcSSimon Schubert 	 we have completely filled the segment, and there is nothing
58135796c8dcSSimon Schubert 	 more to do.  */
58145796c8dcSSimon Schubert       isec = 0;
58155796c8dcSSimon Schubert       matching_lma = 0;
58165796c8dcSSimon Schubert       suggested_lma = 0;
58175796c8dcSSimon Schubert       first_matching_lma = TRUE;
58185796c8dcSSimon Schubert       first_suggested_lma = TRUE;
58195796c8dcSSimon Schubert 
58205796c8dcSSimon Schubert       for (section = ibfd->sections;
58215796c8dcSSimon Schubert 	   section != NULL;
58225796c8dcSSimon Schubert 	   section = section->next)
58235796c8dcSSimon Schubert 	if (section == first_section)
58245796c8dcSSimon Schubert 	  break;
58255796c8dcSSimon Schubert 
58265796c8dcSSimon Schubert       for (j = 0; section != NULL; section = section->next)
58275796c8dcSSimon Schubert 	{
58285796c8dcSSimon Schubert 	  if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
58295796c8dcSSimon Schubert 	    {
58305796c8dcSSimon Schubert 	      output_section = section->output_section;
58315796c8dcSSimon Schubert 
58325796c8dcSSimon Schubert 	      sections[j++] = section;
58335796c8dcSSimon Schubert 
58345796c8dcSSimon Schubert 	      /* The Solaris native linker always sets p_paddr to 0.
58355796c8dcSSimon Schubert 		 We try to catch that case here, and set it to the
58365796c8dcSSimon Schubert 		 correct value.  Note - some backends require that
58375796c8dcSSimon Schubert 		 p_paddr be left as zero.  */
58385796c8dcSSimon Schubert 	      if (!p_paddr_valid
58395796c8dcSSimon Schubert 		  && segment->p_vaddr != 0
58405796c8dcSSimon Schubert 		  && !bed->want_p_paddr_set_to_zero
58415796c8dcSSimon Schubert 		  && isec == 0
58425796c8dcSSimon Schubert 		  && output_section->lma != 0
58435796c8dcSSimon Schubert 		  && output_section->vma == (segment->p_vaddr
58445796c8dcSSimon Schubert 					     + (map->includes_filehdr
58455796c8dcSSimon Schubert 						? iehdr->e_ehsize
58465796c8dcSSimon Schubert 						: 0)
58475796c8dcSSimon Schubert 					     + (map->includes_phdrs
58485796c8dcSSimon Schubert 						? (iehdr->e_phnum
58495796c8dcSSimon Schubert 						   * iehdr->e_phentsize)
58505796c8dcSSimon Schubert 						: 0)))
58515796c8dcSSimon Schubert 		map->p_paddr = segment->p_vaddr;
58525796c8dcSSimon Schubert 
58535796c8dcSSimon Schubert 	      /* Match up the physical address of the segment with the
58545796c8dcSSimon Schubert 		 LMA address of the output section.  */
58555796c8dcSSimon Schubert 	      if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
58565796c8dcSSimon Schubert 		  || IS_COREFILE_NOTE (segment, section)
58575796c8dcSSimon Schubert 		  || (bed->want_p_paddr_set_to_zero
58585796c8dcSSimon Schubert 		      && IS_CONTAINED_BY_VMA (output_section, segment)))
58595796c8dcSSimon Schubert 		{
58605796c8dcSSimon Schubert 		  if (first_matching_lma || output_section->lma < matching_lma)
58615796c8dcSSimon Schubert 		    {
58625796c8dcSSimon Schubert 		      matching_lma = output_section->lma;
58635796c8dcSSimon Schubert 		      first_matching_lma = FALSE;
58645796c8dcSSimon Schubert 		    }
58655796c8dcSSimon Schubert 
58665796c8dcSSimon Schubert 		  /* We assume that if the section fits within the segment
58675796c8dcSSimon Schubert 		     then it does not overlap any other section within that
58685796c8dcSSimon Schubert 		     segment.  */
58695796c8dcSSimon Schubert 		  map->sections[isec++] = output_section;
58705796c8dcSSimon Schubert 		}
58715796c8dcSSimon Schubert 	      else if (first_suggested_lma)
58725796c8dcSSimon Schubert 		{
58735796c8dcSSimon Schubert 		  suggested_lma = output_section->lma;
58745796c8dcSSimon Schubert 		  first_suggested_lma = FALSE;
58755796c8dcSSimon Schubert 		}
58765796c8dcSSimon Schubert 
58775796c8dcSSimon Schubert 	      if (j == section_count)
58785796c8dcSSimon Schubert 		break;
58795796c8dcSSimon Schubert 	    }
58805796c8dcSSimon Schubert 	}
58815796c8dcSSimon Schubert 
58825796c8dcSSimon Schubert       BFD_ASSERT (j == section_count);
58835796c8dcSSimon Schubert 
58845796c8dcSSimon Schubert       /* Step Two: Adjust the physical address of the current segment,
58855796c8dcSSimon Schubert 	 if necessary.  */
58865796c8dcSSimon Schubert       if (isec == section_count)
58875796c8dcSSimon Schubert 	{
58885796c8dcSSimon Schubert 	  /* All of the sections fitted within the segment as currently
58895796c8dcSSimon Schubert 	     specified.  This is the default case.  Add the segment to
58905796c8dcSSimon Schubert 	     the list of built segments and carry on to process the next
58915796c8dcSSimon Schubert 	     program header in the input BFD.  */
58925796c8dcSSimon Schubert 	  map->count = section_count;
58935796c8dcSSimon Schubert 	  *pointer_to_map = map;
58945796c8dcSSimon Schubert 	  pointer_to_map = &map->next;
58955796c8dcSSimon Schubert 
58965796c8dcSSimon Schubert 	  if (p_paddr_valid
58975796c8dcSSimon Schubert 	      && !bed->want_p_paddr_set_to_zero
58985796c8dcSSimon Schubert 	      && matching_lma != map->p_paddr
58995796c8dcSSimon Schubert 	      && !map->includes_filehdr
59005796c8dcSSimon Schubert 	      && !map->includes_phdrs)
59015796c8dcSSimon Schubert 	    /* There is some padding before the first section in the
59025796c8dcSSimon Schubert 	       segment.  So, we must account for that in the output
59035796c8dcSSimon Schubert 	       segment's vma.  */
59045796c8dcSSimon Schubert 	    map->p_vaddr_offset = matching_lma - map->p_paddr;
59055796c8dcSSimon Schubert 
59065796c8dcSSimon Schubert 	  free (sections);
59075796c8dcSSimon Schubert 	  continue;
59085796c8dcSSimon Schubert 	}
59095796c8dcSSimon Schubert       else
59105796c8dcSSimon Schubert 	{
59115796c8dcSSimon Schubert 	  if (!first_matching_lma)
59125796c8dcSSimon Schubert 	    {
59135796c8dcSSimon Schubert 	      /* At least one section fits inside the current segment.
59145796c8dcSSimon Schubert 		 Keep it, but modify its physical address to match the
59155796c8dcSSimon Schubert 		 LMA of the first section that fitted.  */
59165796c8dcSSimon Schubert 	      map->p_paddr = matching_lma;
59175796c8dcSSimon Schubert 	    }
59185796c8dcSSimon Schubert 	  else
59195796c8dcSSimon Schubert 	    {
59205796c8dcSSimon Schubert 	      /* None of the sections fitted inside the current segment.
59215796c8dcSSimon Schubert 		 Change the current segment's physical address to match
59225796c8dcSSimon Schubert 		 the LMA of the first section.  */
59235796c8dcSSimon Schubert 	      map->p_paddr = suggested_lma;
59245796c8dcSSimon Schubert 	    }
59255796c8dcSSimon Schubert 
59265796c8dcSSimon Schubert 	  /* Offset the segment physical address from the lma
59275796c8dcSSimon Schubert 	     to allow for space taken up by elf headers.  */
59285796c8dcSSimon Schubert 	  if (map->includes_filehdr)
59295796c8dcSSimon Schubert 	    {
59305796c8dcSSimon Schubert 	      if (map->p_paddr >= iehdr->e_ehsize)
59315796c8dcSSimon Schubert 		map->p_paddr -= iehdr->e_ehsize;
59325796c8dcSSimon Schubert 	      else
59335796c8dcSSimon Schubert 		{
59345796c8dcSSimon Schubert 		  map->includes_filehdr = FALSE;
59355796c8dcSSimon Schubert 		  map->includes_phdrs = FALSE;
59365796c8dcSSimon Schubert 		}
59375796c8dcSSimon Schubert 	    }
59385796c8dcSSimon Schubert 
59395796c8dcSSimon Schubert 	  if (map->includes_phdrs)
59405796c8dcSSimon Schubert 	    {
59415796c8dcSSimon Schubert 	      if (map->p_paddr >= iehdr->e_phnum * iehdr->e_phentsize)
59425796c8dcSSimon Schubert 		{
59435796c8dcSSimon Schubert 		  map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
59445796c8dcSSimon Schubert 
59455796c8dcSSimon Schubert 		  /* iehdr->e_phnum is just an estimate of the number
59465796c8dcSSimon Schubert 		     of program headers that we will need.  Make a note
59475796c8dcSSimon Schubert 		     here of the number we used and the segment we chose
59485796c8dcSSimon Schubert 		     to hold these headers, so that we can adjust the
59495796c8dcSSimon Schubert 		     offset when we know the correct value.  */
59505796c8dcSSimon Schubert 		  phdr_adjust_num = iehdr->e_phnum;
59515796c8dcSSimon Schubert 		  phdr_adjust_seg = map;
59525796c8dcSSimon Schubert 		}
59535796c8dcSSimon Schubert 	      else
59545796c8dcSSimon Schubert 		map->includes_phdrs = FALSE;
59555796c8dcSSimon Schubert 	    }
59565796c8dcSSimon Schubert 	}
59575796c8dcSSimon Schubert 
59585796c8dcSSimon Schubert       /* Step Three: Loop over the sections again, this time assigning
59595796c8dcSSimon Schubert 	 those that fit to the current segment and removing them from the
59605796c8dcSSimon Schubert 	 sections array; but making sure not to leave large gaps.  Once all
59615796c8dcSSimon Schubert 	 possible sections have been assigned to the current segment it is
59625796c8dcSSimon Schubert 	 added to the list of built segments and if sections still remain
59635796c8dcSSimon Schubert 	 to be assigned, a new segment is constructed before repeating
59645796c8dcSSimon Schubert 	 the loop.  */
59655796c8dcSSimon Schubert       isec = 0;
59665796c8dcSSimon Schubert       do
59675796c8dcSSimon Schubert 	{
59685796c8dcSSimon Schubert 	  map->count = 0;
59695796c8dcSSimon Schubert 	  suggested_lma = 0;
59705796c8dcSSimon Schubert 	  first_suggested_lma = TRUE;
59715796c8dcSSimon Schubert 
59725796c8dcSSimon Schubert 	  /* Fill the current segment with sections that fit.  */
59735796c8dcSSimon Schubert 	  for (j = 0; j < section_count; j++)
59745796c8dcSSimon Schubert 	    {
59755796c8dcSSimon Schubert 	      section = sections[j];
59765796c8dcSSimon Schubert 
59775796c8dcSSimon Schubert 	      if (section == NULL)
59785796c8dcSSimon Schubert 		continue;
59795796c8dcSSimon Schubert 
59805796c8dcSSimon Schubert 	      output_section = section->output_section;
59815796c8dcSSimon Schubert 
59825796c8dcSSimon Schubert 	      BFD_ASSERT (output_section != NULL);
59835796c8dcSSimon Schubert 
59845796c8dcSSimon Schubert 	      if (IS_CONTAINED_BY_LMA (output_section, segment, map->p_paddr)
59855796c8dcSSimon Schubert 		  || IS_COREFILE_NOTE (segment, section))
59865796c8dcSSimon Schubert 		{
59875796c8dcSSimon Schubert 		  if (map->count == 0)
59885796c8dcSSimon Schubert 		    {
59895796c8dcSSimon Schubert 		      /* If the first section in a segment does not start at
59905796c8dcSSimon Schubert 			 the beginning of the segment, then something is
59915796c8dcSSimon Schubert 			 wrong.  */
59925796c8dcSSimon Schubert 		      if (output_section->lma
59935796c8dcSSimon Schubert 			  != (map->p_paddr
59945796c8dcSSimon Schubert 			      + (map->includes_filehdr ? iehdr->e_ehsize : 0)
59955796c8dcSSimon Schubert 			      + (map->includes_phdrs
59965796c8dcSSimon Schubert 				 ? iehdr->e_phnum * iehdr->e_phentsize
59975796c8dcSSimon Schubert 				 : 0)))
59985796c8dcSSimon Schubert 			abort ();
59995796c8dcSSimon Schubert 		    }
60005796c8dcSSimon Schubert 		  else
60015796c8dcSSimon Schubert 		    {
60025796c8dcSSimon Schubert 		      asection *prev_sec;
60035796c8dcSSimon Schubert 
60045796c8dcSSimon Schubert 		      prev_sec = map->sections[map->count - 1];
60055796c8dcSSimon Schubert 
60065796c8dcSSimon Schubert 		      /* If the gap between the end of the previous section
60075796c8dcSSimon Schubert 			 and the start of this section is more than
60085796c8dcSSimon Schubert 			 maxpagesize then we need to start a new segment.  */
60095796c8dcSSimon Schubert 		      if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
60105796c8dcSSimon Schubert 				      maxpagesize)
60115796c8dcSSimon Schubert 			   < BFD_ALIGN (output_section->lma, maxpagesize))
60125796c8dcSSimon Schubert 			  || (prev_sec->lma + prev_sec->size
60135796c8dcSSimon Schubert 			      > output_section->lma))
60145796c8dcSSimon Schubert 			{
60155796c8dcSSimon Schubert 			  if (first_suggested_lma)
60165796c8dcSSimon Schubert 			    {
60175796c8dcSSimon Schubert 			      suggested_lma = output_section->lma;
60185796c8dcSSimon Schubert 			      first_suggested_lma = FALSE;
60195796c8dcSSimon Schubert 			    }
60205796c8dcSSimon Schubert 
60215796c8dcSSimon Schubert 			  continue;
60225796c8dcSSimon Schubert 			}
60235796c8dcSSimon Schubert 		    }
60245796c8dcSSimon Schubert 
60255796c8dcSSimon Schubert 		  map->sections[map->count++] = output_section;
60265796c8dcSSimon Schubert 		  ++isec;
60275796c8dcSSimon Schubert 		  sections[j] = NULL;
60285796c8dcSSimon Schubert 		  section->segment_mark = TRUE;
60295796c8dcSSimon Schubert 		}
60305796c8dcSSimon Schubert 	      else if (first_suggested_lma)
60315796c8dcSSimon Schubert 		{
60325796c8dcSSimon Schubert 		  suggested_lma = output_section->lma;
60335796c8dcSSimon Schubert 		  first_suggested_lma = FALSE;
60345796c8dcSSimon Schubert 		}
60355796c8dcSSimon Schubert 	    }
60365796c8dcSSimon Schubert 
60375796c8dcSSimon Schubert 	  BFD_ASSERT (map->count > 0);
60385796c8dcSSimon Schubert 
60395796c8dcSSimon Schubert 	  /* Add the current segment to the list of built segments.  */
60405796c8dcSSimon Schubert 	  *pointer_to_map = map;
60415796c8dcSSimon Schubert 	  pointer_to_map = &map->next;
60425796c8dcSSimon Schubert 
60435796c8dcSSimon Schubert 	  if (isec < section_count)
60445796c8dcSSimon Schubert 	    {
60455796c8dcSSimon Schubert 	      /* We still have not allocated all of the sections to
60465796c8dcSSimon Schubert 		 segments.  Create a new segment here, initialise it
60475796c8dcSSimon Schubert 		 and carry on looping.  */
60485796c8dcSSimon Schubert 	      amt = sizeof (struct elf_segment_map);
60495796c8dcSSimon Schubert 	      amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
6050*ef5ccd6cSJohn Marino 	      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
60515796c8dcSSimon Schubert 	      if (map == NULL)
60525796c8dcSSimon Schubert 		{
60535796c8dcSSimon Schubert 		  free (sections);
60545796c8dcSSimon Schubert 		  return FALSE;
60555796c8dcSSimon Schubert 		}
60565796c8dcSSimon Schubert 
60575796c8dcSSimon Schubert 	      /* Initialise the fields of the segment map.  Set the physical
60585796c8dcSSimon Schubert 		 physical address to the LMA of the first section that has
60595796c8dcSSimon Schubert 		 not yet been assigned.  */
60605796c8dcSSimon Schubert 	      map->next = NULL;
60615796c8dcSSimon Schubert 	      map->p_type = segment->p_type;
60625796c8dcSSimon Schubert 	      map->p_flags = segment->p_flags;
60635796c8dcSSimon Schubert 	      map->p_flags_valid = 1;
60645796c8dcSSimon Schubert 	      map->p_paddr = suggested_lma;
60655796c8dcSSimon Schubert 	      map->p_paddr_valid = p_paddr_valid;
60665796c8dcSSimon Schubert 	      map->includes_filehdr = 0;
60675796c8dcSSimon Schubert 	      map->includes_phdrs = 0;
60685796c8dcSSimon Schubert 	    }
60695796c8dcSSimon Schubert 	}
60705796c8dcSSimon Schubert       while (isec < section_count);
60715796c8dcSSimon Schubert 
60725796c8dcSSimon Schubert       free (sections);
60735796c8dcSSimon Schubert     }
60745796c8dcSSimon Schubert 
6075*ef5ccd6cSJohn Marino   elf_seg_map (obfd) = map_first;
60765796c8dcSSimon Schubert 
60775796c8dcSSimon Schubert   /* If we had to estimate the number of program headers that were
60785796c8dcSSimon Schubert      going to be needed, then check our estimate now and adjust
60795796c8dcSSimon Schubert      the offset if necessary.  */
60805796c8dcSSimon Schubert   if (phdr_adjust_seg != NULL)
60815796c8dcSSimon Schubert     {
60825796c8dcSSimon Schubert       unsigned int count;
60835796c8dcSSimon Schubert 
60845796c8dcSSimon Schubert       for (count = 0, map = map_first; map != NULL; map = map->next)
60855796c8dcSSimon Schubert 	count++;
60865796c8dcSSimon Schubert 
60875796c8dcSSimon Schubert       if (count > phdr_adjust_num)
60885796c8dcSSimon Schubert 	phdr_adjust_seg->p_paddr
60895796c8dcSSimon Schubert 	  -= (count - phdr_adjust_num) * iehdr->e_phentsize;
60905796c8dcSSimon Schubert     }
60915796c8dcSSimon Schubert 
60925796c8dcSSimon Schubert #undef SEGMENT_END
60935796c8dcSSimon Schubert #undef SECTION_SIZE
60945796c8dcSSimon Schubert #undef IS_CONTAINED_BY_VMA
60955796c8dcSSimon Schubert #undef IS_CONTAINED_BY_LMA
60965796c8dcSSimon Schubert #undef IS_NOTE
60975796c8dcSSimon Schubert #undef IS_COREFILE_NOTE
60985796c8dcSSimon Schubert #undef IS_SOLARIS_PT_INTERP
60995796c8dcSSimon Schubert #undef IS_SECTION_IN_INPUT_SEGMENT
61005796c8dcSSimon Schubert #undef INCLUDE_SECTION_IN_SEGMENT
61015796c8dcSSimon Schubert #undef SEGMENT_AFTER_SEGMENT
61025796c8dcSSimon Schubert #undef SEGMENT_OVERLAPS
61035796c8dcSSimon Schubert   return TRUE;
61045796c8dcSSimon Schubert }
61055796c8dcSSimon Schubert 
61065796c8dcSSimon Schubert /* Copy ELF program header information.  */
61075796c8dcSSimon Schubert 
61085796c8dcSSimon Schubert static bfd_boolean
copy_elf_program_header(bfd * ibfd,bfd * obfd)61095796c8dcSSimon Schubert copy_elf_program_header (bfd *ibfd, bfd *obfd)
61105796c8dcSSimon Schubert {
61115796c8dcSSimon Schubert   Elf_Internal_Ehdr *iehdr;
61125796c8dcSSimon Schubert   struct elf_segment_map *map;
61135796c8dcSSimon Schubert   struct elf_segment_map *map_first;
61145796c8dcSSimon Schubert   struct elf_segment_map **pointer_to_map;
61155796c8dcSSimon Schubert   Elf_Internal_Phdr *segment;
61165796c8dcSSimon Schubert   unsigned int i;
61175796c8dcSSimon Schubert   unsigned int num_segments;
61185796c8dcSSimon Schubert   bfd_boolean phdr_included = FALSE;
61195796c8dcSSimon Schubert   bfd_boolean p_paddr_valid;
61205796c8dcSSimon Schubert 
61215796c8dcSSimon Schubert   iehdr = elf_elfheader (ibfd);
61225796c8dcSSimon Schubert 
61235796c8dcSSimon Schubert   map_first = NULL;
61245796c8dcSSimon Schubert   pointer_to_map = &map_first;
61255796c8dcSSimon Schubert 
61265796c8dcSSimon Schubert   /* If all the segment p_paddr fields are zero, don't set
61275796c8dcSSimon Schubert      map->p_paddr_valid.  */
61285796c8dcSSimon Schubert   p_paddr_valid = FALSE;
61295796c8dcSSimon Schubert   num_segments = elf_elfheader (ibfd)->e_phnum;
61305796c8dcSSimon Schubert   for (i = 0, segment = elf_tdata (ibfd)->phdr;
61315796c8dcSSimon Schubert        i < num_segments;
61325796c8dcSSimon Schubert        i++, segment++)
61335796c8dcSSimon Schubert     if (segment->p_paddr != 0)
61345796c8dcSSimon Schubert       {
61355796c8dcSSimon Schubert 	p_paddr_valid = TRUE;
61365796c8dcSSimon Schubert 	break;
61375796c8dcSSimon Schubert       }
61385796c8dcSSimon Schubert 
61395796c8dcSSimon Schubert   for (i = 0, segment = elf_tdata (ibfd)->phdr;
61405796c8dcSSimon Schubert        i < num_segments;
61415796c8dcSSimon Schubert        i++, segment++)
61425796c8dcSSimon Schubert     {
61435796c8dcSSimon Schubert       asection *section;
61445796c8dcSSimon Schubert       unsigned int section_count;
61455796c8dcSSimon Schubert       bfd_size_type amt;
61465796c8dcSSimon Schubert       Elf_Internal_Shdr *this_hdr;
61475796c8dcSSimon Schubert       asection *first_section = NULL;
6148c50c785cSJohn Marino       asection *lowest_section;
61495796c8dcSSimon Schubert 
61505796c8dcSSimon Schubert       /* Compute how many sections are in this segment.  */
61515796c8dcSSimon Schubert       for (section = ibfd->sections, section_count = 0;
61525796c8dcSSimon Schubert 	   section != NULL;
61535796c8dcSSimon Schubert 	   section = section->next)
61545796c8dcSSimon Schubert 	{
61555796c8dcSSimon Schubert 	  this_hdr = &(elf_section_data(section)->this_hdr);
6156c50c785cSJohn Marino 	  if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
61575796c8dcSSimon Schubert 	    {
6158c50c785cSJohn Marino 	      if (first_section == NULL)
6159c50c785cSJohn Marino 		first_section = section;
61605796c8dcSSimon Schubert 	      section_count++;
61615796c8dcSSimon Schubert 	    }
61625796c8dcSSimon Schubert 	}
61635796c8dcSSimon Schubert 
61645796c8dcSSimon Schubert       /* Allocate a segment map big enough to contain
61655796c8dcSSimon Schubert 	 all of the sections we have selected.  */
61665796c8dcSSimon Schubert       amt = sizeof (struct elf_segment_map);
61675796c8dcSSimon Schubert       if (section_count != 0)
61685796c8dcSSimon Schubert 	amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
61695796c8dcSSimon Schubert       map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
61705796c8dcSSimon Schubert       if (map == NULL)
61715796c8dcSSimon Schubert 	return FALSE;
61725796c8dcSSimon Schubert 
61735796c8dcSSimon Schubert       /* Initialize the fields of the output segment map with the
61745796c8dcSSimon Schubert 	 input segment.  */
61755796c8dcSSimon Schubert       map->next = NULL;
61765796c8dcSSimon Schubert       map->p_type = segment->p_type;
61775796c8dcSSimon Schubert       map->p_flags = segment->p_flags;
61785796c8dcSSimon Schubert       map->p_flags_valid = 1;
61795796c8dcSSimon Schubert       map->p_paddr = segment->p_paddr;
61805796c8dcSSimon Schubert       map->p_paddr_valid = p_paddr_valid;
61815796c8dcSSimon Schubert       map->p_align = segment->p_align;
61825796c8dcSSimon Schubert       map->p_align_valid = 1;
61835796c8dcSSimon Schubert       map->p_vaddr_offset = 0;
61845796c8dcSSimon Schubert 
6185*ef5ccd6cSJohn Marino       if (map->p_type == PT_GNU_RELRO
6186*ef5ccd6cSJohn Marino 	  || map->p_type == PT_GNU_STACK)
61875796c8dcSSimon Schubert 	{
61885796c8dcSSimon Schubert 	  /* The PT_GNU_RELRO segment may contain the first a few
61895796c8dcSSimon Schubert 	     bytes in the .got.plt section even if the whole .got.plt
61905796c8dcSSimon Schubert 	     section isn't in the PT_GNU_RELRO segment.  We won't
6191*ef5ccd6cSJohn Marino 	     change the size of the PT_GNU_RELRO segment.
6192*ef5ccd6cSJohn Marino 	     Similarly, PT_GNU_STACK size is significant on uclinux
6193*ef5ccd6cSJohn Marino 	     systems.    */
61945796c8dcSSimon Schubert 	  map->p_size = segment->p_memsz;
61955796c8dcSSimon Schubert 	  map->p_size_valid = 1;
61965796c8dcSSimon Schubert 	}
61975796c8dcSSimon Schubert 
61985796c8dcSSimon Schubert       /* Determine if this segment contains the ELF file header
61995796c8dcSSimon Schubert 	 and if it contains the program headers themselves.  */
62005796c8dcSSimon Schubert       map->includes_filehdr = (segment->p_offset == 0
62015796c8dcSSimon Schubert 			       && segment->p_filesz >= iehdr->e_ehsize);
62025796c8dcSSimon Schubert 
62035796c8dcSSimon Schubert       map->includes_phdrs = 0;
62045796c8dcSSimon Schubert       if (! phdr_included || segment->p_type != PT_LOAD)
62055796c8dcSSimon Schubert 	{
62065796c8dcSSimon Schubert 	  map->includes_phdrs =
62075796c8dcSSimon Schubert 	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
62085796c8dcSSimon Schubert 	     && (segment->p_offset + segment->p_filesz
62095796c8dcSSimon Schubert 		 >= ((bfd_vma) iehdr->e_phoff
62105796c8dcSSimon Schubert 		     + iehdr->e_phnum * iehdr->e_phentsize)));
62115796c8dcSSimon Schubert 
62125796c8dcSSimon Schubert 	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
62135796c8dcSSimon Schubert 	    phdr_included = TRUE;
62145796c8dcSSimon Schubert 	}
62155796c8dcSSimon Schubert 
6216c50c785cSJohn Marino       lowest_section = first_section;
62175796c8dcSSimon Schubert       if (section_count != 0)
62185796c8dcSSimon Schubert 	{
62195796c8dcSSimon Schubert 	  unsigned int isec = 0;
62205796c8dcSSimon Schubert 
62215796c8dcSSimon Schubert 	  for (section = first_section;
62225796c8dcSSimon Schubert 	       section != NULL;
62235796c8dcSSimon Schubert 	       section = section->next)
62245796c8dcSSimon Schubert 	    {
62255796c8dcSSimon Schubert 	      this_hdr = &(elf_section_data(section)->this_hdr);
6226c50c785cSJohn Marino 	      if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
62275796c8dcSSimon Schubert 		{
62285796c8dcSSimon Schubert 		  map->sections[isec++] = section->output_section;
6229c50c785cSJohn Marino 		  if (section->lma < lowest_section->lma)
6230c50c785cSJohn Marino 		    lowest_section = section;
6231c50c785cSJohn Marino 		  if ((section->flags & SEC_ALLOC) != 0)
6232c50c785cSJohn Marino 		    {
6233c50c785cSJohn Marino 		      bfd_vma seg_off;
6234c50c785cSJohn Marino 
6235c50c785cSJohn Marino 		      /* Section lmas are set up from PT_LOAD header
6236c50c785cSJohn Marino 			 p_paddr in _bfd_elf_make_section_from_shdr.
6237c50c785cSJohn Marino 			 If this header has a p_paddr that disagrees
6238c50c785cSJohn Marino 			 with the section lma, flag the p_paddr as
6239c50c785cSJohn Marino 			 invalid.  */
6240c50c785cSJohn Marino 		      if ((section->flags & SEC_LOAD) != 0)
6241c50c785cSJohn Marino 			seg_off = this_hdr->sh_offset - segment->p_offset;
6242c50c785cSJohn Marino 		      else
6243c50c785cSJohn Marino 			seg_off = this_hdr->sh_addr - segment->p_vaddr;
6244c50c785cSJohn Marino 		      if (section->lma - segment->p_paddr != seg_off)
6245c50c785cSJohn Marino 			map->p_paddr_valid = FALSE;
6246c50c785cSJohn Marino 		    }
62475796c8dcSSimon Schubert 		  if (isec == section_count)
62485796c8dcSSimon Schubert 		    break;
62495796c8dcSSimon Schubert 		}
62505796c8dcSSimon Schubert 	    }
62515796c8dcSSimon Schubert 	}
62525796c8dcSSimon Schubert 
6253c50c785cSJohn Marino       if (map->includes_filehdr && lowest_section != NULL)
6254c50c785cSJohn Marino 	/* We need to keep the space used by the headers fixed.  */
6255c50c785cSJohn Marino 	map->header_size = lowest_section->vma - segment->p_vaddr;
6256c50c785cSJohn Marino 
6257c50c785cSJohn Marino       if (!map->includes_phdrs
6258c50c785cSJohn Marino 	  && !map->includes_filehdr
6259c50c785cSJohn Marino 	  && map->p_paddr_valid)
6260c50c785cSJohn Marino 	/* There is some other padding before the first section.  */
6261c50c785cSJohn Marino 	map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
6262c50c785cSJohn Marino 			       - segment->p_paddr);
6263c50c785cSJohn Marino 
62645796c8dcSSimon Schubert       map->count = section_count;
62655796c8dcSSimon Schubert       *pointer_to_map = map;
62665796c8dcSSimon Schubert       pointer_to_map = &map->next;
62675796c8dcSSimon Schubert     }
62685796c8dcSSimon Schubert 
6269*ef5ccd6cSJohn Marino   elf_seg_map (obfd) = map_first;
62705796c8dcSSimon Schubert   return TRUE;
62715796c8dcSSimon Schubert }
62725796c8dcSSimon Schubert 
62735796c8dcSSimon Schubert /* Copy private BFD data.  This copies or rewrites ELF program header
62745796c8dcSSimon Schubert    information.  */
62755796c8dcSSimon Schubert 
62765796c8dcSSimon Schubert static bfd_boolean
copy_private_bfd_data(bfd * ibfd,bfd * obfd)62775796c8dcSSimon Schubert copy_private_bfd_data (bfd *ibfd, bfd *obfd)
62785796c8dcSSimon Schubert {
62795796c8dcSSimon Schubert   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
62805796c8dcSSimon Schubert       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
62815796c8dcSSimon Schubert     return TRUE;
62825796c8dcSSimon Schubert 
62835796c8dcSSimon Schubert   if (elf_tdata (ibfd)->phdr == NULL)
62845796c8dcSSimon Schubert     return TRUE;
62855796c8dcSSimon Schubert 
62865796c8dcSSimon Schubert   if (ibfd->xvec == obfd->xvec)
62875796c8dcSSimon Schubert     {
62885796c8dcSSimon Schubert       /* Check to see if any sections in the input BFD
62895796c8dcSSimon Schubert 	 covered by ELF program header have changed.  */
62905796c8dcSSimon Schubert       Elf_Internal_Phdr *segment;
62915796c8dcSSimon Schubert       asection *section, *osec;
62925796c8dcSSimon Schubert       unsigned int i, num_segments;
62935796c8dcSSimon Schubert       Elf_Internal_Shdr *this_hdr;
62945796c8dcSSimon Schubert       const struct elf_backend_data *bed;
62955796c8dcSSimon Schubert 
62965796c8dcSSimon Schubert       bed = get_elf_backend_data (ibfd);
62975796c8dcSSimon Schubert 
62985796c8dcSSimon Schubert       /* Regenerate the segment map if p_paddr is set to 0.  */
62995796c8dcSSimon Schubert       if (bed->want_p_paddr_set_to_zero)
63005796c8dcSSimon Schubert 	goto rewrite;
63015796c8dcSSimon Schubert 
63025796c8dcSSimon Schubert       /* Initialize the segment mark field.  */
63035796c8dcSSimon Schubert       for (section = obfd->sections; section != NULL;
63045796c8dcSSimon Schubert 	   section = section->next)
63055796c8dcSSimon Schubert 	section->segment_mark = FALSE;
63065796c8dcSSimon Schubert 
63075796c8dcSSimon Schubert       num_segments = elf_elfheader (ibfd)->e_phnum;
63085796c8dcSSimon Schubert       for (i = 0, segment = elf_tdata (ibfd)->phdr;
63095796c8dcSSimon Schubert 	   i < num_segments;
63105796c8dcSSimon Schubert 	   i++, segment++)
63115796c8dcSSimon Schubert 	{
63125796c8dcSSimon Schubert 	  /* PR binutils/3535.  The Solaris linker always sets the p_paddr
63135796c8dcSSimon Schubert 	     and p_memsz fields of special segments (DYNAMIC, INTERP) to 0
63145796c8dcSSimon Schubert 	     which severly confuses things, so always regenerate the segment
63155796c8dcSSimon Schubert 	     map in this case.  */
63165796c8dcSSimon Schubert 	  if (segment->p_paddr == 0
63175796c8dcSSimon Schubert 	      && segment->p_memsz == 0
63185796c8dcSSimon Schubert 	      && (segment->p_type == PT_INTERP || segment->p_type == PT_DYNAMIC))
63195796c8dcSSimon Schubert 	    goto rewrite;
63205796c8dcSSimon Schubert 
63215796c8dcSSimon Schubert 	  for (section = ibfd->sections;
63225796c8dcSSimon Schubert 	       section != NULL; section = section->next)
63235796c8dcSSimon Schubert 	    {
63245796c8dcSSimon Schubert 	      /* We mark the output section so that we know it comes
63255796c8dcSSimon Schubert 		 from the input BFD.  */
63265796c8dcSSimon Schubert 	      osec = section->output_section;
63275796c8dcSSimon Schubert 	      if (osec)
63285796c8dcSSimon Schubert 		osec->segment_mark = TRUE;
63295796c8dcSSimon Schubert 
63305796c8dcSSimon Schubert 	      /* Check if this section is covered by the segment.  */
63315796c8dcSSimon Schubert 	      this_hdr = &(elf_section_data(section)->this_hdr);
6332c50c785cSJohn Marino 	      if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
63335796c8dcSSimon Schubert 		{
63345796c8dcSSimon Schubert 		  /* FIXME: Check if its output section is changed or
63355796c8dcSSimon Schubert 		     removed.  What else do we need to check?  */
63365796c8dcSSimon Schubert 		  if (osec == NULL
63375796c8dcSSimon Schubert 		      || section->flags != osec->flags
63385796c8dcSSimon Schubert 		      || section->lma != osec->lma
63395796c8dcSSimon Schubert 		      || section->vma != osec->vma
63405796c8dcSSimon Schubert 		      || section->size != osec->size
63415796c8dcSSimon Schubert 		      || section->rawsize != osec->rawsize
63425796c8dcSSimon Schubert 		      || section->alignment_power != osec->alignment_power)
63435796c8dcSSimon Schubert 		    goto rewrite;
63445796c8dcSSimon Schubert 		}
63455796c8dcSSimon Schubert 	    }
63465796c8dcSSimon Schubert 	}
63475796c8dcSSimon Schubert 
63485796c8dcSSimon Schubert       /* Check to see if any output section do not come from the
63495796c8dcSSimon Schubert 	 input BFD.  */
63505796c8dcSSimon Schubert       for (section = obfd->sections; section != NULL;
63515796c8dcSSimon Schubert 	   section = section->next)
63525796c8dcSSimon Schubert 	{
63535796c8dcSSimon Schubert 	  if (section->segment_mark == FALSE)
63545796c8dcSSimon Schubert 	    goto rewrite;
63555796c8dcSSimon Schubert 	  else
63565796c8dcSSimon Schubert 	    section->segment_mark = FALSE;
63575796c8dcSSimon Schubert 	}
63585796c8dcSSimon Schubert 
63595796c8dcSSimon Schubert       return copy_elf_program_header (ibfd, obfd);
63605796c8dcSSimon Schubert     }
63615796c8dcSSimon Schubert 
63625796c8dcSSimon Schubert rewrite:
6363*ef5ccd6cSJohn Marino   if (ibfd->xvec == obfd->xvec)
6364*ef5ccd6cSJohn Marino     {
6365*ef5ccd6cSJohn Marino       /* When rewriting program header, set the output maxpagesize to
6366*ef5ccd6cSJohn Marino 	 the maximum alignment of input PT_LOAD segments.  */
6367*ef5ccd6cSJohn Marino       Elf_Internal_Phdr *segment;
6368*ef5ccd6cSJohn Marino       unsigned int i;
6369*ef5ccd6cSJohn Marino       unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;
6370*ef5ccd6cSJohn Marino       bfd_vma maxpagesize = 0;
6371*ef5ccd6cSJohn Marino 
6372*ef5ccd6cSJohn Marino       for (i = 0, segment = elf_tdata (ibfd)->phdr;
6373*ef5ccd6cSJohn Marino 	   i < num_segments;
6374*ef5ccd6cSJohn Marino 	   i++, segment++)
6375*ef5ccd6cSJohn Marino 	if (segment->p_type == PT_LOAD
6376*ef5ccd6cSJohn Marino 	    && maxpagesize < segment->p_align)
6377*ef5ccd6cSJohn Marino 	  maxpagesize = segment->p_align;
6378*ef5ccd6cSJohn Marino 
6379*ef5ccd6cSJohn Marino       if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
6380*ef5ccd6cSJohn Marino 	bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
6381*ef5ccd6cSJohn Marino     }
6382*ef5ccd6cSJohn Marino 
63835796c8dcSSimon Schubert   return rewrite_elf_program_header (ibfd, obfd);
63845796c8dcSSimon Schubert }
63855796c8dcSSimon Schubert 
63865796c8dcSSimon Schubert /* Initialize private output section information from input section.  */
63875796c8dcSSimon Schubert 
63885796c8dcSSimon Schubert bfd_boolean
_bfd_elf_init_private_section_data(bfd * ibfd,asection * isec,bfd * obfd,asection * osec,struct bfd_link_info * link_info)63895796c8dcSSimon Schubert _bfd_elf_init_private_section_data (bfd *ibfd,
63905796c8dcSSimon Schubert 				    asection *isec,
63915796c8dcSSimon Schubert 				    bfd *obfd,
63925796c8dcSSimon Schubert 				    asection *osec,
63935796c8dcSSimon Schubert 				    struct bfd_link_info *link_info)
63945796c8dcSSimon Schubert 
63955796c8dcSSimon Schubert {
63965796c8dcSSimon Schubert   Elf_Internal_Shdr *ihdr, *ohdr;
6397cf7f2e2dSJohn Marino   bfd_boolean final_link = link_info != NULL && !link_info->relocatable;
63985796c8dcSSimon Schubert 
63995796c8dcSSimon Schubert   if (ibfd->xvec->flavour != bfd_target_elf_flavour
64005796c8dcSSimon Schubert       || obfd->xvec->flavour != bfd_target_elf_flavour)
64015796c8dcSSimon Schubert     return TRUE;
64025796c8dcSSimon Schubert 
6403a45ae5f8SJohn Marino   BFD_ASSERT (elf_section_data (osec) != NULL);
6404a45ae5f8SJohn Marino 
6405cf7f2e2dSJohn Marino   /* For objcopy and relocatable link, don't copy the output ELF
6406cf7f2e2dSJohn Marino      section type from input if the output BFD section flags have been
6407cf7f2e2dSJohn Marino      set to something different.  For a final link allow some flags
6408cf7f2e2dSJohn Marino      that the linker clears to differ.  */
64095796c8dcSSimon Schubert   if (elf_section_type (osec) == SHT_NULL
6410cf7f2e2dSJohn Marino       && (osec->flags == isec->flags
6411cf7f2e2dSJohn Marino 	  || (final_link
6412cf7f2e2dSJohn Marino 	      && ((osec->flags ^ isec->flags)
6413c50c785cSJohn Marino 		  & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
64145796c8dcSSimon Schubert     elf_section_type (osec) = elf_section_type (isec);
64155796c8dcSSimon Schubert 
64165796c8dcSSimon Schubert   /* FIXME: Is this correct for all OS/PROC specific flags?  */
64175796c8dcSSimon Schubert   elf_section_flags (osec) |= (elf_section_flags (isec)
64185796c8dcSSimon Schubert 			       & (SHF_MASKOS | SHF_MASKPROC));
64195796c8dcSSimon Schubert 
64205796c8dcSSimon Schubert   /* Set things up for objcopy and relocatable link.  The output
64215796c8dcSSimon Schubert      SHT_GROUP section will have its elf_next_in_group pointing back
64225796c8dcSSimon Schubert      to the input group members.  Ignore linker created group section.
64235796c8dcSSimon Schubert      See elfNN_ia64_object_p in elfxx-ia64.c.  */
6424cf7f2e2dSJohn Marino   if (!final_link)
64255796c8dcSSimon Schubert     {
64265796c8dcSSimon Schubert       if (elf_sec_group (isec) == NULL
64275796c8dcSSimon Schubert 	  || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
64285796c8dcSSimon Schubert 	{
64295796c8dcSSimon Schubert 	  if (elf_section_flags (isec) & SHF_GROUP)
64305796c8dcSSimon Schubert 	    elf_section_flags (osec) |= SHF_GROUP;
64315796c8dcSSimon Schubert 	  elf_next_in_group (osec) = elf_next_in_group (isec);
64325796c8dcSSimon Schubert 	  elf_section_data (osec)->group = elf_section_data (isec)->group;
64335796c8dcSSimon Schubert 	}
64345796c8dcSSimon Schubert     }
64355796c8dcSSimon Schubert 
64365796c8dcSSimon Schubert   ihdr = &elf_section_data (isec)->this_hdr;
64375796c8dcSSimon Schubert 
64385796c8dcSSimon Schubert   /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
64395796c8dcSSimon Schubert      don't use the output section of the linked-to section since it
64405796c8dcSSimon Schubert      may be NULL at this point.  */
64415796c8dcSSimon Schubert   if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
64425796c8dcSSimon Schubert     {
64435796c8dcSSimon Schubert       ohdr = &elf_section_data (osec)->this_hdr;
64445796c8dcSSimon Schubert       ohdr->sh_flags |= SHF_LINK_ORDER;
64455796c8dcSSimon Schubert       elf_linked_to_section (osec) = elf_linked_to_section (isec);
64465796c8dcSSimon Schubert     }
64475796c8dcSSimon Schubert 
64485796c8dcSSimon Schubert   osec->use_rela_p = isec->use_rela_p;
64495796c8dcSSimon Schubert 
64505796c8dcSSimon Schubert   return TRUE;
64515796c8dcSSimon Schubert }
64525796c8dcSSimon Schubert 
64535796c8dcSSimon Schubert /* Copy private section information.  This copies over the entsize
64545796c8dcSSimon Schubert    field, and sometimes the info field.  */
64555796c8dcSSimon Schubert 
64565796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_section_data(bfd * ibfd,asection * isec,bfd * obfd,asection * osec)64575796c8dcSSimon Schubert _bfd_elf_copy_private_section_data (bfd *ibfd,
64585796c8dcSSimon Schubert 				    asection *isec,
64595796c8dcSSimon Schubert 				    bfd *obfd,
64605796c8dcSSimon Schubert 				    asection *osec)
64615796c8dcSSimon Schubert {
64625796c8dcSSimon Schubert   Elf_Internal_Shdr *ihdr, *ohdr;
64635796c8dcSSimon Schubert 
64645796c8dcSSimon Schubert   if (ibfd->xvec->flavour != bfd_target_elf_flavour
64655796c8dcSSimon Schubert       || obfd->xvec->flavour != bfd_target_elf_flavour)
64665796c8dcSSimon Schubert     return TRUE;
64675796c8dcSSimon Schubert 
64685796c8dcSSimon Schubert   ihdr = &elf_section_data (isec)->this_hdr;
64695796c8dcSSimon Schubert   ohdr = &elf_section_data (osec)->this_hdr;
64705796c8dcSSimon Schubert 
64715796c8dcSSimon Schubert   ohdr->sh_entsize = ihdr->sh_entsize;
64725796c8dcSSimon Schubert 
64735796c8dcSSimon Schubert   if (ihdr->sh_type == SHT_SYMTAB
64745796c8dcSSimon Schubert       || ihdr->sh_type == SHT_DYNSYM
64755796c8dcSSimon Schubert       || ihdr->sh_type == SHT_GNU_verneed
64765796c8dcSSimon Schubert       || ihdr->sh_type == SHT_GNU_verdef)
64775796c8dcSSimon Schubert     ohdr->sh_info = ihdr->sh_info;
64785796c8dcSSimon Schubert 
64795796c8dcSSimon Schubert   return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
64805796c8dcSSimon Schubert 					     NULL);
64815796c8dcSSimon Schubert }
64825796c8dcSSimon Schubert 
6483cf7f2e2dSJohn Marino /* Look at all the SHT_GROUP sections in IBFD, making any adjustments
6484cf7f2e2dSJohn Marino    necessary if we are removing either the SHT_GROUP section or any of
6485cf7f2e2dSJohn Marino    the group member sections.  DISCARDED is the value that a section's
6486cf7f2e2dSJohn Marino    output_section has if the section will be discarded, NULL when this
6487cf7f2e2dSJohn Marino    function is called from objcopy, bfd_abs_section_ptr when called
6488cf7f2e2dSJohn Marino    from the linker.  */
6489cf7f2e2dSJohn Marino 
6490cf7f2e2dSJohn Marino bfd_boolean
_bfd_elf_fixup_group_sections(bfd * ibfd,asection * discarded)6491cf7f2e2dSJohn Marino _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
6492cf7f2e2dSJohn Marino {
6493cf7f2e2dSJohn Marino   asection *isec;
6494cf7f2e2dSJohn Marino 
6495cf7f2e2dSJohn Marino   for (isec = ibfd->sections; isec != NULL; isec = isec->next)
6496cf7f2e2dSJohn Marino     if (elf_section_type (isec) == SHT_GROUP)
6497cf7f2e2dSJohn Marino       {
6498cf7f2e2dSJohn Marino 	asection *first = elf_next_in_group (isec);
6499cf7f2e2dSJohn Marino 	asection *s = first;
6500cf7f2e2dSJohn Marino 	bfd_size_type removed = 0;
6501cf7f2e2dSJohn Marino 
6502cf7f2e2dSJohn Marino 	while (s != NULL)
6503cf7f2e2dSJohn Marino 	  {
6504cf7f2e2dSJohn Marino 	    /* If this member section is being output but the
6505cf7f2e2dSJohn Marino 	       SHT_GROUP section is not, then clear the group info
6506cf7f2e2dSJohn Marino 	       set up by _bfd_elf_copy_private_section_data.  */
6507cf7f2e2dSJohn Marino 	    if (s->output_section != discarded
6508cf7f2e2dSJohn Marino 		&& isec->output_section == discarded)
6509cf7f2e2dSJohn Marino 	      {
6510cf7f2e2dSJohn Marino 		elf_section_flags (s->output_section) &= ~SHF_GROUP;
6511cf7f2e2dSJohn Marino 		elf_group_name (s->output_section) = NULL;
6512cf7f2e2dSJohn Marino 	      }
6513cf7f2e2dSJohn Marino 	    /* Conversely, if the member section is not being output
6514cf7f2e2dSJohn Marino 	       but the SHT_GROUP section is, then adjust its size.  */
6515cf7f2e2dSJohn Marino 	    else if (s->output_section == discarded
6516cf7f2e2dSJohn Marino 		     && isec->output_section != discarded)
6517cf7f2e2dSJohn Marino 	      removed += 4;
6518cf7f2e2dSJohn Marino 	    s = elf_next_in_group (s);
6519cf7f2e2dSJohn Marino 	    if (s == first)
6520cf7f2e2dSJohn Marino 	      break;
6521cf7f2e2dSJohn Marino 	  }
6522cf7f2e2dSJohn Marino 	if (removed != 0)
6523cf7f2e2dSJohn Marino 	  {
6524cf7f2e2dSJohn Marino 	    if (discarded != NULL)
6525cf7f2e2dSJohn Marino 	      {
6526cf7f2e2dSJohn Marino 		/* If we've been called for ld -r, then we need to
6527cf7f2e2dSJohn Marino 		   adjust the input section size.  This function may
6528cf7f2e2dSJohn Marino 		   be called multiple times, so save the original
6529cf7f2e2dSJohn Marino 		   size.  */
6530cf7f2e2dSJohn Marino 		if (isec->rawsize == 0)
6531cf7f2e2dSJohn Marino 		  isec->rawsize = isec->size;
6532cf7f2e2dSJohn Marino 		isec->size = isec->rawsize - removed;
6533cf7f2e2dSJohn Marino 	      }
6534cf7f2e2dSJohn Marino 	    else
6535cf7f2e2dSJohn Marino 	      {
6536cf7f2e2dSJohn Marino 		/* Adjust the output section size when called from
6537cf7f2e2dSJohn Marino 		   objcopy. */
6538cf7f2e2dSJohn Marino 		isec->output_section->size -= removed;
6539cf7f2e2dSJohn Marino 	      }
6540cf7f2e2dSJohn Marino 	  }
6541cf7f2e2dSJohn Marino       }
6542cf7f2e2dSJohn Marino 
6543cf7f2e2dSJohn Marino   return TRUE;
6544cf7f2e2dSJohn Marino }
6545cf7f2e2dSJohn Marino 
65465796c8dcSSimon Schubert /* Copy private header information.  */
65475796c8dcSSimon Schubert 
65485796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_header_data(bfd * ibfd,bfd * obfd)65495796c8dcSSimon Schubert _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
65505796c8dcSSimon Schubert {
65515796c8dcSSimon Schubert   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
65525796c8dcSSimon Schubert       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
65535796c8dcSSimon Schubert     return TRUE;
65545796c8dcSSimon Schubert 
65555796c8dcSSimon Schubert   /* Copy over private BFD data if it has not already been copied.
65565796c8dcSSimon Schubert      This must be done here, rather than in the copy_private_bfd_data
65575796c8dcSSimon Schubert      entry point, because the latter is called after the section
65585796c8dcSSimon Schubert      contents have been set, which means that the program headers have
65595796c8dcSSimon Schubert      already been worked out.  */
6560*ef5ccd6cSJohn Marino   if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL)
65615796c8dcSSimon Schubert     {
65625796c8dcSSimon Schubert       if (! copy_private_bfd_data (ibfd, obfd))
65635796c8dcSSimon Schubert 	return FALSE;
65645796c8dcSSimon Schubert     }
65655796c8dcSSimon Schubert 
6566cf7f2e2dSJohn Marino   return _bfd_elf_fixup_group_sections (ibfd, NULL);
65675796c8dcSSimon Schubert }
65685796c8dcSSimon Schubert 
65695796c8dcSSimon Schubert /* Copy private symbol information.  If this symbol is in a section
65705796c8dcSSimon Schubert    which we did not map into a BFD section, try to map the section
65715796c8dcSSimon Schubert    index correctly.  We use special macro definitions for the mapped
65725796c8dcSSimon Schubert    section indices; these definitions are interpreted by the
65735796c8dcSSimon Schubert    swap_out_syms function.  */
65745796c8dcSSimon Schubert 
65755796c8dcSSimon Schubert #define MAP_ONESYMTAB (SHN_HIOS + 1)
65765796c8dcSSimon Schubert #define MAP_DYNSYMTAB (SHN_HIOS + 2)
65775796c8dcSSimon Schubert #define MAP_STRTAB    (SHN_HIOS + 3)
65785796c8dcSSimon Schubert #define MAP_SHSTRTAB  (SHN_HIOS + 4)
65795796c8dcSSimon Schubert #define MAP_SYM_SHNDX (SHN_HIOS + 5)
65805796c8dcSSimon Schubert 
65815796c8dcSSimon Schubert bfd_boolean
_bfd_elf_copy_private_symbol_data(bfd * ibfd,asymbol * isymarg,bfd * obfd,asymbol * osymarg)65825796c8dcSSimon Schubert _bfd_elf_copy_private_symbol_data (bfd *ibfd,
65835796c8dcSSimon Schubert 				   asymbol *isymarg,
65845796c8dcSSimon Schubert 				   bfd *obfd,
65855796c8dcSSimon Schubert 				   asymbol *osymarg)
65865796c8dcSSimon Schubert {
65875796c8dcSSimon Schubert   elf_symbol_type *isym, *osym;
65885796c8dcSSimon Schubert 
65895796c8dcSSimon Schubert   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
65905796c8dcSSimon Schubert       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
65915796c8dcSSimon Schubert     return TRUE;
65925796c8dcSSimon Schubert 
65935796c8dcSSimon Schubert   isym = elf_symbol_from (ibfd, isymarg);
65945796c8dcSSimon Schubert   osym = elf_symbol_from (obfd, osymarg);
65955796c8dcSSimon Schubert 
65965796c8dcSSimon Schubert   if (isym != NULL
65975796c8dcSSimon Schubert       && isym->internal_elf_sym.st_shndx != 0
65985796c8dcSSimon Schubert       && osym != NULL
65995796c8dcSSimon Schubert       && bfd_is_abs_section (isym->symbol.section))
66005796c8dcSSimon Schubert     {
66015796c8dcSSimon Schubert       unsigned int shndx;
66025796c8dcSSimon Schubert 
66035796c8dcSSimon Schubert       shndx = isym->internal_elf_sym.st_shndx;
66045796c8dcSSimon Schubert       if (shndx == elf_onesymtab (ibfd))
66055796c8dcSSimon Schubert 	shndx = MAP_ONESYMTAB;
66065796c8dcSSimon Schubert       else if (shndx == elf_dynsymtab (ibfd))
66075796c8dcSSimon Schubert 	shndx = MAP_DYNSYMTAB;
6608*ef5ccd6cSJohn Marino       else if (shndx == elf_strtab_sec (ibfd))
66095796c8dcSSimon Schubert 	shndx = MAP_STRTAB;
6610*ef5ccd6cSJohn Marino       else if (shndx == elf_shstrtab_sec (ibfd))
66115796c8dcSSimon Schubert 	shndx = MAP_SHSTRTAB;
6612*ef5ccd6cSJohn Marino       else if (shndx == elf_symtab_shndx (ibfd))
66135796c8dcSSimon Schubert 	shndx = MAP_SYM_SHNDX;
66145796c8dcSSimon Schubert       osym->internal_elf_sym.st_shndx = shndx;
66155796c8dcSSimon Schubert     }
66165796c8dcSSimon Schubert 
66175796c8dcSSimon Schubert   return TRUE;
66185796c8dcSSimon Schubert }
66195796c8dcSSimon Schubert 
66205796c8dcSSimon Schubert /* Swap out the symbols.  */
66215796c8dcSSimon Schubert 
66225796c8dcSSimon Schubert static bfd_boolean
swap_out_syms(bfd * abfd,struct bfd_strtab_hash ** sttp,int relocatable_p)66235796c8dcSSimon Schubert swap_out_syms (bfd *abfd,
66245796c8dcSSimon Schubert 	       struct bfd_strtab_hash **sttp,
66255796c8dcSSimon Schubert 	       int relocatable_p)
66265796c8dcSSimon Schubert {
66275796c8dcSSimon Schubert   const struct elf_backend_data *bed;
66285796c8dcSSimon Schubert   int symcount;
66295796c8dcSSimon Schubert   asymbol **syms;
66305796c8dcSSimon Schubert   struct bfd_strtab_hash *stt;
66315796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_hdr;
66325796c8dcSSimon Schubert   Elf_Internal_Shdr *symtab_shndx_hdr;
66335796c8dcSSimon Schubert   Elf_Internal_Shdr *symstrtab_hdr;
66345796c8dcSSimon Schubert   bfd_byte *outbound_syms;
66355796c8dcSSimon Schubert   bfd_byte *outbound_shndx;
66365796c8dcSSimon Schubert   int idx;
6637*ef5ccd6cSJohn Marino   unsigned int num_locals;
66385796c8dcSSimon Schubert   bfd_size_type amt;
66395796c8dcSSimon Schubert   bfd_boolean name_local_sections;
66405796c8dcSSimon Schubert 
6641*ef5ccd6cSJohn Marino   if (!elf_map_symbols (abfd, &num_locals))
66425796c8dcSSimon Schubert     return FALSE;
66435796c8dcSSimon Schubert 
66445796c8dcSSimon Schubert   /* Dump out the symtabs.  */
66455796c8dcSSimon Schubert   stt = _bfd_elf_stringtab_init ();
66465796c8dcSSimon Schubert   if (stt == NULL)
66475796c8dcSSimon Schubert     return FALSE;
66485796c8dcSSimon Schubert 
66495796c8dcSSimon Schubert   bed = get_elf_backend_data (abfd);
66505796c8dcSSimon Schubert   symcount = bfd_get_symcount (abfd);
66515796c8dcSSimon Schubert   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
66525796c8dcSSimon Schubert   symtab_hdr->sh_type = SHT_SYMTAB;
66535796c8dcSSimon Schubert   symtab_hdr->sh_entsize = bed->s->sizeof_sym;
66545796c8dcSSimon Schubert   symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
6655*ef5ccd6cSJohn Marino   symtab_hdr->sh_info = num_locals + 1;
66565796c8dcSSimon Schubert   symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
66575796c8dcSSimon Schubert 
66585796c8dcSSimon Schubert   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
66595796c8dcSSimon Schubert   symstrtab_hdr->sh_type = SHT_STRTAB;
66605796c8dcSSimon Schubert 
66615796c8dcSSimon Schubert   outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount,
66625796c8dcSSimon Schubert                                            bed->s->sizeof_sym);
66635796c8dcSSimon Schubert   if (outbound_syms == NULL)
66645796c8dcSSimon Schubert     {
66655796c8dcSSimon Schubert       _bfd_stringtab_free (stt);
66665796c8dcSSimon Schubert       return FALSE;
66675796c8dcSSimon Schubert     }
66685796c8dcSSimon Schubert   symtab_hdr->contents = outbound_syms;
66695796c8dcSSimon Schubert 
66705796c8dcSSimon Schubert   outbound_shndx = NULL;
66715796c8dcSSimon Schubert   symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
66725796c8dcSSimon Schubert   if (symtab_shndx_hdr->sh_name != 0)
66735796c8dcSSimon Schubert     {
66745796c8dcSSimon Schubert       amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
66755796c8dcSSimon Schubert       outbound_shndx =  (bfd_byte *)
66765796c8dcSSimon Schubert           bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
66775796c8dcSSimon Schubert       if (outbound_shndx == NULL)
66785796c8dcSSimon Schubert 	{
66795796c8dcSSimon Schubert 	  _bfd_stringtab_free (stt);
66805796c8dcSSimon Schubert 	  return FALSE;
66815796c8dcSSimon Schubert 	}
66825796c8dcSSimon Schubert 
66835796c8dcSSimon Schubert       symtab_shndx_hdr->contents = outbound_shndx;
66845796c8dcSSimon Schubert       symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
66855796c8dcSSimon Schubert       symtab_shndx_hdr->sh_size = amt;
66865796c8dcSSimon Schubert       symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
66875796c8dcSSimon Schubert       symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
66885796c8dcSSimon Schubert     }
66895796c8dcSSimon Schubert 
66905796c8dcSSimon Schubert   /* Now generate the data (for "contents").  */
66915796c8dcSSimon Schubert   {
66925796c8dcSSimon Schubert     /* Fill in zeroth symbol and swap it out.  */
66935796c8dcSSimon Schubert     Elf_Internal_Sym sym;
66945796c8dcSSimon Schubert     sym.st_name = 0;
66955796c8dcSSimon Schubert     sym.st_value = 0;
66965796c8dcSSimon Schubert     sym.st_size = 0;
66975796c8dcSSimon Schubert     sym.st_info = 0;
66985796c8dcSSimon Schubert     sym.st_other = 0;
66995796c8dcSSimon Schubert     sym.st_shndx = SHN_UNDEF;
6700c50c785cSJohn Marino     sym.st_target_internal = 0;
67015796c8dcSSimon Schubert     bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
67025796c8dcSSimon Schubert     outbound_syms += bed->s->sizeof_sym;
67035796c8dcSSimon Schubert     if (outbound_shndx != NULL)
67045796c8dcSSimon Schubert       outbound_shndx += sizeof (Elf_External_Sym_Shndx);
67055796c8dcSSimon Schubert   }
67065796c8dcSSimon Schubert 
67075796c8dcSSimon Schubert   name_local_sections
67085796c8dcSSimon Schubert     = (bed->elf_backend_name_local_section_symbols
67095796c8dcSSimon Schubert        && bed->elf_backend_name_local_section_symbols (abfd));
67105796c8dcSSimon Schubert 
67115796c8dcSSimon Schubert   syms = bfd_get_outsymbols (abfd);
67125796c8dcSSimon Schubert   for (idx = 0; idx < symcount; idx++)
67135796c8dcSSimon Schubert     {
67145796c8dcSSimon Schubert       Elf_Internal_Sym sym;
67155796c8dcSSimon Schubert       bfd_vma value = syms[idx]->value;
67165796c8dcSSimon Schubert       elf_symbol_type *type_ptr;
67175796c8dcSSimon Schubert       flagword flags = syms[idx]->flags;
67185796c8dcSSimon Schubert       int type;
67195796c8dcSSimon Schubert 
67205796c8dcSSimon Schubert       if (!name_local_sections
67215796c8dcSSimon Schubert 	  && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
67225796c8dcSSimon Schubert 	{
67235796c8dcSSimon Schubert 	  /* Local section symbols have no name.  */
67245796c8dcSSimon Schubert 	  sym.st_name = 0;
67255796c8dcSSimon Schubert 	}
67265796c8dcSSimon Schubert       else
67275796c8dcSSimon Schubert 	{
67285796c8dcSSimon Schubert 	  sym.st_name = (unsigned long) _bfd_stringtab_add (stt,
67295796c8dcSSimon Schubert 							    syms[idx]->name,
67305796c8dcSSimon Schubert 							    TRUE, FALSE);
67315796c8dcSSimon Schubert 	  if (sym.st_name == (unsigned long) -1)
67325796c8dcSSimon Schubert 	    {
67335796c8dcSSimon Schubert 	      _bfd_stringtab_free (stt);
67345796c8dcSSimon Schubert 	      return FALSE;
67355796c8dcSSimon Schubert 	    }
67365796c8dcSSimon Schubert 	}
67375796c8dcSSimon Schubert 
67385796c8dcSSimon Schubert       type_ptr = elf_symbol_from (abfd, syms[idx]);
67395796c8dcSSimon Schubert 
67405796c8dcSSimon Schubert       if ((flags & BSF_SECTION_SYM) == 0
67415796c8dcSSimon Schubert 	  && bfd_is_com_section (syms[idx]->section))
67425796c8dcSSimon Schubert 	{
67435796c8dcSSimon Schubert 	  /* ELF common symbols put the alignment into the `value' field,
67445796c8dcSSimon Schubert 	     and the size into the `size' field.  This is backwards from
67455796c8dcSSimon Schubert 	     how BFD handles it, so reverse it here.  */
67465796c8dcSSimon Schubert 	  sym.st_size = value;
67475796c8dcSSimon Schubert 	  if (type_ptr == NULL
67485796c8dcSSimon Schubert 	      || type_ptr->internal_elf_sym.st_value == 0)
67495796c8dcSSimon Schubert 	    sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
67505796c8dcSSimon Schubert 	  else
67515796c8dcSSimon Schubert 	    sym.st_value = type_ptr->internal_elf_sym.st_value;
67525796c8dcSSimon Schubert 	  sym.st_shndx = _bfd_elf_section_from_bfd_section
67535796c8dcSSimon Schubert 	    (abfd, syms[idx]->section);
67545796c8dcSSimon Schubert 	}
67555796c8dcSSimon Schubert       else
67565796c8dcSSimon Schubert 	{
67575796c8dcSSimon Schubert 	  asection *sec = syms[idx]->section;
67585796c8dcSSimon Schubert 	  unsigned int shndx;
67595796c8dcSSimon Schubert 
67605796c8dcSSimon Schubert 	  if (sec->output_section)
67615796c8dcSSimon Schubert 	    {
67625796c8dcSSimon Schubert 	      value += sec->output_offset;
67635796c8dcSSimon Schubert 	      sec = sec->output_section;
67645796c8dcSSimon Schubert 	    }
67655796c8dcSSimon Schubert 
67665796c8dcSSimon Schubert 	  /* Don't add in the section vma for relocatable output.  */
67675796c8dcSSimon Schubert 	  if (! relocatable_p)
67685796c8dcSSimon Schubert 	    value += sec->vma;
67695796c8dcSSimon Schubert 	  sym.st_value = value;
67705796c8dcSSimon Schubert 	  sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;
67715796c8dcSSimon Schubert 
67725796c8dcSSimon Schubert 	  if (bfd_is_abs_section (sec)
67735796c8dcSSimon Schubert 	      && type_ptr != NULL
67745796c8dcSSimon Schubert 	      && type_ptr->internal_elf_sym.st_shndx != 0)
67755796c8dcSSimon Schubert 	    {
67765796c8dcSSimon Schubert 	      /* This symbol is in a real ELF section which we did
67775796c8dcSSimon Schubert 		 not create as a BFD section.  Undo the mapping done
67785796c8dcSSimon Schubert 		 by copy_private_symbol_data.  */
67795796c8dcSSimon Schubert 	      shndx = type_ptr->internal_elf_sym.st_shndx;
67805796c8dcSSimon Schubert 	      switch (shndx)
67815796c8dcSSimon Schubert 		{
67825796c8dcSSimon Schubert 		case MAP_ONESYMTAB:
67835796c8dcSSimon Schubert 		  shndx = elf_onesymtab (abfd);
67845796c8dcSSimon Schubert 		  break;
67855796c8dcSSimon Schubert 		case MAP_DYNSYMTAB:
67865796c8dcSSimon Schubert 		  shndx = elf_dynsymtab (abfd);
67875796c8dcSSimon Schubert 		  break;
67885796c8dcSSimon Schubert 		case MAP_STRTAB:
6789*ef5ccd6cSJohn Marino 		  shndx = elf_strtab_sec (abfd);
67905796c8dcSSimon Schubert 		  break;
67915796c8dcSSimon Schubert 		case MAP_SHSTRTAB:
6792*ef5ccd6cSJohn Marino 		  shndx = elf_shstrtab_sec (abfd);
67935796c8dcSSimon Schubert 		  break;
67945796c8dcSSimon Schubert 		case MAP_SYM_SHNDX:
6795*ef5ccd6cSJohn Marino 		  shndx = elf_symtab_shndx (abfd);
67965796c8dcSSimon Schubert 		  break;
67975796c8dcSSimon Schubert 		default:
6798*ef5ccd6cSJohn Marino 		  shndx = SHN_ABS;
67995796c8dcSSimon Schubert 		  break;
68005796c8dcSSimon Schubert 		}
68015796c8dcSSimon Schubert 	    }
68025796c8dcSSimon Schubert 	  else
68035796c8dcSSimon Schubert 	    {
68045796c8dcSSimon Schubert 	      shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
68055796c8dcSSimon Schubert 
68065796c8dcSSimon Schubert 	      if (shndx == SHN_BAD)
68075796c8dcSSimon Schubert 		{
68085796c8dcSSimon Schubert 		  asection *sec2;
68095796c8dcSSimon Schubert 
68105796c8dcSSimon Schubert 		  /* Writing this would be a hell of a lot easier if
68115796c8dcSSimon Schubert 		     we had some decent documentation on bfd, and
68125796c8dcSSimon Schubert 		     knew what to expect of the library, and what to
68135796c8dcSSimon Schubert 		     demand of applications.  For example, it
68145796c8dcSSimon Schubert 		     appears that `objcopy' might not set the
68155796c8dcSSimon Schubert 		     section of a symbol to be a section that is
68165796c8dcSSimon Schubert 		     actually in the output file.  */
68175796c8dcSSimon Schubert 		  sec2 = bfd_get_section_by_name (abfd, sec->name);
68185796c8dcSSimon Schubert 		  if (sec2 == NULL)
68195796c8dcSSimon Schubert 		    {
68205796c8dcSSimon Schubert 		      _bfd_error_handler (_("\
68215796c8dcSSimon Schubert Unable to find equivalent output section for symbol '%s' from section '%s'"),
68225796c8dcSSimon Schubert 					  syms[idx]->name ? syms[idx]->name : "<Local sym>",
68235796c8dcSSimon Schubert 					  sec->name);
68245796c8dcSSimon Schubert 		      bfd_set_error (bfd_error_invalid_operation);
68255796c8dcSSimon Schubert 		      _bfd_stringtab_free (stt);
68265796c8dcSSimon Schubert 		      return FALSE;
68275796c8dcSSimon Schubert 		    }
68285796c8dcSSimon Schubert 
68295796c8dcSSimon Schubert 		  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
68305796c8dcSSimon Schubert 		  BFD_ASSERT (shndx != SHN_BAD);
68315796c8dcSSimon Schubert 		}
68325796c8dcSSimon Schubert 	    }
68335796c8dcSSimon Schubert 
68345796c8dcSSimon Schubert 	  sym.st_shndx = shndx;
68355796c8dcSSimon Schubert 	}
68365796c8dcSSimon Schubert 
68375796c8dcSSimon Schubert       if ((flags & BSF_THREAD_LOCAL) != 0)
68385796c8dcSSimon Schubert 	type = STT_TLS;
68395796c8dcSSimon Schubert       else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
68405796c8dcSSimon Schubert 	type = STT_GNU_IFUNC;
68415796c8dcSSimon Schubert       else if ((flags & BSF_FUNCTION) != 0)
68425796c8dcSSimon Schubert 	type = STT_FUNC;
68435796c8dcSSimon Schubert       else if ((flags & BSF_OBJECT) != 0)
68445796c8dcSSimon Schubert 	type = STT_OBJECT;
68455796c8dcSSimon Schubert       else if ((flags & BSF_RELC) != 0)
68465796c8dcSSimon Schubert 	type = STT_RELC;
68475796c8dcSSimon Schubert       else if ((flags & BSF_SRELC) != 0)
68485796c8dcSSimon Schubert 	type = STT_SRELC;
68495796c8dcSSimon Schubert       else
68505796c8dcSSimon Schubert 	type = STT_NOTYPE;
68515796c8dcSSimon Schubert 
68525796c8dcSSimon Schubert       if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
68535796c8dcSSimon Schubert 	type = STT_TLS;
68545796c8dcSSimon Schubert 
68555796c8dcSSimon Schubert       /* Processor-specific types.  */
68565796c8dcSSimon Schubert       if (type_ptr != NULL
68575796c8dcSSimon Schubert 	  && bed->elf_backend_get_symbol_type)
68585796c8dcSSimon Schubert 	type = ((*bed->elf_backend_get_symbol_type)
68595796c8dcSSimon Schubert 		(&type_ptr->internal_elf_sym, type));
68605796c8dcSSimon Schubert 
68615796c8dcSSimon Schubert       if (flags & BSF_SECTION_SYM)
68625796c8dcSSimon Schubert 	{
68635796c8dcSSimon Schubert 	  if (flags & BSF_GLOBAL)
68645796c8dcSSimon Schubert 	    sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
68655796c8dcSSimon Schubert 	  else
68665796c8dcSSimon Schubert 	    sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
68675796c8dcSSimon Schubert 	}
68685796c8dcSSimon Schubert       else if (bfd_is_com_section (syms[idx]->section))
68695796c8dcSSimon Schubert 	{
68705796c8dcSSimon Schubert #ifdef USE_STT_COMMON
68715796c8dcSSimon Schubert 	  if (type == STT_OBJECT)
68725796c8dcSSimon Schubert 	    sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
68735796c8dcSSimon Schubert 	  else
68745796c8dcSSimon Schubert #endif
68755796c8dcSSimon Schubert 	    sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
68765796c8dcSSimon Schubert 	}
68775796c8dcSSimon Schubert       else if (bfd_is_und_section (syms[idx]->section))
68785796c8dcSSimon Schubert 	sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
68795796c8dcSSimon Schubert 				    ? STB_WEAK
68805796c8dcSSimon Schubert 				    : STB_GLOBAL),
68815796c8dcSSimon Schubert 				   type);
68825796c8dcSSimon Schubert       else if (flags & BSF_FILE)
68835796c8dcSSimon Schubert 	sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
68845796c8dcSSimon Schubert       else
68855796c8dcSSimon Schubert 	{
68865796c8dcSSimon Schubert 	  int bind = STB_LOCAL;
68875796c8dcSSimon Schubert 
68885796c8dcSSimon Schubert 	  if (flags & BSF_LOCAL)
68895796c8dcSSimon Schubert 	    bind = STB_LOCAL;
68905796c8dcSSimon Schubert 	  else if (flags & BSF_GNU_UNIQUE)
68915796c8dcSSimon Schubert 	    bind = STB_GNU_UNIQUE;
68925796c8dcSSimon Schubert 	  else if (flags & BSF_WEAK)
68935796c8dcSSimon Schubert 	    bind = STB_WEAK;
68945796c8dcSSimon Schubert 	  else if (flags & BSF_GLOBAL)
68955796c8dcSSimon Schubert 	    bind = STB_GLOBAL;
68965796c8dcSSimon Schubert 
68975796c8dcSSimon Schubert 	  sym.st_info = ELF_ST_INFO (bind, type);
68985796c8dcSSimon Schubert 	}
68995796c8dcSSimon Schubert 
69005796c8dcSSimon Schubert       if (type_ptr != NULL)
6901c50c785cSJohn Marino 	{
69025796c8dcSSimon Schubert 	  sym.st_other = type_ptr->internal_elf_sym.st_other;
6903c50c785cSJohn Marino 	  sym.st_target_internal
6904c50c785cSJohn Marino 	    = type_ptr->internal_elf_sym.st_target_internal;
6905c50c785cSJohn Marino 	}
69065796c8dcSSimon Schubert       else
6907c50c785cSJohn Marino 	{
69085796c8dcSSimon Schubert 	  sym.st_other = 0;
6909c50c785cSJohn Marino 	  sym.st_target_internal = 0;
6910c50c785cSJohn Marino 	}
69115796c8dcSSimon Schubert 
69125796c8dcSSimon Schubert       bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
69135796c8dcSSimon Schubert       outbound_syms += bed->s->sizeof_sym;
69145796c8dcSSimon Schubert       if (outbound_shndx != NULL)
69155796c8dcSSimon Schubert 	outbound_shndx += sizeof (Elf_External_Sym_Shndx);
69165796c8dcSSimon Schubert     }
69175796c8dcSSimon Schubert 
69185796c8dcSSimon Schubert   *sttp = stt;
69195796c8dcSSimon Schubert   symstrtab_hdr->sh_size = _bfd_stringtab_size (stt);
69205796c8dcSSimon Schubert   symstrtab_hdr->sh_type = SHT_STRTAB;
69215796c8dcSSimon Schubert 
69225796c8dcSSimon Schubert   symstrtab_hdr->sh_flags = 0;
69235796c8dcSSimon Schubert   symstrtab_hdr->sh_addr = 0;
69245796c8dcSSimon Schubert   symstrtab_hdr->sh_entsize = 0;
69255796c8dcSSimon Schubert   symstrtab_hdr->sh_link = 0;
69265796c8dcSSimon Schubert   symstrtab_hdr->sh_info = 0;
69275796c8dcSSimon Schubert   symstrtab_hdr->sh_addralign = 1;
69285796c8dcSSimon Schubert 
69295796c8dcSSimon Schubert   return TRUE;
69305796c8dcSSimon Schubert }
69315796c8dcSSimon Schubert 
69325796c8dcSSimon Schubert /* Return the number of bytes required to hold the symtab vector.
69335796c8dcSSimon Schubert 
69345796c8dcSSimon Schubert    Note that we base it on the count plus 1, since we will null terminate
69355796c8dcSSimon Schubert    the vector allocated based on this size.  However, the ELF symbol table
69365796c8dcSSimon Schubert    always has a dummy entry as symbol #0, so it ends up even.  */
69375796c8dcSSimon Schubert 
69385796c8dcSSimon Schubert long
_bfd_elf_get_symtab_upper_bound(bfd * abfd)69395796c8dcSSimon Schubert _bfd_elf_get_symtab_upper_bound (bfd *abfd)
69405796c8dcSSimon Schubert {
69415796c8dcSSimon Schubert   long symcount;
69425796c8dcSSimon Schubert   long symtab_size;
69435796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
69445796c8dcSSimon Schubert 
69455796c8dcSSimon Schubert   symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
69465796c8dcSSimon Schubert   symtab_size = (symcount + 1) * (sizeof (asymbol *));
69475796c8dcSSimon Schubert   if (symcount > 0)
69485796c8dcSSimon Schubert     symtab_size -= sizeof (asymbol *);
69495796c8dcSSimon Schubert 
69505796c8dcSSimon Schubert   return symtab_size;
69515796c8dcSSimon Schubert }
69525796c8dcSSimon Schubert 
69535796c8dcSSimon Schubert long
_bfd_elf_get_dynamic_symtab_upper_bound(bfd * abfd)69545796c8dcSSimon Schubert _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
69555796c8dcSSimon Schubert {
69565796c8dcSSimon Schubert   long symcount;
69575796c8dcSSimon Schubert   long symtab_size;
69585796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
69595796c8dcSSimon Schubert 
69605796c8dcSSimon Schubert   if (elf_dynsymtab (abfd) == 0)
69615796c8dcSSimon Schubert     {
69625796c8dcSSimon Schubert       bfd_set_error (bfd_error_invalid_operation);
69635796c8dcSSimon Schubert       return -1;
69645796c8dcSSimon Schubert     }
69655796c8dcSSimon Schubert 
69665796c8dcSSimon Schubert   symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
69675796c8dcSSimon Schubert   symtab_size = (symcount + 1) * (sizeof (asymbol *));
69685796c8dcSSimon Schubert   if (symcount > 0)
69695796c8dcSSimon Schubert     symtab_size -= sizeof (asymbol *);
69705796c8dcSSimon Schubert 
69715796c8dcSSimon Schubert   return symtab_size;
69725796c8dcSSimon Schubert }
69735796c8dcSSimon Schubert 
69745796c8dcSSimon Schubert long
_bfd_elf_get_reloc_upper_bound(bfd * abfd ATTRIBUTE_UNUSED,sec_ptr asect)69755796c8dcSSimon Schubert _bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
69765796c8dcSSimon Schubert 				sec_ptr asect)
69775796c8dcSSimon Schubert {
69785796c8dcSSimon Schubert   return (asect->reloc_count + 1) * sizeof (arelent *);
69795796c8dcSSimon Schubert }
69805796c8dcSSimon Schubert 
69815796c8dcSSimon Schubert /* Canonicalize the relocs.  */
69825796c8dcSSimon Schubert 
69835796c8dcSSimon Schubert long
_bfd_elf_canonicalize_reloc(bfd * abfd,sec_ptr section,arelent ** relptr,asymbol ** symbols)69845796c8dcSSimon Schubert _bfd_elf_canonicalize_reloc (bfd *abfd,
69855796c8dcSSimon Schubert 			     sec_ptr section,
69865796c8dcSSimon Schubert 			     arelent **relptr,
69875796c8dcSSimon Schubert 			     asymbol **symbols)
69885796c8dcSSimon Schubert {
69895796c8dcSSimon Schubert   arelent *tblptr;
69905796c8dcSSimon Schubert   unsigned int i;
69915796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
69925796c8dcSSimon Schubert 
69935796c8dcSSimon Schubert   if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
69945796c8dcSSimon Schubert     return -1;
69955796c8dcSSimon Schubert 
69965796c8dcSSimon Schubert   tblptr = section->relocation;
69975796c8dcSSimon Schubert   for (i = 0; i < section->reloc_count; i++)
69985796c8dcSSimon Schubert     *relptr++ = tblptr++;
69995796c8dcSSimon Schubert 
70005796c8dcSSimon Schubert   *relptr = NULL;
70015796c8dcSSimon Schubert 
70025796c8dcSSimon Schubert   return section->reloc_count;
70035796c8dcSSimon Schubert }
70045796c8dcSSimon Schubert 
70055796c8dcSSimon Schubert long
_bfd_elf_canonicalize_symtab(bfd * abfd,asymbol ** allocation)70065796c8dcSSimon Schubert _bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
70075796c8dcSSimon Schubert {
70085796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
70095796c8dcSSimon Schubert   long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);
70105796c8dcSSimon Schubert 
70115796c8dcSSimon Schubert   if (symcount >= 0)
70125796c8dcSSimon Schubert     bfd_get_symcount (abfd) = symcount;
70135796c8dcSSimon Schubert   return symcount;
70145796c8dcSSimon Schubert }
70155796c8dcSSimon Schubert 
70165796c8dcSSimon Schubert long
_bfd_elf_canonicalize_dynamic_symtab(bfd * abfd,asymbol ** allocation)70175796c8dcSSimon Schubert _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
70185796c8dcSSimon Schubert 				      asymbol **allocation)
70195796c8dcSSimon Schubert {
70205796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
70215796c8dcSSimon Schubert   long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);
70225796c8dcSSimon Schubert 
70235796c8dcSSimon Schubert   if (symcount >= 0)
70245796c8dcSSimon Schubert     bfd_get_dynamic_symcount (abfd) = symcount;
70255796c8dcSSimon Schubert   return symcount;
70265796c8dcSSimon Schubert }
70275796c8dcSSimon Schubert 
70285796c8dcSSimon Schubert /* Return the size required for the dynamic reloc entries.  Any loadable
70295796c8dcSSimon Schubert    section that was actually installed in the BFD, and has type SHT_REL
70305796c8dcSSimon Schubert    or SHT_RELA, and uses the dynamic symbol table, is considered to be a
70315796c8dcSSimon Schubert    dynamic reloc section.  */
70325796c8dcSSimon Schubert 
70335796c8dcSSimon Schubert long
_bfd_elf_get_dynamic_reloc_upper_bound(bfd * abfd)70345796c8dcSSimon Schubert _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
70355796c8dcSSimon Schubert {
70365796c8dcSSimon Schubert   long ret;
70375796c8dcSSimon Schubert   asection *s;
70385796c8dcSSimon Schubert 
70395796c8dcSSimon Schubert   if (elf_dynsymtab (abfd) == 0)
70405796c8dcSSimon Schubert     {
70415796c8dcSSimon Schubert       bfd_set_error (bfd_error_invalid_operation);
70425796c8dcSSimon Schubert       return -1;
70435796c8dcSSimon Schubert     }
70445796c8dcSSimon Schubert 
70455796c8dcSSimon Schubert   ret = sizeof (arelent *);
70465796c8dcSSimon Schubert   for (s = abfd->sections; s != NULL; s = s->next)
70475796c8dcSSimon Schubert     if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
70485796c8dcSSimon Schubert 	&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
70495796c8dcSSimon Schubert 	    || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
70505796c8dcSSimon Schubert       ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
70515796c8dcSSimon Schubert 	      * sizeof (arelent *));
70525796c8dcSSimon Schubert 
70535796c8dcSSimon Schubert   return ret;
70545796c8dcSSimon Schubert }
70555796c8dcSSimon Schubert 
70565796c8dcSSimon Schubert /* Canonicalize the dynamic relocation entries.  Note that we return the
70575796c8dcSSimon Schubert    dynamic relocations as a single block, although they are actually
70585796c8dcSSimon Schubert    associated with particular sections; the interface, which was
70595796c8dcSSimon Schubert    designed for SunOS style shared libraries, expects that there is only
70605796c8dcSSimon Schubert    one set of dynamic relocs.  Any loadable section that was actually
70615796c8dcSSimon Schubert    installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the
70625796c8dcSSimon Schubert    dynamic symbol table, is considered to be a dynamic reloc section.  */
70635796c8dcSSimon Schubert 
70645796c8dcSSimon Schubert long
_bfd_elf_canonicalize_dynamic_reloc(bfd * abfd,arelent ** storage,asymbol ** syms)70655796c8dcSSimon Schubert _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
70665796c8dcSSimon Schubert 				     arelent **storage,
70675796c8dcSSimon Schubert 				     asymbol **syms)
70685796c8dcSSimon Schubert {
70695796c8dcSSimon Schubert   bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
70705796c8dcSSimon Schubert   asection *s;
70715796c8dcSSimon Schubert   long ret;
70725796c8dcSSimon Schubert 
70735796c8dcSSimon Schubert   if (elf_dynsymtab (abfd) == 0)
70745796c8dcSSimon Schubert     {
70755796c8dcSSimon Schubert       bfd_set_error (bfd_error_invalid_operation);
70765796c8dcSSimon Schubert       return -1;
70775796c8dcSSimon Schubert     }
70785796c8dcSSimon Schubert 
70795796c8dcSSimon Schubert   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
70805796c8dcSSimon Schubert   ret = 0;
70815796c8dcSSimon Schubert   for (s = abfd->sections; s != NULL; s = s->next)
70825796c8dcSSimon Schubert     {
70835796c8dcSSimon Schubert       if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
70845796c8dcSSimon Schubert 	  && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
70855796c8dcSSimon Schubert 	      || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
70865796c8dcSSimon Schubert 	{
70875796c8dcSSimon Schubert 	  arelent *p;
70885796c8dcSSimon Schubert 	  long count, i;
70895796c8dcSSimon Schubert 
70905796c8dcSSimon Schubert 	  if (! (*slurp_relocs) (abfd, s, syms, TRUE))
70915796c8dcSSimon Schubert 	    return -1;
70925796c8dcSSimon Schubert 	  count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
70935796c8dcSSimon Schubert 	  p = s->relocation;
70945796c8dcSSimon Schubert 	  for (i = 0; i < count; i++)
70955796c8dcSSimon Schubert 	    *storage++ = p++;
70965796c8dcSSimon Schubert 	  ret += count;
70975796c8dcSSimon Schubert 	}
70985796c8dcSSimon Schubert     }
70995796c8dcSSimon Schubert 
71005796c8dcSSimon Schubert   *storage = NULL;
71015796c8dcSSimon Schubert 
71025796c8dcSSimon Schubert   return ret;
71035796c8dcSSimon Schubert }
71045796c8dcSSimon Schubert 
71055796c8dcSSimon Schubert /* Read in the version information.  */
71065796c8dcSSimon Schubert 
71075796c8dcSSimon Schubert bfd_boolean
_bfd_elf_slurp_version_tables(bfd * abfd,bfd_boolean default_imported_symver)71085796c8dcSSimon Schubert _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
71095796c8dcSSimon Schubert {
71105796c8dcSSimon Schubert   bfd_byte *contents = NULL;
71115796c8dcSSimon Schubert   unsigned int freeidx = 0;
71125796c8dcSSimon Schubert 
71135796c8dcSSimon Schubert   if (elf_dynverref (abfd) != 0)
71145796c8dcSSimon Schubert     {
71155796c8dcSSimon Schubert       Elf_Internal_Shdr *hdr;
71165796c8dcSSimon Schubert       Elf_External_Verneed *everneed;
71175796c8dcSSimon Schubert       Elf_Internal_Verneed *iverneed;
71185796c8dcSSimon Schubert       unsigned int i;
71195796c8dcSSimon Schubert       bfd_byte *contents_end;
71205796c8dcSSimon Schubert 
71215796c8dcSSimon Schubert       hdr = &elf_tdata (abfd)->dynverref_hdr;
71225796c8dcSSimon Schubert 
71235796c8dcSSimon Schubert       elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
71245796c8dcSSimon Schubert           bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
71255796c8dcSSimon Schubert       if (elf_tdata (abfd)->verref == NULL)
71265796c8dcSSimon Schubert 	goto error_return;
71275796c8dcSSimon Schubert 
71285796c8dcSSimon Schubert       elf_tdata (abfd)->cverrefs = hdr->sh_info;
71295796c8dcSSimon Schubert 
71305796c8dcSSimon Schubert       contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
71315796c8dcSSimon Schubert       if (contents == NULL)
71325796c8dcSSimon Schubert 	{
71335796c8dcSSimon Schubert error_return_verref:
71345796c8dcSSimon Schubert 	  elf_tdata (abfd)->verref = NULL;
71355796c8dcSSimon Schubert 	  elf_tdata (abfd)->cverrefs = 0;
71365796c8dcSSimon Schubert 	  goto error_return;
71375796c8dcSSimon Schubert 	}
71385796c8dcSSimon Schubert       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
71395796c8dcSSimon Schubert 	  || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
71405796c8dcSSimon Schubert 	goto error_return_verref;
71415796c8dcSSimon Schubert 
71425796c8dcSSimon Schubert       if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verneed))
71435796c8dcSSimon Schubert 	goto error_return_verref;
71445796c8dcSSimon Schubert 
71455796c8dcSSimon Schubert       BFD_ASSERT (sizeof (Elf_External_Verneed)
71465796c8dcSSimon Schubert 		  == sizeof (Elf_External_Vernaux));
71475796c8dcSSimon Schubert       contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
71485796c8dcSSimon Schubert       everneed = (Elf_External_Verneed *) contents;
71495796c8dcSSimon Schubert       iverneed = elf_tdata (abfd)->verref;
71505796c8dcSSimon Schubert       for (i = 0; i < hdr->sh_info; i++, iverneed++)
71515796c8dcSSimon Schubert 	{
71525796c8dcSSimon Schubert 	  Elf_External_Vernaux *evernaux;
71535796c8dcSSimon Schubert 	  Elf_Internal_Vernaux *ivernaux;
71545796c8dcSSimon Schubert 	  unsigned int j;
71555796c8dcSSimon Schubert 
71565796c8dcSSimon Schubert 	  _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
71575796c8dcSSimon Schubert 
71585796c8dcSSimon Schubert 	  iverneed->vn_bfd = abfd;
71595796c8dcSSimon Schubert 
71605796c8dcSSimon Schubert 	  iverneed->vn_filename =
71615796c8dcSSimon Schubert 	    bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
71625796c8dcSSimon Schubert 					     iverneed->vn_file);
71635796c8dcSSimon Schubert 	  if (iverneed->vn_filename == NULL)
71645796c8dcSSimon Schubert 	    goto error_return_verref;
71655796c8dcSSimon Schubert 
71665796c8dcSSimon Schubert 	  if (iverneed->vn_cnt == 0)
71675796c8dcSSimon Schubert 	    iverneed->vn_auxptr = NULL;
71685796c8dcSSimon Schubert 	  else
71695796c8dcSSimon Schubert 	    {
71705796c8dcSSimon Schubert 	      iverneed->vn_auxptr = (struct elf_internal_vernaux *)
71715796c8dcSSimon Schubert                   bfd_alloc2 (abfd, iverneed->vn_cnt,
71725796c8dcSSimon Schubert                               sizeof (Elf_Internal_Vernaux));
71735796c8dcSSimon Schubert 	      if (iverneed->vn_auxptr == NULL)
71745796c8dcSSimon Schubert 		goto error_return_verref;
71755796c8dcSSimon Schubert 	    }
71765796c8dcSSimon Schubert 
71775796c8dcSSimon Schubert 	  if (iverneed->vn_aux
71785796c8dcSSimon Schubert 	      > (size_t) (contents_end - (bfd_byte *) everneed))
71795796c8dcSSimon Schubert 	    goto error_return_verref;
71805796c8dcSSimon Schubert 
71815796c8dcSSimon Schubert 	  evernaux = ((Elf_External_Vernaux *)
71825796c8dcSSimon Schubert 		      ((bfd_byte *) everneed + iverneed->vn_aux));
71835796c8dcSSimon Schubert 	  ivernaux = iverneed->vn_auxptr;
71845796c8dcSSimon Schubert 	  for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
71855796c8dcSSimon Schubert 	    {
71865796c8dcSSimon Schubert 	      _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
71875796c8dcSSimon Schubert 
71885796c8dcSSimon Schubert 	      ivernaux->vna_nodename =
71895796c8dcSSimon Schubert 		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
71905796c8dcSSimon Schubert 						 ivernaux->vna_name);
71915796c8dcSSimon Schubert 	      if (ivernaux->vna_nodename == NULL)
71925796c8dcSSimon Schubert 		goto error_return_verref;
71935796c8dcSSimon Schubert 
71945796c8dcSSimon Schubert 	      if (j + 1 < iverneed->vn_cnt)
71955796c8dcSSimon Schubert 		ivernaux->vna_nextptr = ivernaux + 1;
71965796c8dcSSimon Schubert 	      else
71975796c8dcSSimon Schubert 		ivernaux->vna_nextptr = NULL;
71985796c8dcSSimon Schubert 
71995796c8dcSSimon Schubert 	      if (ivernaux->vna_next
72005796c8dcSSimon Schubert 		  > (size_t) (contents_end - (bfd_byte *) evernaux))
72015796c8dcSSimon Schubert 		goto error_return_verref;
72025796c8dcSSimon Schubert 
72035796c8dcSSimon Schubert 	      evernaux = ((Elf_External_Vernaux *)
72045796c8dcSSimon Schubert 			  ((bfd_byte *) evernaux + ivernaux->vna_next));
72055796c8dcSSimon Schubert 
72065796c8dcSSimon Schubert 	      if (ivernaux->vna_other > freeidx)
72075796c8dcSSimon Schubert 		freeidx = ivernaux->vna_other;
72085796c8dcSSimon Schubert 	    }
72095796c8dcSSimon Schubert 
72105796c8dcSSimon Schubert 	  if (i + 1 < hdr->sh_info)
72115796c8dcSSimon Schubert 	    iverneed->vn_nextref = iverneed + 1;
72125796c8dcSSimon Schubert 	  else
72135796c8dcSSimon Schubert 	    iverneed->vn_nextref = NULL;
72145796c8dcSSimon Schubert 
72155796c8dcSSimon Schubert 	  if (iverneed->vn_next
72165796c8dcSSimon Schubert 	      > (size_t) (contents_end - (bfd_byte *) everneed))
72175796c8dcSSimon Schubert 	    goto error_return_verref;
72185796c8dcSSimon Schubert 
72195796c8dcSSimon Schubert 	  everneed = ((Elf_External_Verneed *)
72205796c8dcSSimon Schubert 		      ((bfd_byte *) everneed + iverneed->vn_next));
72215796c8dcSSimon Schubert 	}
72225796c8dcSSimon Schubert 
72235796c8dcSSimon Schubert       free (contents);
72245796c8dcSSimon Schubert       contents = NULL;
72255796c8dcSSimon Schubert     }
72265796c8dcSSimon Schubert 
72275796c8dcSSimon Schubert   if (elf_dynverdef (abfd) != 0)
72285796c8dcSSimon Schubert     {
72295796c8dcSSimon Schubert       Elf_Internal_Shdr *hdr;
72305796c8dcSSimon Schubert       Elf_External_Verdef *everdef;
72315796c8dcSSimon Schubert       Elf_Internal_Verdef *iverdef;
72325796c8dcSSimon Schubert       Elf_Internal_Verdef *iverdefarr;
72335796c8dcSSimon Schubert       Elf_Internal_Verdef iverdefmem;
72345796c8dcSSimon Schubert       unsigned int i;
72355796c8dcSSimon Schubert       unsigned int maxidx;
72365796c8dcSSimon Schubert       bfd_byte *contents_end_def, *contents_end_aux;
72375796c8dcSSimon Schubert 
72385796c8dcSSimon Schubert       hdr = &elf_tdata (abfd)->dynverdef_hdr;
72395796c8dcSSimon Schubert 
72405796c8dcSSimon Schubert       contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
72415796c8dcSSimon Schubert       if (contents == NULL)
72425796c8dcSSimon Schubert 	goto error_return;
72435796c8dcSSimon Schubert       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
72445796c8dcSSimon Schubert 	  || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
72455796c8dcSSimon Schubert 	goto error_return;
72465796c8dcSSimon Schubert 
72475796c8dcSSimon Schubert       if (hdr->sh_info && hdr->sh_size < sizeof (Elf_External_Verdef))
72485796c8dcSSimon Schubert 	goto error_return;
72495796c8dcSSimon Schubert 
72505796c8dcSSimon Schubert       BFD_ASSERT (sizeof (Elf_External_Verdef)
72515796c8dcSSimon Schubert 		  >= sizeof (Elf_External_Verdaux));
72525796c8dcSSimon Schubert       contents_end_def = contents + hdr->sh_size
72535796c8dcSSimon Schubert 			 - sizeof (Elf_External_Verdef);
72545796c8dcSSimon Schubert       contents_end_aux = contents + hdr->sh_size
72555796c8dcSSimon Schubert 			 - sizeof (Elf_External_Verdaux);
72565796c8dcSSimon Schubert 
72575796c8dcSSimon Schubert       /* We know the number of entries in the section but not the maximum
72585796c8dcSSimon Schubert 	 index.  Therefore we have to run through all entries and find
72595796c8dcSSimon Schubert 	 the maximum.  */
72605796c8dcSSimon Schubert       everdef = (Elf_External_Verdef *) contents;
72615796c8dcSSimon Schubert       maxidx = 0;
72625796c8dcSSimon Schubert       for (i = 0; i < hdr->sh_info; ++i)
72635796c8dcSSimon Schubert 	{
72645796c8dcSSimon Schubert 	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
72655796c8dcSSimon Schubert 
72665796c8dcSSimon Schubert 	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
72675796c8dcSSimon Schubert 	    maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
72685796c8dcSSimon Schubert 
72695796c8dcSSimon Schubert 	  if (iverdefmem.vd_next
72705796c8dcSSimon Schubert 	      > (size_t) (contents_end_def - (bfd_byte *) everdef))
72715796c8dcSSimon Schubert 	    goto error_return;
72725796c8dcSSimon Schubert 
72735796c8dcSSimon Schubert 	  everdef = ((Elf_External_Verdef *)
72745796c8dcSSimon Schubert 		     ((bfd_byte *) everdef + iverdefmem.vd_next));
72755796c8dcSSimon Schubert 	}
72765796c8dcSSimon Schubert 
72775796c8dcSSimon Schubert       if (default_imported_symver)
72785796c8dcSSimon Schubert 	{
72795796c8dcSSimon Schubert 	  if (freeidx > maxidx)
72805796c8dcSSimon Schubert 	    maxidx = ++freeidx;
72815796c8dcSSimon Schubert 	  else
72825796c8dcSSimon Schubert 	    freeidx = ++maxidx;
72835796c8dcSSimon Schubert 	}
72845796c8dcSSimon Schubert       elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
72855796c8dcSSimon Schubert           bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef));
72865796c8dcSSimon Schubert       if (elf_tdata (abfd)->verdef == NULL)
72875796c8dcSSimon Schubert 	goto error_return;
72885796c8dcSSimon Schubert 
72895796c8dcSSimon Schubert       elf_tdata (abfd)->cverdefs = maxidx;
72905796c8dcSSimon Schubert 
72915796c8dcSSimon Schubert       everdef = (Elf_External_Verdef *) contents;
72925796c8dcSSimon Schubert       iverdefarr = elf_tdata (abfd)->verdef;
72935796c8dcSSimon Schubert       for (i = 0; i < hdr->sh_info; i++)
72945796c8dcSSimon Schubert 	{
72955796c8dcSSimon Schubert 	  Elf_External_Verdaux *everdaux;
72965796c8dcSSimon Schubert 	  Elf_Internal_Verdaux *iverdaux;
72975796c8dcSSimon Schubert 	  unsigned int j;
72985796c8dcSSimon Schubert 
72995796c8dcSSimon Schubert 	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
73005796c8dcSSimon Schubert 
73015796c8dcSSimon Schubert 	  if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
73025796c8dcSSimon Schubert 	    {
73035796c8dcSSimon Schubert error_return_verdef:
73045796c8dcSSimon Schubert 	      elf_tdata (abfd)->verdef = NULL;
73055796c8dcSSimon Schubert 	      elf_tdata (abfd)->cverdefs = 0;
73065796c8dcSSimon Schubert 	      goto error_return;
73075796c8dcSSimon Schubert 	    }
73085796c8dcSSimon Schubert 
73095796c8dcSSimon Schubert 	  iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
73105796c8dcSSimon Schubert 	  memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
73115796c8dcSSimon Schubert 
73125796c8dcSSimon Schubert 	  iverdef->vd_bfd = abfd;
73135796c8dcSSimon Schubert 
73145796c8dcSSimon Schubert 	  if (iverdef->vd_cnt == 0)
73155796c8dcSSimon Schubert 	    iverdef->vd_auxptr = NULL;
73165796c8dcSSimon Schubert 	  else
73175796c8dcSSimon Schubert 	    {
73185796c8dcSSimon Schubert 	      iverdef->vd_auxptr = (struct elf_internal_verdaux *)
73195796c8dcSSimon Schubert                   bfd_alloc2 (abfd, iverdef->vd_cnt,
73205796c8dcSSimon Schubert                               sizeof (Elf_Internal_Verdaux));
73215796c8dcSSimon Schubert 	      if (iverdef->vd_auxptr == NULL)
73225796c8dcSSimon Schubert 		goto error_return_verdef;
73235796c8dcSSimon Schubert 	    }
73245796c8dcSSimon Schubert 
73255796c8dcSSimon Schubert 	  if (iverdef->vd_aux
73265796c8dcSSimon Schubert 	      > (size_t) (contents_end_aux - (bfd_byte *) everdef))
73275796c8dcSSimon Schubert 	    goto error_return_verdef;
73285796c8dcSSimon Schubert 
73295796c8dcSSimon Schubert 	  everdaux = ((Elf_External_Verdaux *)
73305796c8dcSSimon Schubert 		      ((bfd_byte *) everdef + iverdef->vd_aux));
73315796c8dcSSimon Schubert 	  iverdaux = iverdef->vd_auxptr;
73325796c8dcSSimon Schubert 	  for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
73335796c8dcSSimon Schubert 	    {
73345796c8dcSSimon Schubert 	      _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);
73355796c8dcSSimon Schubert 
73365796c8dcSSimon Schubert 	      iverdaux->vda_nodename =
73375796c8dcSSimon Schubert 		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
73385796c8dcSSimon Schubert 						 iverdaux->vda_name);
73395796c8dcSSimon Schubert 	      if (iverdaux->vda_nodename == NULL)
73405796c8dcSSimon Schubert 		goto error_return_verdef;
73415796c8dcSSimon Schubert 
73425796c8dcSSimon Schubert 	      if (j + 1 < iverdef->vd_cnt)
73435796c8dcSSimon Schubert 		iverdaux->vda_nextptr = iverdaux + 1;
73445796c8dcSSimon Schubert 	      else
73455796c8dcSSimon Schubert 		iverdaux->vda_nextptr = NULL;
73465796c8dcSSimon Schubert 
73475796c8dcSSimon Schubert 	      if (iverdaux->vda_next
73485796c8dcSSimon Schubert 		  > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
73495796c8dcSSimon Schubert 		goto error_return_verdef;
73505796c8dcSSimon Schubert 
73515796c8dcSSimon Schubert 	      everdaux = ((Elf_External_Verdaux *)
73525796c8dcSSimon Schubert 			  ((bfd_byte *) everdaux + iverdaux->vda_next));
73535796c8dcSSimon Schubert 	    }
73545796c8dcSSimon Schubert 
73555796c8dcSSimon Schubert 	  if (iverdef->vd_cnt)
73565796c8dcSSimon Schubert 	    iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
73575796c8dcSSimon Schubert 
73585796c8dcSSimon Schubert 	  if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
73595796c8dcSSimon Schubert 	    iverdef->vd_nextdef = iverdef + 1;
73605796c8dcSSimon Schubert 	  else
73615796c8dcSSimon Schubert 	    iverdef->vd_nextdef = NULL;
73625796c8dcSSimon Schubert 
73635796c8dcSSimon Schubert 	  everdef = ((Elf_External_Verdef *)
73645796c8dcSSimon Schubert 		     ((bfd_byte *) everdef + iverdef->vd_next));
73655796c8dcSSimon Schubert 	}
73665796c8dcSSimon Schubert 
73675796c8dcSSimon Schubert       free (contents);
73685796c8dcSSimon Schubert       contents = NULL;
73695796c8dcSSimon Schubert     }
73705796c8dcSSimon Schubert   else if (default_imported_symver)
73715796c8dcSSimon Schubert     {
73725796c8dcSSimon Schubert       if (freeidx < 3)
73735796c8dcSSimon Schubert 	freeidx = 3;
73745796c8dcSSimon Schubert       else
73755796c8dcSSimon Schubert 	freeidx++;
73765796c8dcSSimon Schubert 
73775796c8dcSSimon Schubert       elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
73785796c8dcSSimon Schubert           bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef));
73795796c8dcSSimon Schubert       if (elf_tdata (abfd)->verdef == NULL)
73805796c8dcSSimon Schubert 	goto error_return;
73815796c8dcSSimon Schubert 
73825796c8dcSSimon Schubert       elf_tdata (abfd)->cverdefs = freeidx;
73835796c8dcSSimon Schubert     }
73845796c8dcSSimon Schubert 
73855796c8dcSSimon Schubert   /* Create a default version based on the soname.  */
73865796c8dcSSimon Schubert   if (default_imported_symver)
73875796c8dcSSimon Schubert     {
73885796c8dcSSimon Schubert       Elf_Internal_Verdef *iverdef;
73895796c8dcSSimon Schubert       Elf_Internal_Verdaux *iverdaux;
73905796c8dcSSimon Schubert 
7391*ef5ccd6cSJohn Marino       iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];
73925796c8dcSSimon Schubert 
73935796c8dcSSimon Schubert       iverdef->vd_version = VER_DEF_CURRENT;
73945796c8dcSSimon Schubert       iverdef->vd_flags = 0;
73955796c8dcSSimon Schubert       iverdef->vd_ndx = freeidx;
73965796c8dcSSimon Schubert       iverdef->vd_cnt = 1;
73975796c8dcSSimon Schubert 
73985796c8dcSSimon Schubert       iverdef->vd_bfd = abfd;
73995796c8dcSSimon Schubert 
74005796c8dcSSimon Schubert       iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
74015796c8dcSSimon Schubert       if (iverdef->vd_nodename == NULL)
74025796c8dcSSimon Schubert 	goto error_return_verdef;
74035796c8dcSSimon Schubert       iverdef->vd_nextdef = NULL;
74045796c8dcSSimon Schubert       iverdef->vd_auxptr = (struct elf_internal_verdaux *)
74055796c8dcSSimon Schubert           bfd_alloc (abfd, sizeof (Elf_Internal_Verdaux));
74065796c8dcSSimon Schubert       if (iverdef->vd_auxptr == NULL)
74075796c8dcSSimon Schubert 	goto error_return_verdef;
74085796c8dcSSimon Schubert 
74095796c8dcSSimon Schubert       iverdaux = iverdef->vd_auxptr;
74105796c8dcSSimon Schubert       iverdaux->vda_nodename = iverdef->vd_nodename;
74115796c8dcSSimon Schubert       iverdaux->vda_nextptr = NULL;
74125796c8dcSSimon Schubert     }
74135796c8dcSSimon Schubert 
74145796c8dcSSimon Schubert   return TRUE;
74155796c8dcSSimon Schubert 
74165796c8dcSSimon Schubert  error_return:
74175796c8dcSSimon Schubert   if (contents != NULL)
74185796c8dcSSimon Schubert     free (contents);
74195796c8dcSSimon Schubert   return FALSE;
74205796c8dcSSimon Schubert }
74215796c8dcSSimon Schubert 
74225796c8dcSSimon Schubert asymbol *
_bfd_elf_make_empty_symbol(bfd * abfd)74235796c8dcSSimon Schubert _bfd_elf_make_empty_symbol (bfd *abfd)
74245796c8dcSSimon Schubert {
74255796c8dcSSimon Schubert   elf_symbol_type *newsym;
74265796c8dcSSimon Schubert   bfd_size_type amt = sizeof (elf_symbol_type);
74275796c8dcSSimon Schubert 
74285796c8dcSSimon Schubert   newsym = (elf_symbol_type *) bfd_zalloc (abfd, amt);
74295796c8dcSSimon Schubert   if (!newsym)
74305796c8dcSSimon Schubert     return NULL;
74315796c8dcSSimon Schubert   else
74325796c8dcSSimon Schubert     {
74335796c8dcSSimon Schubert       newsym->symbol.the_bfd = abfd;
74345796c8dcSSimon Schubert       return &newsym->symbol;
74355796c8dcSSimon Schubert     }
74365796c8dcSSimon Schubert }
74375796c8dcSSimon Schubert 
74385796c8dcSSimon Schubert void
_bfd_elf_get_symbol_info(bfd * abfd ATTRIBUTE_UNUSED,asymbol * symbol,symbol_info * ret)74395796c8dcSSimon Schubert _bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
74405796c8dcSSimon Schubert 			  asymbol *symbol,
74415796c8dcSSimon Schubert 			  symbol_info *ret)
74425796c8dcSSimon Schubert {
74435796c8dcSSimon Schubert   bfd_symbol_info (symbol, ret);
74445796c8dcSSimon Schubert }
74455796c8dcSSimon Schubert 
74465796c8dcSSimon Schubert /* Return whether a symbol name implies a local symbol.  Most targets
74475796c8dcSSimon Schubert    use this function for the is_local_label_name entry point, but some
74485796c8dcSSimon Schubert    override it.  */
74495796c8dcSSimon Schubert 
74505796c8dcSSimon Schubert bfd_boolean
_bfd_elf_is_local_label_name(bfd * abfd ATTRIBUTE_UNUSED,const char * name)74515796c8dcSSimon Schubert _bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
74525796c8dcSSimon Schubert 			      const char *name)
74535796c8dcSSimon Schubert {
74545796c8dcSSimon Schubert   /* Normal local symbols start with ``.L''.  */
74555796c8dcSSimon Schubert   if (name[0] == '.' && name[1] == 'L')
74565796c8dcSSimon Schubert     return TRUE;
74575796c8dcSSimon Schubert 
74585796c8dcSSimon Schubert   /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
74595796c8dcSSimon Schubert      DWARF debugging symbols starting with ``..''.  */
74605796c8dcSSimon Schubert   if (name[0] == '.' && name[1] == '.')
74615796c8dcSSimon Schubert     return TRUE;
74625796c8dcSSimon Schubert 
74635796c8dcSSimon Schubert   /* gcc will sometimes generate symbols beginning with ``_.L_'' when
74645796c8dcSSimon Schubert      emitting DWARF debugging output.  I suspect this is actually a
74655796c8dcSSimon Schubert      small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
74665796c8dcSSimon Schubert      ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
74675796c8dcSSimon Schubert      underscore to be emitted on some ELF targets).  For ease of use,
74685796c8dcSSimon Schubert      we treat such symbols as local.  */
74695796c8dcSSimon Schubert   if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
74705796c8dcSSimon Schubert     return TRUE;
74715796c8dcSSimon Schubert 
74725796c8dcSSimon Schubert   return FALSE;
74735796c8dcSSimon Schubert }
74745796c8dcSSimon Schubert 
74755796c8dcSSimon Schubert alent *
_bfd_elf_get_lineno(bfd * abfd ATTRIBUTE_UNUSED,asymbol * symbol ATTRIBUTE_UNUSED)74765796c8dcSSimon Schubert _bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED,
74775796c8dcSSimon Schubert 		     asymbol *symbol ATTRIBUTE_UNUSED)
74785796c8dcSSimon Schubert {
74795796c8dcSSimon Schubert   abort ();
74805796c8dcSSimon Schubert   return NULL;
74815796c8dcSSimon Schubert }
74825796c8dcSSimon Schubert 
74835796c8dcSSimon Schubert bfd_boolean
_bfd_elf_set_arch_mach(bfd * abfd,enum bfd_architecture arch,unsigned long machine)74845796c8dcSSimon Schubert _bfd_elf_set_arch_mach (bfd *abfd,
74855796c8dcSSimon Schubert 			enum bfd_architecture arch,
74865796c8dcSSimon Schubert 			unsigned long machine)
74875796c8dcSSimon Schubert {
74885796c8dcSSimon Schubert   /* If this isn't the right architecture for this backend, and this
74895796c8dcSSimon Schubert      isn't the generic backend, fail.  */
74905796c8dcSSimon Schubert   if (arch != get_elf_backend_data (abfd)->arch
74915796c8dcSSimon Schubert       && arch != bfd_arch_unknown
74925796c8dcSSimon Schubert       && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
74935796c8dcSSimon Schubert     return FALSE;
74945796c8dcSSimon Schubert 
74955796c8dcSSimon Schubert   return bfd_default_set_arch_mach (abfd, arch, machine);
74965796c8dcSSimon Schubert }
74975796c8dcSSimon Schubert 
74985796c8dcSSimon Schubert /* Find the function to a particular section and offset,
74995796c8dcSSimon Schubert    for error reporting.  */
75005796c8dcSSimon Schubert 
75015796c8dcSSimon Schubert static bfd_boolean
elf_find_function(bfd * abfd,asection * section,asymbol ** symbols,bfd_vma offset,const char ** filename_ptr,const char ** functionname_ptr)75025796c8dcSSimon Schubert elf_find_function (bfd *abfd,
75035796c8dcSSimon Schubert 		   asection *section,
75045796c8dcSSimon Schubert 		   asymbol **symbols,
75055796c8dcSSimon Schubert 		   bfd_vma offset,
75065796c8dcSSimon Schubert 		   const char **filename_ptr,
75075796c8dcSSimon Schubert 		   const char **functionname_ptr)
75085796c8dcSSimon Schubert {
7509*ef5ccd6cSJohn Marino   struct elf_find_function_cache
7510*ef5ccd6cSJohn Marino   {
7511*ef5ccd6cSJohn Marino     asection *last_section;
7512*ef5ccd6cSJohn Marino     asymbol *func;
75135796c8dcSSimon Schubert     const char *filename;
7514*ef5ccd6cSJohn Marino     bfd_size_type func_size;
7515*ef5ccd6cSJohn Marino   } *cache;
7516*ef5ccd6cSJohn Marino 
7517*ef5ccd6cSJohn Marino   if (symbols == NULL)
7518*ef5ccd6cSJohn Marino     return FALSE;
7519*ef5ccd6cSJohn Marino 
7520*ef5ccd6cSJohn Marino   cache = elf_tdata (abfd)->elf_find_function_cache;
7521*ef5ccd6cSJohn Marino   if (cache == NULL)
7522*ef5ccd6cSJohn Marino     {
7523*ef5ccd6cSJohn Marino       cache = bfd_zalloc (abfd, sizeof (*cache));
7524*ef5ccd6cSJohn Marino       elf_tdata (abfd)->elf_find_function_cache = cache;
7525*ef5ccd6cSJohn Marino       if (cache == NULL)
7526*ef5ccd6cSJohn Marino 	return FALSE;
7527*ef5ccd6cSJohn Marino     }
7528*ef5ccd6cSJohn Marino   if (cache->last_section != section
7529*ef5ccd6cSJohn Marino       || cache->func == NULL
7530*ef5ccd6cSJohn Marino       || offset < cache->func->value
7531*ef5ccd6cSJohn Marino       || offset >= cache->func->value + cache->func_size)
7532*ef5ccd6cSJohn Marino     {
7533*ef5ccd6cSJohn Marino       asymbol *file;
75345796c8dcSSimon Schubert       bfd_vma low_func;
75355796c8dcSSimon Schubert       asymbol **p;
75365796c8dcSSimon Schubert       /* ??? Given multiple file symbols, it is impossible to reliably
75375796c8dcSSimon Schubert 	 choose the right file name for global symbols.  File symbols are
75385796c8dcSSimon Schubert 	 local symbols, and thus all file symbols must sort before any
75395796c8dcSSimon Schubert 	 global symbols.  The ELF spec may be interpreted to say that a
75405796c8dcSSimon Schubert 	 file symbol must sort before other local symbols, but currently
75415796c8dcSSimon Schubert 	 ld -r doesn't do this.  So, for ld -r output, it is possible to
75425796c8dcSSimon Schubert 	 make a better choice of file name for local symbols by ignoring
75435796c8dcSSimon Schubert 	 file symbols appearing after a given local symbol.  */
75445796c8dcSSimon Schubert       enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
75455796c8dcSSimon Schubert       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
75465796c8dcSSimon Schubert 
75475796c8dcSSimon Schubert       file = NULL;
75485796c8dcSSimon Schubert       low_func = 0;
75495796c8dcSSimon Schubert       state = nothing_seen;
7550*ef5ccd6cSJohn Marino       cache->filename = NULL;
7551*ef5ccd6cSJohn Marino       cache->func = NULL;
7552*ef5ccd6cSJohn Marino       cache->func_size = 0;
7553*ef5ccd6cSJohn Marino       cache->last_section = section;
75545796c8dcSSimon Schubert 
75555796c8dcSSimon Schubert       for (p = symbols; *p != NULL; p++)
75565796c8dcSSimon Schubert 	{
7557*ef5ccd6cSJohn Marino 	  asymbol *sym = *p;
7558*ef5ccd6cSJohn Marino 	  bfd_vma code_off;
7559*ef5ccd6cSJohn Marino 	  bfd_size_type size;
75605796c8dcSSimon Schubert 
7561*ef5ccd6cSJohn Marino 	  if ((sym->flags & BSF_FILE) != 0)
75625796c8dcSSimon Schubert 	    {
7563*ef5ccd6cSJohn Marino 	      file = sym;
75645796c8dcSSimon Schubert 	      if (state == symbol_seen)
75655796c8dcSSimon Schubert 		state = file_after_symbol_seen;
75665796c8dcSSimon Schubert 	      continue;
75675796c8dcSSimon Schubert 	    }
7568*ef5ccd6cSJohn Marino 
7569*ef5ccd6cSJohn Marino 	  size = bed->maybe_function_sym (sym, section, &code_off);
7570*ef5ccd6cSJohn Marino 	  if (size != 0
7571*ef5ccd6cSJohn Marino 	      && code_off <= offset
7572*ef5ccd6cSJohn Marino 	      && (code_off > low_func
7573*ef5ccd6cSJohn Marino 		  || (code_off == low_func
7574*ef5ccd6cSJohn Marino 		      && size > cache->func_size)))
7575*ef5ccd6cSJohn Marino 	    {
7576*ef5ccd6cSJohn Marino 	      cache->func = sym;
7577*ef5ccd6cSJohn Marino 	      cache->func_size = size;
7578*ef5ccd6cSJohn Marino 	      cache->filename = NULL;
7579*ef5ccd6cSJohn Marino 	      low_func = code_off;
7580*ef5ccd6cSJohn Marino 	      if (file != NULL
7581*ef5ccd6cSJohn Marino 		  && ((sym->flags & BSF_LOCAL) != 0
7582*ef5ccd6cSJohn Marino 		      || state != file_after_symbol_seen))
7583*ef5ccd6cSJohn Marino 		cache->filename = bfd_asymbol_name (file);
75845796c8dcSSimon Schubert 	    }
75855796c8dcSSimon Schubert 	  if (state == nothing_seen)
75865796c8dcSSimon Schubert 	    state = symbol_seen;
75875796c8dcSSimon Schubert 	}
7588*ef5ccd6cSJohn Marino     }
75895796c8dcSSimon Schubert 
7590*ef5ccd6cSJohn Marino   if (cache->func == NULL)
75915796c8dcSSimon Schubert     return FALSE;
75925796c8dcSSimon Schubert 
75935796c8dcSSimon Schubert   if (filename_ptr)
7594*ef5ccd6cSJohn Marino     *filename_ptr = cache->filename;
75955796c8dcSSimon Schubert   if (functionname_ptr)
7596*ef5ccd6cSJohn Marino     *functionname_ptr = bfd_asymbol_name (cache->func);
75975796c8dcSSimon Schubert 
75985796c8dcSSimon Schubert   return TRUE;
75995796c8dcSSimon Schubert }
76005796c8dcSSimon Schubert 
76015796c8dcSSimon Schubert /* Find the nearest line to a particular section and offset,
76025796c8dcSSimon Schubert    for error reporting.  */
76035796c8dcSSimon Schubert 
76045796c8dcSSimon Schubert bfd_boolean
_bfd_elf_find_nearest_line(bfd * abfd,asection * section,asymbol ** symbols,bfd_vma offset,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * line_ptr)76055796c8dcSSimon Schubert _bfd_elf_find_nearest_line (bfd *abfd,
76065796c8dcSSimon Schubert 			    asection *section,
76075796c8dcSSimon Schubert 			    asymbol **symbols,
76085796c8dcSSimon Schubert 			    bfd_vma offset,
76095796c8dcSSimon Schubert 			    const char **filename_ptr,
76105796c8dcSSimon Schubert 			    const char **functionname_ptr,
76115796c8dcSSimon Schubert 			    unsigned int *line_ptr)
76125796c8dcSSimon Schubert {
7613*ef5ccd6cSJohn Marino   return _bfd_elf_find_nearest_line_discriminator (abfd, section, symbols,
7614*ef5ccd6cSJohn Marino                                                    offset, filename_ptr,
7615*ef5ccd6cSJohn Marino                                                    functionname_ptr,
7616*ef5ccd6cSJohn Marino                                                    line_ptr,
7617*ef5ccd6cSJohn Marino                                                    NULL);
7618*ef5ccd6cSJohn Marino }
7619*ef5ccd6cSJohn Marino 
7620*ef5ccd6cSJohn Marino bfd_boolean
_bfd_elf_find_nearest_line_discriminator(bfd * abfd,asection * section,asymbol ** symbols,bfd_vma offset,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * line_ptr,unsigned int * discriminator_ptr)7621*ef5ccd6cSJohn Marino _bfd_elf_find_nearest_line_discriminator (bfd *abfd,
7622*ef5ccd6cSJohn Marino                                           asection *section,
7623*ef5ccd6cSJohn Marino                                           asymbol **symbols,
7624*ef5ccd6cSJohn Marino                                           bfd_vma offset,
7625*ef5ccd6cSJohn Marino                                           const char **filename_ptr,
7626*ef5ccd6cSJohn Marino                                           const char **functionname_ptr,
7627*ef5ccd6cSJohn Marino                                           unsigned int *line_ptr,
7628*ef5ccd6cSJohn Marino                                           unsigned int *discriminator_ptr)
7629*ef5ccd6cSJohn Marino {
76305796c8dcSSimon Schubert   bfd_boolean found;
76315796c8dcSSimon Schubert 
76325796c8dcSSimon Schubert   if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
76335796c8dcSSimon Schubert 				     filename_ptr, functionname_ptr,
76345796c8dcSSimon Schubert 				     line_ptr))
76355796c8dcSSimon Schubert     {
76365796c8dcSSimon Schubert       if (!*functionname_ptr)
76375796c8dcSSimon Schubert 	elf_find_function (abfd, section, symbols, offset,
76385796c8dcSSimon Schubert 			   *filename_ptr ? NULL : filename_ptr,
76395796c8dcSSimon Schubert 			   functionname_ptr);
76405796c8dcSSimon Schubert 
76415796c8dcSSimon Schubert       return TRUE;
76425796c8dcSSimon Schubert     }
76435796c8dcSSimon Schubert 
7644a45ae5f8SJohn Marino   if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
7645a45ae5f8SJohn Marino                                      section, symbols, offset,
76465796c8dcSSimon Schubert 				     filename_ptr, functionname_ptr,
7647*ef5ccd6cSJohn Marino 				     line_ptr, discriminator_ptr, 0,
76485796c8dcSSimon Schubert 				     &elf_tdata (abfd)->dwarf2_find_line_info))
76495796c8dcSSimon Schubert     {
76505796c8dcSSimon Schubert       if (!*functionname_ptr)
76515796c8dcSSimon Schubert 	elf_find_function (abfd, section, symbols, offset,
76525796c8dcSSimon Schubert 			   *filename_ptr ? NULL : filename_ptr,
76535796c8dcSSimon Schubert 			   functionname_ptr);
76545796c8dcSSimon Schubert 
76555796c8dcSSimon Schubert       return TRUE;
76565796c8dcSSimon Schubert     }
76575796c8dcSSimon Schubert 
76585796c8dcSSimon Schubert   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
76595796c8dcSSimon Schubert 					     &found, filename_ptr,
76605796c8dcSSimon Schubert 					     functionname_ptr, line_ptr,
76615796c8dcSSimon Schubert 					     &elf_tdata (abfd)->line_info))
76625796c8dcSSimon Schubert     return FALSE;
76635796c8dcSSimon Schubert   if (found && (*functionname_ptr || *line_ptr))
76645796c8dcSSimon Schubert     return TRUE;
76655796c8dcSSimon Schubert 
76665796c8dcSSimon Schubert   if (symbols == NULL)
76675796c8dcSSimon Schubert     return FALSE;
76685796c8dcSSimon Schubert 
76695796c8dcSSimon Schubert   if (! elf_find_function (abfd, section, symbols, offset,
76705796c8dcSSimon Schubert 			   filename_ptr, functionname_ptr))
76715796c8dcSSimon Schubert     return FALSE;
76725796c8dcSSimon Schubert 
76735796c8dcSSimon Schubert   *line_ptr = 0;
76745796c8dcSSimon Schubert   return TRUE;
76755796c8dcSSimon Schubert }
76765796c8dcSSimon Schubert 
76775796c8dcSSimon Schubert /* Find the line for a symbol.  */
76785796c8dcSSimon Schubert 
76795796c8dcSSimon Schubert bfd_boolean
_bfd_elf_find_line(bfd * abfd,asymbol ** symbols,asymbol * symbol,const char ** filename_ptr,unsigned int * line_ptr)76805796c8dcSSimon Schubert _bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
76815796c8dcSSimon Schubert 		    const char **filename_ptr, unsigned int *line_ptr)
76825796c8dcSSimon Schubert {
7683*ef5ccd6cSJohn Marino   return _bfd_elf_find_line_discriminator (abfd, symbols, symbol,
7684*ef5ccd6cSJohn Marino 		                           filename_ptr, line_ptr,
7685*ef5ccd6cSJohn Marino                                            NULL);
7686*ef5ccd6cSJohn Marino }
7687*ef5ccd6cSJohn Marino 
7688*ef5ccd6cSJohn Marino bfd_boolean
_bfd_elf_find_line_discriminator(bfd * abfd,asymbol ** symbols,asymbol * symbol,const char ** filename_ptr,unsigned int * line_ptr,unsigned int * discriminator_ptr)7689*ef5ccd6cSJohn Marino _bfd_elf_find_line_discriminator (bfd *abfd, asymbol **symbols, asymbol *symbol,
7690*ef5ccd6cSJohn Marino                                   const char **filename_ptr,
7691*ef5ccd6cSJohn Marino                                   unsigned int *line_ptr,
7692*ef5ccd6cSJohn Marino                                   unsigned int *discriminator_ptr)
7693*ef5ccd6cSJohn Marino {
76945796c8dcSSimon Schubert   return _bfd_dwarf2_find_line (abfd, symbols, symbol,
7695*ef5ccd6cSJohn Marino 				filename_ptr, line_ptr, discriminator_ptr, 0,
76965796c8dcSSimon Schubert 				&elf_tdata (abfd)->dwarf2_find_line_info);
76975796c8dcSSimon Schubert }
76985796c8dcSSimon Schubert 
76995796c8dcSSimon Schubert /* After a call to bfd_find_nearest_line, successive calls to
77005796c8dcSSimon Schubert    bfd_find_inliner_info can be used to get source information about
77015796c8dcSSimon Schubert    each level of function inlining that terminated at the address
77025796c8dcSSimon Schubert    passed to bfd_find_nearest_line.  Currently this is only supported
77035796c8dcSSimon Schubert    for DWARF2 with appropriate DWARF3 extensions. */
77045796c8dcSSimon Schubert 
77055796c8dcSSimon Schubert bfd_boolean
_bfd_elf_find_inliner_info(bfd * abfd,const char ** filename_ptr,const char ** functionname_ptr,unsigned int * line_ptr)77065796c8dcSSimon Schubert _bfd_elf_find_inliner_info (bfd *abfd,
77075796c8dcSSimon Schubert 			    const char **filename_ptr,
77085796c8dcSSimon Schubert 			    const char **functionname_ptr,
77095796c8dcSSimon Schubert 			    unsigned int *line_ptr)
77105796c8dcSSimon Schubert {
77115796c8dcSSimon Schubert   bfd_boolean found;
77125796c8dcSSimon Schubert   found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
77135796c8dcSSimon Schubert 					 functionname_ptr, line_ptr,
77145796c8dcSSimon Schubert 					 & elf_tdata (abfd)->dwarf2_find_line_info);
77155796c8dcSSimon Schubert   return found;
77165796c8dcSSimon Schubert }
77175796c8dcSSimon Schubert 
77185796c8dcSSimon Schubert int
_bfd_elf_sizeof_headers(bfd * abfd,struct bfd_link_info * info)77195796c8dcSSimon Schubert _bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
77205796c8dcSSimon Schubert {
77215796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
77225796c8dcSSimon Schubert   int ret = bed->s->sizeof_ehdr;
77235796c8dcSSimon Schubert 
77245796c8dcSSimon Schubert   if (!info->relocatable)
77255796c8dcSSimon Schubert     {
7726*ef5ccd6cSJohn Marino       bfd_size_type phdr_size = elf_program_header_size (abfd);
77275796c8dcSSimon Schubert 
77285796c8dcSSimon Schubert       if (phdr_size == (bfd_size_type) -1)
77295796c8dcSSimon Schubert 	{
77305796c8dcSSimon Schubert 	  struct elf_segment_map *m;
77315796c8dcSSimon Schubert 
77325796c8dcSSimon Schubert 	  phdr_size = 0;
7733*ef5ccd6cSJohn Marino 	  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
77345796c8dcSSimon Schubert 	    phdr_size += bed->s->sizeof_phdr;
77355796c8dcSSimon Schubert 
77365796c8dcSSimon Schubert 	  if (phdr_size == 0)
77375796c8dcSSimon Schubert 	    phdr_size = get_program_header_size (abfd, info);
77385796c8dcSSimon Schubert 	}
77395796c8dcSSimon Schubert 
7740*ef5ccd6cSJohn Marino       elf_program_header_size (abfd) = phdr_size;
77415796c8dcSSimon Schubert       ret += phdr_size;
77425796c8dcSSimon Schubert     }
77435796c8dcSSimon Schubert 
77445796c8dcSSimon Schubert   return ret;
77455796c8dcSSimon Schubert }
77465796c8dcSSimon Schubert 
77475796c8dcSSimon Schubert bfd_boolean
_bfd_elf_set_section_contents(bfd * abfd,sec_ptr section,const void * location,file_ptr offset,bfd_size_type count)77485796c8dcSSimon Schubert _bfd_elf_set_section_contents (bfd *abfd,
77495796c8dcSSimon Schubert 			       sec_ptr section,
77505796c8dcSSimon Schubert 			       const void *location,
77515796c8dcSSimon Schubert 			       file_ptr offset,
77525796c8dcSSimon Schubert 			       bfd_size_type count)
77535796c8dcSSimon Schubert {
77545796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr;
77555796c8dcSSimon Schubert   bfd_signed_vma pos;
77565796c8dcSSimon Schubert 
77575796c8dcSSimon Schubert   if (! abfd->output_has_begun
77585796c8dcSSimon Schubert       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
77595796c8dcSSimon Schubert     return FALSE;
77605796c8dcSSimon Schubert 
77615796c8dcSSimon Schubert   hdr = &elf_section_data (section)->this_hdr;
77625796c8dcSSimon Schubert   pos = hdr->sh_offset + offset;
77635796c8dcSSimon Schubert   if (bfd_seek (abfd, pos, SEEK_SET) != 0
77645796c8dcSSimon Schubert       || bfd_bwrite (location, count, abfd) != count)
77655796c8dcSSimon Schubert     return FALSE;
77665796c8dcSSimon Schubert 
77675796c8dcSSimon Schubert   return TRUE;
77685796c8dcSSimon Schubert }
77695796c8dcSSimon Schubert 
77705796c8dcSSimon Schubert void
_bfd_elf_no_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr ATTRIBUTE_UNUSED,Elf_Internal_Rela * dst ATTRIBUTE_UNUSED)77715796c8dcSSimon Schubert _bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
77725796c8dcSSimon Schubert 			   arelent *cache_ptr ATTRIBUTE_UNUSED,
77735796c8dcSSimon Schubert 			   Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
77745796c8dcSSimon Schubert {
77755796c8dcSSimon Schubert   abort ();
77765796c8dcSSimon Schubert }
77775796c8dcSSimon Schubert 
77785796c8dcSSimon Schubert /* Try to convert a non-ELF reloc into an ELF one.  */
77795796c8dcSSimon Schubert 
77805796c8dcSSimon Schubert bfd_boolean
_bfd_elf_validate_reloc(bfd * abfd,arelent * areloc)77815796c8dcSSimon Schubert _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
77825796c8dcSSimon Schubert {
77835796c8dcSSimon Schubert   /* Check whether we really have an ELF howto.  */
77845796c8dcSSimon Schubert 
77855796c8dcSSimon Schubert   if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
77865796c8dcSSimon Schubert     {
77875796c8dcSSimon Schubert       bfd_reloc_code_real_type code;
77885796c8dcSSimon Schubert       reloc_howto_type *howto;
77895796c8dcSSimon Schubert 
77905796c8dcSSimon Schubert       /* Alien reloc: Try to determine its type to replace it with an
77915796c8dcSSimon Schubert 	 equivalent ELF reloc.  */
77925796c8dcSSimon Schubert 
77935796c8dcSSimon Schubert       if (areloc->howto->pc_relative)
77945796c8dcSSimon Schubert 	{
77955796c8dcSSimon Schubert 	  switch (areloc->howto->bitsize)
77965796c8dcSSimon Schubert 	    {
77975796c8dcSSimon Schubert 	    case 8:
77985796c8dcSSimon Schubert 	      code = BFD_RELOC_8_PCREL;
77995796c8dcSSimon Schubert 	      break;
78005796c8dcSSimon Schubert 	    case 12:
78015796c8dcSSimon Schubert 	      code = BFD_RELOC_12_PCREL;
78025796c8dcSSimon Schubert 	      break;
78035796c8dcSSimon Schubert 	    case 16:
78045796c8dcSSimon Schubert 	      code = BFD_RELOC_16_PCREL;
78055796c8dcSSimon Schubert 	      break;
78065796c8dcSSimon Schubert 	    case 24:
78075796c8dcSSimon Schubert 	      code = BFD_RELOC_24_PCREL;
78085796c8dcSSimon Schubert 	      break;
78095796c8dcSSimon Schubert 	    case 32:
78105796c8dcSSimon Schubert 	      code = BFD_RELOC_32_PCREL;
78115796c8dcSSimon Schubert 	      break;
78125796c8dcSSimon Schubert 	    case 64:
78135796c8dcSSimon Schubert 	      code = BFD_RELOC_64_PCREL;
78145796c8dcSSimon Schubert 	      break;
78155796c8dcSSimon Schubert 	    default:
78165796c8dcSSimon Schubert 	      goto fail;
78175796c8dcSSimon Schubert 	    }
78185796c8dcSSimon Schubert 
78195796c8dcSSimon Schubert 	  howto = bfd_reloc_type_lookup (abfd, code);
78205796c8dcSSimon Schubert 
78215796c8dcSSimon Schubert 	  if (areloc->howto->pcrel_offset != howto->pcrel_offset)
78225796c8dcSSimon Schubert 	    {
78235796c8dcSSimon Schubert 	      if (howto->pcrel_offset)
78245796c8dcSSimon Schubert 		areloc->addend += areloc->address;
78255796c8dcSSimon Schubert 	      else
78265796c8dcSSimon Schubert 		areloc->addend -= areloc->address; /* addend is unsigned!! */
78275796c8dcSSimon Schubert 	    }
78285796c8dcSSimon Schubert 	}
78295796c8dcSSimon Schubert       else
78305796c8dcSSimon Schubert 	{
78315796c8dcSSimon Schubert 	  switch (areloc->howto->bitsize)
78325796c8dcSSimon Schubert 	    {
78335796c8dcSSimon Schubert 	    case 8:
78345796c8dcSSimon Schubert 	      code = BFD_RELOC_8;
78355796c8dcSSimon Schubert 	      break;
78365796c8dcSSimon Schubert 	    case 14:
78375796c8dcSSimon Schubert 	      code = BFD_RELOC_14;
78385796c8dcSSimon Schubert 	      break;
78395796c8dcSSimon Schubert 	    case 16:
78405796c8dcSSimon Schubert 	      code = BFD_RELOC_16;
78415796c8dcSSimon Schubert 	      break;
78425796c8dcSSimon Schubert 	    case 26:
78435796c8dcSSimon Schubert 	      code = BFD_RELOC_26;
78445796c8dcSSimon Schubert 	      break;
78455796c8dcSSimon Schubert 	    case 32:
78465796c8dcSSimon Schubert 	      code = BFD_RELOC_32;
78475796c8dcSSimon Schubert 	      break;
78485796c8dcSSimon Schubert 	    case 64:
78495796c8dcSSimon Schubert 	      code = BFD_RELOC_64;
78505796c8dcSSimon Schubert 	      break;
78515796c8dcSSimon Schubert 	    default:
78525796c8dcSSimon Schubert 	      goto fail;
78535796c8dcSSimon Schubert 	    }
78545796c8dcSSimon Schubert 
78555796c8dcSSimon Schubert 	  howto = bfd_reloc_type_lookup (abfd, code);
78565796c8dcSSimon Schubert 	}
78575796c8dcSSimon Schubert 
78585796c8dcSSimon Schubert       if (howto)
78595796c8dcSSimon Schubert 	areloc->howto = howto;
78605796c8dcSSimon Schubert       else
78615796c8dcSSimon Schubert 	goto fail;
78625796c8dcSSimon Schubert     }
78635796c8dcSSimon Schubert 
78645796c8dcSSimon Schubert   return TRUE;
78655796c8dcSSimon Schubert 
78665796c8dcSSimon Schubert  fail:
78675796c8dcSSimon Schubert   (*_bfd_error_handler)
78685796c8dcSSimon Schubert     (_("%B: unsupported relocation type %s"),
78695796c8dcSSimon Schubert      abfd, areloc->howto->name);
78705796c8dcSSimon Schubert   bfd_set_error (bfd_error_bad_value);
78715796c8dcSSimon Schubert   return FALSE;
78725796c8dcSSimon Schubert }
78735796c8dcSSimon Schubert 
78745796c8dcSSimon Schubert bfd_boolean
_bfd_elf_close_and_cleanup(bfd * abfd)78755796c8dcSSimon Schubert _bfd_elf_close_and_cleanup (bfd *abfd)
78765796c8dcSSimon Schubert {
7877*ef5ccd6cSJohn Marino   struct elf_obj_tdata *tdata = elf_tdata (abfd);
7878*ef5ccd6cSJohn Marino   if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
78795796c8dcSSimon Schubert     {
7880*ef5ccd6cSJohn Marino       if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
78815796c8dcSSimon Schubert 	_bfd_elf_strtab_free (elf_shstrtab (abfd));
7882*ef5ccd6cSJohn Marino       _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
78835796c8dcSSimon Schubert     }
78845796c8dcSSimon Schubert 
78855796c8dcSSimon Schubert   return _bfd_generic_close_and_cleanup (abfd);
78865796c8dcSSimon Schubert }
78875796c8dcSSimon Schubert 
78885796c8dcSSimon Schubert /* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY
78895796c8dcSSimon Schubert    in the relocation's offset.  Thus we cannot allow any sort of sanity
78905796c8dcSSimon Schubert    range-checking to interfere.  There is nothing else to do in processing
78915796c8dcSSimon Schubert    this reloc.  */
78925796c8dcSSimon Schubert 
78935796c8dcSSimon Schubert bfd_reloc_status_type
_bfd_elf_rel_vtable_reloc_fn(bfd * abfd ATTRIBUTE_UNUSED,arelent * re ATTRIBUTE_UNUSED,struct bfd_symbol * symbol ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED,asection * is ATTRIBUTE_UNUSED,bfd * obfd ATTRIBUTE_UNUSED,char ** errmsg ATTRIBUTE_UNUSED)78945796c8dcSSimon Schubert _bfd_elf_rel_vtable_reloc_fn
78955796c8dcSSimon Schubert   (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
78965796c8dcSSimon Schubert    struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
78975796c8dcSSimon Schubert    void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
78985796c8dcSSimon Schubert    bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
78995796c8dcSSimon Schubert {
79005796c8dcSSimon Schubert   return bfd_reloc_ok;
79015796c8dcSSimon Schubert }
79025796c8dcSSimon Schubert 
79035796c8dcSSimon Schubert /* Elf core file support.  Much of this only works on native
79045796c8dcSSimon Schubert    toolchains, since we rely on knowing the
79055796c8dcSSimon Schubert    machine-dependent procfs structure in order to pick
79065796c8dcSSimon Schubert    out details about the corefile.  */
79075796c8dcSSimon Schubert 
79085796c8dcSSimon Schubert #ifdef HAVE_SYS_PROCFS_H
7909cf7f2e2dSJohn Marino /* Needed for new procfs interface on sparc-solaris.  */
7910cf7f2e2dSJohn Marino # define _STRUCTURED_PROC 1
79115796c8dcSSimon Schubert # include <sys/procfs.h>
79125796c8dcSSimon Schubert #endif
79135796c8dcSSimon Schubert 
7914c50c785cSJohn Marino /* Return a PID that identifies a "thread" for threaded cores, or the
7915c50c785cSJohn Marino    PID of the main process for non-threaded cores.  */
79165796c8dcSSimon Schubert 
79175796c8dcSSimon Schubert static int
elfcore_make_pid(bfd * abfd)79185796c8dcSSimon Schubert elfcore_make_pid (bfd *abfd)
79195796c8dcSSimon Schubert {
7920c50c785cSJohn Marino   int pid;
7921c50c785cSJohn Marino 
7922*ef5ccd6cSJohn Marino   pid = elf_tdata (abfd)->core->lwpid;
7923c50c785cSJohn Marino   if (pid == 0)
7924*ef5ccd6cSJohn Marino     pid = elf_tdata (abfd)->core->pid;
7925c50c785cSJohn Marino 
7926c50c785cSJohn Marino   return pid;
79275796c8dcSSimon Schubert }
79285796c8dcSSimon Schubert 
79295796c8dcSSimon Schubert /* If there isn't a section called NAME, make one, using
79305796c8dcSSimon Schubert    data from SECT.  Note, this function will generate a
79315796c8dcSSimon Schubert    reference to NAME, so you shouldn't deallocate or
79325796c8dcSSimon Schubert    overwrite it.  */
79335796c8dcSSimon Schubert 
79345796c8dcSSimon Schubert static bfd_boolean
elfcore_maybe_make_sect(bfd * abfd,char * name,asection * sect)79355796c8dcSSimon Schubert elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
79365796c8dcSSimon Schubert {
79375796c8dcSSimon Schubert   asection *sect2;
79385796c8dcSSimon Schubert 
79395796c8dcSSimon Schubert   if (bfd_get_section_by_name (abfd, name) != NULL)
79405796c8dcSSimon Schubert     return TRUE;
79415796c8dcSSimon Schubert 
79425796c8dcSSimon Schubert   sect2 = bfd_make_section_with_flags (abfd, name, sect->flags);
79435796c8dcSSimon Schubert   if (sect2 == NULL)
79445796c8dcSSimon Schubert     return FALSE;
79455796c8dcSSimon Schubert 
79465796c8dcSSimon Schubert   sect2->size = sect->size;
79475796c8dcSSimon Schubert   sect2->filepos = sect->filepos;
79485796c8dcSSimon Schubert   sect2->alignment_power = sect->alignment_power;
79495796c8dcSSimon Schubert   return TRUE;
79505796c8dcSSimon Schubert }
79515796c8dcSSimon Schubert 
79525796c8dcSSimon Schubert /* Create a pseudosection containing SIZE bytes at FILEPOS.  This
79535796c8dcSSimon Schubert    actually creates up to two pseudosections:
79545796c8dcSSimon Schubert    - For the single-threaded case, a section named NAME, unless
79555796c8dcSSimon Schubert      such a section already exists.
79565796c8dcSSimon Schubert    - For the multi-threaded case, a section named "NAME/PID", where
79575796c8dcSSimon Schubert      PID is elfcore_make_pid (abfd).
79585796c8dcSSimon Schubert    Both pseudosections have identical contents. */
79595796c8dcSSimon Schubert bfd_boolean
_bfd_elfcore_make_pseudosection(bfd * abfd,char * name,size_t size,ufile_ptr filepos)79605796c8dcSSimon Schubert _bfd_elfcore_make_pseudosection (bfd *abfd,
79615796c8dcSSimon Schubert 				 char *name,
79625796c8dcSSimon Schubert 				 size_t size,
79635796c8dcSSimon Schubert 				 ufile_ptr filepos)
79645796c8dcSSimon Schubert {
79655796c8dcSSimon Schubert   char buf[100];
79665796c8dcSSimon Schubert   char *threaded_name;
79675796c8dcSSimon Schubert   size_t len;
79685796c8dcSSimon Schubert   asection *sect;
79695796c8dcSSimon Schubert 
79705796c8dcSSimon Schubert   /* Build the section name.  */
79715796c8dcSSimon Schubert 
79725796c8dcSSimon Schubert   sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
79735796c8dcSSimon Schubert   len = strlen (buf) + 1;
79745796c8dcSSimon Schubert   threaded_name = (char *) bfd_alloc (abfd, len);
79755796c8dcSSimon Schubert   if (threaded_name == NULL)
79765796c8dcSSimon Schubert     return FALSE;
79775796c8dcSSimon Schubert   memcpy (threaded_name, buf, len);
79785796c8dcSSimon Schubert 
79795796c8dcSSimon Schubert   sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
79805796c8dcSSimon Schubert 					     SEC_HAS_CONTENTS);
79815796c8dcSSimon Schubert   if (sect == NULL)
79825796c8dcSSimon Schubert     return FALSE;
79835796c8dcSSimon Schubert   sect->size = size;
79845796c8dcSSimon Schubert   sect->filepos = filepos;
79855796c8dcSSimon Schubert   sect->alignment_power = 2;
79865796c8dcSSimon Schubert 
79875796c8dcSSimon Schubert   return elfcore_maybe_make_sect (abfd, name, sect);
79885796c8dcSSimon Schubert }
79895796c8dcSSimon Schubert 
79905796c8dcSSimon Schubert /* prstatus_t exists on:
79915796c8dcSSimon Schubert      solaris 2.5+
79925796c8dcSSimon Schubert      linux 2.[01] + glibc
79935796c8dcSSimon Schubert      unixware 4.2
79945796c8dcSSimon Schubert */
79955796c8dcSSimon Schubert 
79965796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS_T)
79975796c8dcSSimon Schubert 
79985796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)79995796c8dcSSimon Schubert elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
80005796c8dcSSimon Schubert {
80015796c8dcSSimon Schubert   size_t size;
80025796c8dcSSimon Schubert   int offset;
80035796c8dcSSimon Schubert 
80045796c8dcSSimon Schubert   if (note->descsz == sizeof (prstatus_t))
80055796c8dcSSimon Schubert     {
80065796c8dcSSimon Schubert       prstatus_t prstat;
80075796c8dcSSimon Schubert 
80085796c8dcSSimon Schubert       size = sizeof (prstat.pr_reg);
80095796c8dcSSimon Schubert       offset   = offsetof (prstatus_t, pr_reg);
80105796c8dcSSimon Schubert       memcpy (&prstat, note->descdata, sizeof (prstat));
80115796c8dcSSimon Schubert 
80125796c8dcSSimon Schubert       /* Do not overwrite the core signal if it
80135796c8dcSSimon Schubert 	 has already been set by another thread.  */
8014*ef5ccd6cSJohn Marino       if (elf_tdata (abfd)->core->signal == 0)
8015*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->signal = prstat.pr_cursig;
8016*ef5ccd6cSJohn Marino       if (elf_tdata (abfd)->core->pid == 0)
8017*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->pid = prstat.pr_pid;
80185796c8dcSSimon Schubert 
80195796c8dcSSimon Schubert       /* pr_who exists on:
80205796c8dcSSimon Schubert 	 solaris 2.5+
80215796c8dcSSimon Schubert 	 unixware 4.2
80225796c8dcSSimon Schubert 	 pr_who doesn't exist on:
80235796c8dcSSimon Schubert 	 linux 2.[01]
80245796c8dcSSimon Schubert 	 */
80255796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS_T_PR_WHO)
8026*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->lwpid = prstat.pr_who;
8027c50c785cSJohn Marino #else
8028*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
80295796c8dcSSimon Schubert #endif
80305796c8dcSSimon Schubert     }
80315796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS32_T)
80325796c8dcSSimon Schubert   else if (note->descsz == sizeof (prstatus32_t))
80335796c8dcSSimon Schubert     {
80345796c8dcSSimon Schubert       /* 64-bit host, 32-bit corefile */
80355796c8dcSSimon Schubert       prstatus32_t prstat;
80365796c8dcSSimon Schubert 
80375796c8dcSSimon Schubert       size = sizeof (prstat.pr_reg);
80385796c8dcSSimon Schubert       offset   = offsetof (prstatus32_t, pr_reg);
80395796c8dcSSimon Schubert       memcpy (&prstat, note->descdata, sizeof (prstat));
80405796c8dcSSimon Schubert 
80415796c8dcSSimon Schubert       /* Do not overwrite the core signal if it
80425796c8dcSSimon Schubert 	 has already been set by another thread.  */
8043*ef5ccd6cSJohn Marino       if (elf_tdata (abfd)->core->signal == 0)
8044*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->signal = prstat.pr_cursig;
8045*ef5ccd6cSJohn Marino       if (elf_tdata (abfd)->core->pid == 0)
8046*ef5ccd6cSJohn Marino 	elf_tdata (abfd)->core->pid = prstat.pr_pid;
80475796c8dcSSimon Schubert 
80485796c8dcSSimon Schubert       /* pr_who exists on:
80495796c8dcSSimon Schubert 	 solaris 2.5+
80505796c8dcSSimon Schubert 	 unixware 4.2
80515796c8dcSSimon Schubert 	 pr_who doesn't exist on:
80525796c8dcSSimon Schubert 	 linux 2.[01]
80535796c8dcSSimon Schubert 	 */
80545796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS32_T_PR_WHO)
8055*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->lwpid = prstat.pr_who;
8056c50c785cSJohn Marino #else
8057*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
80585796c8dcSSimon Schubert #endif
80595796c8dcSSimon Schubert     }
80605796c8dcSSimon Schubert #endif /* HAVE_PRSTATUS32_T */
80615796c8dcSSimon Schubert   else
80625796c8dcSSimon Schubert     {
80635796c8dcSSimon Schubert       /* Fail - we don't know how to handle any other
80645796c8dcSSimon Schubert 	 note size (ie. data object type).  */
80655796c8dcSSimon Schubert       return TRUE;
80665796c8dcSSimon Schubert     }
80675796c8dcSSimon Schubert 
80685796c8dcSSimon Schubert   /* Make a ".reg/999" section and a ".reg" section.  */
80695796c8dcSSimon Schubert   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
80705796c8dcSSimon Schubert 					  size, note->descpos + offset);
80715796c8dcSSimon Schubert }
80725796c8dcSSimon Schubert #endif /* defined (HAVE_PRSTATUS_T) */
80735796c8dcSSimon Schubert 
80745796c8dcSSimon Schubert /* Create a pseudosection containing the exact contents of NOTE.  */
80755796c8dcSSimon Schubert static bfd_boolean
elfcore_make_note_pseudosection(bfd * abfd,char * name,Elf_Internal_Note * note)80765796c8dcSSimon Schubert elfcore_make_note_pseudosection (bfd *abfd,
80775796c8dcSSimon Schubert 				 char *name,
80785796c8dcSSimon Schubert 				 Elf_Internal_Note *note)
80795796c8dcSSimon Schubert {
80805796c8dcSSimon Schubert   return _bfd_elfcore_make_pseudosection (abfd, name,
80815796c8dcSSimon Schubert 					  note->descsz, note->descpos);
80825796c8dcSSimon Schubert }
80835796c8dcSSimon Schubert 
80845796c8dcSSimon Schubert /* There isn't a consistent prfpregset_t across platforms,
80855796c8dcSSimon Schubert    but it doesn't matter, because we don't have to pick this
80865796c8dcSSimon Schubert    data structure apart.  */
80875796c8dcSSimon Schubert 
80885796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_prfpreg(bfd * abfd,Elf_Internal_Note * note)80895796c8dcSSimon Schubert elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
80905796c8dcSSimon Schubert {
80915796c8dcSSimon Schubert   return elfcore_make_note_pseudosection (abfd, ".reg2", note);
80925796c8dcSSimon Schubert }
80935796c8dcSSimon Schubert 
80945796c8dcSSimon Schubert /* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
80955796c8dcSSimon Schubert    type of NT_PRXFPREG.  Just include the whole note's contents
80965796c8dcSSimon Schubert    literally.  */
80975796c8dcSSimon Schubert 
80985796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_prxfpreg(bfd * abfd,Elf_Internal_Note * note)80995796c8dcSSimon Schubert elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
81005796c8dcSSimon Schubert {
81015796c8dcSSimon Schubert   return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
81025796c8dcSSimon Schubert }
81035796c8dcSSimon Schubert 
8104cf7f2e2dSJohn Marino /* Linux dumps the Intel XSAVE extended state in a note named "LINUX"
8105cf7f2e2dSJohn Marino    with a note type of NT_X86_XSTATE.  Just include the whole note's
8106cf7f2e2dSJohn Marino    contents literally.  */
8107cf7f2e2dSJohn Marino 
8108cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_xstatereg(bfd * abfd,Elf_Internal_Note * note)8109cf7f2e2dSJohn Marino elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note)
8110cf7f2e2dSJohn Marino {
8111cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note);
8112cf7f2e2dSJohn Marino }
8113cf7f2e2dSJohn Marino 
81145796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_ppc_vmx(bfd * abfd,Elf_Internal_Note * note)81155796c8dcSSimon Schubert elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
81165796c8dcSSimon Schubert {
81175796c8dcSSimon Schubert   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
81185796c8dcSSimon Schubert }
81195796c8dcSSimon Schubert 
81205796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_ppc_vsx(bfd * abfd,Elf_Internal_Note * note)81215796c8dcSSimon Schubert elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
81225796c8dcSSimon Schubert {
81235796c8dcSSimon Schubert   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note);
81245796c8dcSSimon Schubert }
81255796c8dcSSimon Schubert 
8126cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_high_gprs(bfd * abfd,Elf_Internal_Note * note)8127cf7f2e2dSJohn Marino elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note)
8128cf7f2e2dSJohn Marino {
8129cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note);
8130cf7f2e2dSJohn Marino }
8131cf7f2e2dSJohn Marino 
8132cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_timer(bfd * abfd,Elf_Internal_Note * note)8133cf7f2e2dSJohn Marino elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
8134cf7f2e2dSJohn Marino {
8135cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note);
8136cf7f2e2dSJohn Marino }
8137cf7f2e2dSJohn Marino 
8138cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_todcmp(bfd * abfd,Elf_Internal_Note * note)8139cf7f2e2dSJohn Marino elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
8140cf7f2e2dSJohn Marino {
8141cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note);
8142cf7f2e2dSJohn Marino }
8143cf7f2e2dSJohn Marino 
8144cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_todpreg(bfd * abfd,Elf_Internal_Note * note)8145cf7f2e2dSJohn Marino elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
8146cf7f2e2dSJohn Marino {
8147cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note);
8148cf7f2e2dSJohn Marino }
8149cf7f2e2dSJohn Marino 
8150cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_ctrs(bfd * abfd,Elf_Internal_Note * note)8151cf7f2e2dSJohn Marino elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
8152cf7f2e2dSJohn Marino {
8153cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note);
8154cf7f2e2dSJohn Marino }
8155cf7f2e2dSJohn Marino 
8156cf7f2e2dSJohn Marino static bfd_boolean
elfcore_grok_s390_prefix(bfd * abfd,Elf_Internal_Note * note)8157cf7f2e2dSJohn Marino elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
8158cf7f2e2dSJohn Marino {
8159cf7f2e2dSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
8160cf7f2e2dSJohn Marino }
8161cf7f2e2dSJohn Marino 
8162a45ae5f8SJohn Marino static bfd_boolean
elfcore_grok_s390_last_break(bfd * abfd,Elf_Internal_Note * note)8163a45ae5f8SJohn Marino elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
8164a45ae5f8SJohn Marino {
8165a45ae5f8SJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
8166a45ae5f8SJohn Marino }
8167a45ae5f8SJohn Marino 
8168a45ae5f8SJohn Marino static bfd_boolean
elfcore_grok_s390_system_call(bfd * abfd,Elf_Internal_Note * note)8169a45ae5f8SJohn Marino elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
8170a45ae5f8SJohn Marino {
8171a45ae5f8SJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
8172a45ae5f8SJohn Marino }
8173a45ae5f8SJohn Marino 
8174a45ae5f8SJohn Marino static bfd_boolean
elfcore_grok_s390_tdb(bfd * abfd,Elf_Internal_Note * note)8175*ef5ccd6cSJohn Marino elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
8176*ef5ccd6cSJohn Marino {
8177*ef5ccd6cSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
8178*ef5ccd6cSJohn Marino }
8179*ef5ccd6cSJohn Marino 
8180*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_arm_vfp(bfd * abfd,Elf_Internal_Note * note)8181a45ae5f8SJohn Marino elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
8182a45ae5f8SJohn Marino {
8183a45ae5f8SJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
8184a45ae5f8SJohn Marino }
8185a45ae5f8SJohn Marino 
8186*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_aarch_tls(bfd * abfd,Elf_Internal_Note * note)8187*ef5ccd6cSJohn Marino elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
8188*ef5ccd6cSJohn Marino {
8189*ef5ccd6cSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note);
8190*ef5ccd6cSJohn Marino }
8191*ef5ccd6cSJohn Marino 
8192*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_aarch_hw_break(bfd * abfd,Elf_Internal_Note * note)8193*ef5ccd6cSJohn Marino elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
8194*ef5ccd6cSJohn Marino {
8195*ef5ccd6cSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note);
8196*ef5ccd6cSJohn Marino }
8197*ef5ccd6cSJohn Marino 
8198*ef5ccd6cSJohn Marino static bfd_boolean
elfcore_grok_aarch_hw_watch(bfd * abfd,Elf_Internal_Note * note)8199*ef5ccd6cSJohn Marino elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
8200*ef5ccd6cSJohn Marino {
8201*ef5ccd6cSJohn Marino   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note);
8202*ef5ccd6cSJohn Marino }
8203*ef5ccd6cSJohn Marino 
82045796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO_T)
82055796c8dcSSimon Schubert typedef prpsinfo_t   elfcore_psinfo_t;
82065796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
82075796c8dcSSimon Schubert typedef prpsinfo32_t elfcore_psinfo32_t;
82085796c8dcSSimon Schubert #endif
82095796c8dcSSimon Schubert #endif
82105796c8dcSSimon Schubert 
82115796c8dcSSimon Schubert #if defined (HAVE_PSINFO_T)
82125796c8dcSSimon Schubert typedef psinfo_t   elfcore_psinfo_t;
82135796c8dcSSimon Schubert #if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
82145796c8dcSSimon Schubert typedef psinfo32_t elfcore_psinfo32_t;
82155796c8dcSSimon Schubert #endif
82165796c8dcSSimon Schubert #endif
82175796c8dcSSimon Schubert 
82185796c8dcSSimon Schubert /* return a malloc'ed copy of a string at START which is at
82195796c8dcSSimon Schubert    most MAX bytes long, possibly without a terminating '\0'.
82205796c8dcSSimon Schubert    the copy will always have a terminating '\0'.  */
82215796c8dcSSimon Schubert 
82225796c8dcSSimon Schubert char *
_bfd_elfcore_strndup(bfd * abfd,char * start,size_t max)82235796c8dcSSimon Schubert _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
82245796c8dcSSimon Schubert {
82255796c8dcSSimon Schubert   char *dups;
82265796c8dcSSimon Schubert   char *end = (char *) memchr (start, '\0', max);
82275796c8dcSSimon Schubert   size_t len;
82285796c8dcSSimon Schubert 
82295796c8dcSSimon Schubert   if (end == NULL)
82305796c8dcSSimon Schubert     len = max;
82315796c8dcSSimon Schubert   else
82325796c8dcSSimon Schubert     len = end - start;
82335796c8dcSSimon Schubert 
82345796c8dcSSimon Schubert   dups = (char *) bfd_alloc (abfd, len + 1);
82355796c8dcSSimon Schubert   if (dups == NULL)
82365796c8dcSSimon Schubert     return NULL;
82375796c8dcSSimon Schubert 
82385796c8dcSSimon Schubert   memcpy (dups, start, len);
82395796c8dcSSimon Schubert   dups[len] = '\0';
82405796c8dcSSimon Schubert 
82415796c8dcSSimon Schubert   return dups;
82425796c8dcSSimon Schubert }
82435796c8dcSSimon Schubert 
82445796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
82455796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)82465796c8dcSSimon Schubert elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
82475796c8dcSSimon Schubert {
82485796c8dcSSimon Schubert   if (note->descsz == sizeof (elfcore_psinfo_t))
82495796c8dcSSimon Schubert     {
82505796c8dcSSimon Schubert       elfcore_psinfo_t psinfo;
82515796c8dcSSimon Schubert 
82525796c8dcSSimon Schubert       memcpy (&psinfo, note->descdata, sizeof (psinfo));
82535796c8dcSSimon Schubert 
8254a45ae5f8SJohn Marino #if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
8255*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->pid = psinfo.pr_pid;
8256a45ae5f8SJohn Marino #endif
8257*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->program
82585796c8dcSSimon Schubert 	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
82595796c8dcSSimon Schubert 				sizeof (psinfo.pr_fname));
82605796c8dcSSimon Schubert 
8261*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->command
82625796c8dcSSimon Schubert 	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
82635796c8dcSSimon Schubert 				sizeof (psinfo.pr_psargs));
82645796c8dcSSimon Schubert     }
82655796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
82665796c8dcSSimon Schubert   else if (note->descsz == sizeof (elfcore_psinfo32_t))
82675796c8dcSSimon Schubert     {
82685796c8dcSSimon Schubert       /* 64-bit host, 32-bit corefile */
82695796c8dcSSimon Schubert       elfcore_psinfo32_t psinfo;
82705796c8dcSSimon Schubert 
82715796c8dcSSimon Schubert       memcpy (&psinfo, note->descdata, sizeof (psinfo));
82725796c8dcSSimon Schubert 
8273a45ae5f8SJohn Marino #if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
8274*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->pid = psinfo.pr_pid;
8275a45ae5f8SJohn Marino #endif
8276*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->program
82775796c8dcSSimon Schubert 	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
82785796c8dcSSimon Schubert 				sizeof (psinfo.pr_fname));
82795796c8dcSSimon Schubert 
8280*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->command
82815796c8dcSSimon Schubert 	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
82825796c8dcSSimon Schubert 				sizeof (psinfo.pr_psargs));
82835796c8dcSSimon Schubert     }
82845796c8dcSSimon Schubert #endif
82855796c8dcSSimon Schubert 
82865796c8dcSSimon Schubert   else
82875796c8dcSSimon Schubert     {
82885796c8dcSSimon Schubert       /* Fail - we don't know how to handle any other
82895796c8dcSSimon Schubert 	 note size (ie. data object type).  */
82905796c8dcSSimon Schubert       return TRUE;
82915796c8dcSSimon Schubert     }
82925796c8dcSSimon Schubert 
82935796c8dcSSimon Schubert   /* Note that for some reason, a spurious space is tacked
82945796c8dcSSimon Schubert      onto the end of the args in some (at least one anyway)
82955796c8dcSSimon Schubert      implementations, so strip it off if it exists.  */
82965796c8dcSSimon Schubert 
82975796c8dcSSimon Schubert   {
8298*ef5ccd6cSJohn Marino     char *command = elf_tdata (abfd)->core->command;
82995796c8dcSSimon Schubert     int n = strlen (command);
83005796c8dcSSimon Schubert 
83015796c8dcSSimon Schubert     if (0 < n && command[n - 1] == ' ')
83025796c8dcSSimon Schubert       command[n - 1] = '\0';
83035796c8dcSSimon Schubert   }
83045796c8dcSSimon Schubert 
83055796c8dcSSimon Schubert   return TRUE;
83065796c8dcSSimon Schubert }
83075796c8dcSSimon Schubert #endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
83085796c8dcSSimon Schubert 
83095796c8dcSSimon Schubert #if defined (HAVE_PSTATUS_T)
83105796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_pstatus(bfd * abfd,Elf_Internal_Note * note)83115796c8dcSSimon Schubert elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
83125796c8dcSSimon Schubert {
83135796c8dcSSimon Schubert   if (note->descsz == sizeof (pstatus_t)
83145796c8dcSSimon Schubert #if defined (HAVE_PXSTATUS_T)
83155796c8dcSSimon Schubert       || note->descsz == sizeof (pxstatus_t)
83165796c8dcSSimon Schubert #endif
83175796c8dcSSimon Schubert       )
83185796c8dcSSimon Schubert     {
83195796c8dcSSimon Schubert       pstatus_t pstat;
83205796c8dcSSimon Schubert 
83215796c8dcSSimon Schubert       memcpy (&pstat, note->descdata, sizeof (pstat));
83225796c8dcSSimon Schubert 
8323*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->pid = pstat.pr_pid;
83245796c8dcSSimon Schubert     }
83255796c8dcSSimon Schubert #if defined (HAVE_PSTATUS32_T)
83265796c8dcSSimon Schubert   else if (note->descsz == sizeof (pstatus32_t))
83275796c8dcSSimon Schubert     {
83285796c8dcSSimon Schubert       /* 64-bit host, 32-bit corefile */
83295796c8dcSSimon Schubert       pstatus32_t pstat;
83305796c8dcSSimon Schubert 
83315796c8dcSSimon Schubert       memcpy (&pstat, note->descdata, sizeof (pstat));
83325796c8dcSSimon Schubert 
8333*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->pid = pstat.pr_pid;
83345796c8dcSSimon Schubert     }
83355796c8dcSSimon Schubert #endif
83365796c8dcSSimon Schubert   /* Could grab some more details from the "representative"
83375796c8dcSSimon Schubert      lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
83385796c8dcSSimon Schubert      NT_LWPSTATUS note, presumably.  */
83395796c8dcSSimon Schubert 
83405796c8dcSSimon Schubert   return TRUE;
83415796c8dcSSimon Schubert }
83425796c8dcSSimon Schubert #endif /* defined (HAVE_PSTATUS_T) */
83435796c8dcSSimon Schubert 
83445796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T)
83455796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_lwpstatus(bfd * abfd,Elf_Internal_Note * note)83465796c8dcSSimon Schubert elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
83475796c8dcSSimon Schubert {
83485796c8dcSSimon Schubert   lwpstatus_t lwpstat;
83495796c8dcSSimon Schubert   char buf[100];
83505796c8dcSSimon Schubert   char *name;
83515796c8dcSSimon Schubert   size_t len;
83525796c8dcSSimon Schubert   asection *sect;
83535796c8dcSSimon Schubert 
83545796c8dcSSimon Schubert   if (note->descsz != sizeof (lwpstat)
83555796c8dcSSimon Schubert #if defined (HAVE_LWPXSTATUS_T)
83565796c8dcSSimon Schubert       && note->descsz != sizeof (lwpxstatus_t)
83575796c8dcSSimon Schubert #endif
83585796c8dcSSimon Schubert       )
83595796c8dcSSimon Schubert     return TRUE;
83605796c8dcSSimon Schubert 
83615796c8dcSSimon Schubert   memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
83625796c8dcSSimon Schubert 
8363*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
8364cf7f2e2dSJohn Marino   /* Do not overwrite the core signal if it has already been set by
8365cf7f2e2dSJohn Marino      another thread.  */
8366*ef5ccd6cSJohn Marino   if (elf_tdata (abfd)->core->signal == 0)
8367*ef5ccd6cSJohn Marino     elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;
83685796c8dcSSimon Schubert 
83695796c8dcSSimon Schubert   /* Make a ".reg/999" section.  */
83705796c8dcSSimon Schubert 
83715796c8dcSSimon Schubert   sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
83725796c8dcSSimon Schubert   len = strlen (buf) + 1;
83735796c8dcSSimon Schubert   name = bfd_alloc (abfd, len);
83745796c8dcSSimon Schubert   if (name == NULL)
83755796c8dcSSimon Schubert     return FALSE;
83765796c8dcSSimon Schubert   memcpy (name, buf, len);
83775796c8dcSSimon Schubert 
83785796c8dcSSimon Schubert   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
83795796c8dcSSimon Schubert   if (sect == NULL)
83805796c8dcSSimon Schubert     return FALSE;
83815796c8dcSSimon Schubert 
83825796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
83835796c8dcSSimon Schubert   sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
83845796c8dcSSimon Schubert   sect->filepos = note->descpos
83855796c8dcSSimon Schubert     + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
83865796c8dcSSimon Schubert #endif
83875796c8dcSSimon Schubert 
83885796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_REG)
83895796c8dcSSimon Schubert   sect->size = sizeof (lwpstat.pr_reg);
83905796c8dcSSimon Schubert   sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
83915796c8dcSSimon Schubert #endif
83925796c8dcSSimon Schubert 
83935796c8dcSSimon Schubert   sect->alignment_power = 2;
83945796c8dcSSimon Schubert 
83955796c8dcSSimon Schubert   if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
83965796c8dcSSimon Schubert     return FALSE;
83975796c8dcSSimon Schubert 
83985796c8dcSSimon Schubert   /* Make a ".reg2/999" section */
83995796c8dcSSimon Schubert 
84005796c8dcSSimon Schubert   sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
84015796c8dcSSimon Schubert   len = strlen (buf) + 1;
84025796c8dcSSimon Schubert   name = bfd_alloc (abfd, len);
84035796c8dcSSimon Schubert   if (name == NULL)
84045796c8dcSSimon Schubert     return FALSE;
84055796c8dcSSimon Schubert   memcpy (name, buf, len);
84065796c8dcSSimon Schubert 
84075796c8dcSSimon Schubert   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
84085796c8dcSSimon Schubert   if (sect == NULL)
84095796c8dcSSimon Schubert     return FALSE;
84105796c8dcSSimon Schubert 
84115796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
84125796c8dcSSimon Schubert   sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
84135796c8dcSSimon Schubert   sect->filepos = note->descpos
84145796c8dcSSimon Schubert     + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
84155796c8dcSSimon Schubert #endif
84165796c8dcSSimon Schubert 
84175796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_FPREG)
84185796c8dcSSimon Schubert   sect->size = sizeof (lwpstat.pr_fpreg);
84195796c8dcSSimon Schubert   sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
84205796c8dcSSimon Schubert #endif
84215796c8dcSSimon Schubert 
84225796c8dcSSimon Schubert   sect->alignment_power = 2;
84235796c8dcSSimon Schubert 
84245796c8dcSSimon Schubert   return elfcore_maybe_make_sect (abfd, ".reg2", sect);
84255796c8dcSSimon Schubert }
84265796c8dcSSimon Schubert #endif /* defined (HAVE_LWPSTATUS_T) */
84275796c8dcSSimon Schubert 
84285796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_win32pstatus(bfd * abfd,Elf_Internal_Note * note)84295796c8dcSSimon Schubert elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
84305796c8dcSSimon Schubert {
84315796c8dcSSimon Schubert   char buf[30];
84325796c8dcSSimon Schubert   char *name;
84335796c8dcSSimon Schubert   size_t len;
84345796c8dcSSimon Schubert   asection *sect;
84355796c8dcSSimon Schubert   int type;
84365796c8dcSSimon Schubert   int is_active_thread;
84375796c8dcSSimon Schubert   bfd_vma base_addr;
84385796c8dcSSimon Schubert 
84395796c8dcSSimon Schubert   if (note->descsz < 728)
84405796c8dcSSimon Schubert     return TRUE;
84415796c8dcSSimon Schubert 
84425796c8dcSSimon Schubert   if (! CONST_STRNEQ (note->namedata, "win32"))
84435796c8dcSSimon Schubert     return TRUE;
84445796c8dcSSimon Schubert 
84455796c8dcSSimon Schubert   type = bfd_get_32 (abfd, note->descdata);
84465796c8dcSSimon Schubert 
84475796c8dcSSimon Schubert   switch (type)
84485796c8dcSSimon Schubert     {
84495796c8dcSSimon Schubert     case 1 /* NOTE_INFO_PROCESS */:
8450*ef5ccd6cSJohn Marino       /* FIXME: need to add ->core->command.  */
84515796c8dcSSimon Schubert       /* process_info.pid */
8452*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 8);
84535796c8dcSSimon Schubert       /* process_info.signal */
8454*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 12);
84555796c8dcSSimon Schubert       break;
84565796c8dcSSimon Schubert 
84575796c8dcSSimon Schubert     case 2 /* NOTE_INFO_THREAD */:
84585796c8dcSSimon Schubert       /* Make a ".reg/999" section.  */
84595796c8dcSSimon Schubert       /* thread_info.tid */
84605796c8dcSSimon Schubert       sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 8));
84615796c8dcSSimon Schubert 
84625796c8dcSSimon Schubert       len = strlen (buf) + 1;
84635796c8dcSSimon Schubert       name = (char *) bfd_alloc (abfd, len);
84645796c8dcSSimon Schubert       if (name == NULL)
84655796c8dcSSimon Schubert 	return FALSE;
84665796c8dcSSimon Schubert 
84675796c8dcSSimon Schubert       memcpy (name, buf, len);
84685796c8dcSSimon Schubert 
84695796c8dcSSimon Schubert       sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
84705796c8dcSSimon Schubert       if (sect == NULL)
84715796c8dcSSimon Schubert 	return FALSE;
84725796c8dcSSimon Schubert 
84735796c8dcSSimon Schubert       /* sizeof (thread_info.thread_context) */
84745796c8dcSSimon Schubert       sect->size = 716;
84755796c8dcSSimon Schubert       /* offsetof (thread_info.thread_context) */
84765796c8dcSSimon Schubert       sect->filepos = note->descpos + 12;
84775796c8dcSSimon Schubert       sect->alignment_power = 2;
84785796c8dcSSimon Schubert 
84795796c8dcSSimon Schubert       /* thread_info.is_active_thread */
84805796c8dcSSimon Schubert       is_active_thread = bfd_get_32 (abfd, note->descdata + 8);
84815796c8dcSSimon Schubert 
84825796c8dcSSimon Schubert       if (is_active_thread)
84835796c8dcSSimon Schubert 	if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
84845796c8dcSSimon Schubert 	  return FALSE;
84855796c8dcSSimon Schubert       break;
84865796c8dcSSimon Schubert 
84875796c8dcSSimon Schubert     case 3 /* NOTE_INFO_MODULE */:
84885796c8dcSSimon Schubert       /* Make a ".module/xxxxxxxx" section.  */
84895796c8dcSSimon Schubert       /* module_info.base_address */
84905796c8dcSSimon Schubert       base_addr = bfd_get_32 (abfd, note->descdata + 4);
84915796c8dcSSimon Schubert       sprintf (buf, ".module/%08lx", (unsigned long) base_addr);
84925796c8dcSSimon Schubert 
84935796c8dcSSimon Schubert       len = strlen (buf) + 1;
84945796c8dcSSimon Schubert       name = (char *) bfd_alloc (abfd, len);
84955796c8dcSSimon Schubert       if (name == NULL)
84965796c8dcSSimon Schubert 	return FALSE;
84975796c8dcSSimon Schubert 
84985796c8dcSSimon Schubert       memcpy (name, buf, len);
84995796c8dcSSimon Schubert 
85005796c8dcSSimon Schubert       sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
85015796c8dcSSimon Schubert 
85025796c8dcSSimon Schubert       if (sect == NULL)
85035796c8dcSSimon Schubert 	return FALSE;
85045796c8dcSSimon Schubert 
85055796c8dcSSimon Schubert       sect->size = note->descsz;
85065796c8dcSSimon Schubert       sect->filepos = note->descpos;
85075796c8dcSSimon Schubert       sect->alignment_power = 2;
85085796c8dcSSimon Schubert       break;
85095796c8dcSSimon Schubert 
85105796c8dcSSimon Schubert     default:
85115796c8dcSSimon Schubert       return TRUE;
85125796c8dcSSimon Schubert     }
85135796c8dcSSimon Schubert 
85145796c8dcSSimon Schubert   return TRUE;
85155796c8dcSSimon Schubert }
85165796c8dcSSimon Schubert 
85175796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_note(bfd * abfd,Elf_Internal_Note * note)85185796c8dcSSimon Schubert elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
85195796c8dcSSimon Schubert {
85205796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
85215796c8dcSSimon Schubert 
85225796c8dcSSimon Schubert   switch (note->type)
85235796c8dcSSimon Schubert     {
85245796c8dcSSimon Schubert     default:
85255796c8dcSSimon Schubert       return TRUE;
85265796c8dcSSimon Schubert 
85275796c8dcSSimon Schubert     case NT_PRSTATUS:
85285796c8dcSSimon Schubert       if (bed->elf_backend_grok_prstatus)
85295796c8dcSSimon Schubert 	if ((*bed->elf_backend_grok_prstatus) (abfd, note))
85305796c8dcSSimon Schubert 	  return TRUE;
85315796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS_T)
85325796c8dcSSimon Schubert       return elfcore_grok_prstatus (abfd, note);
85335796c8dcSSimon Schubert #else
85345796c8dcSSimon Schubert       return TRUE;
85355796c8dcSSimon Schubert #endif
85365796c8dcSSimon Schubert 
85375796c8dcSSimon Schubert #if defined (HAVE_PSTATUS_T)
85385796c8dcSSimon Schubert     case NT_PSTATUS:
85395796c8dcSSimon Schubert       return elfcore_grok_pstatus (abfd, note);
85405796c8dcSSimon Schubert #endif
85415796c8dcSSimon Schubert 
85425796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T)
85435796c8dcSSimon Schubert     case NT_LWPSTATUS:
85445796c8dcSSimon Schubert       return elfcore_grok_lwpstatus (abfd, note);
85455796c8dcSSimon Schubert #endif
85465796c8dcSSimon Schubert 
85475796c8dcSSimon Schubert     case NT_FPREGSET:		/* FIXME: rename to NT_PRFPREG */
85485796c8dcSSimon Schubert       return elfcore_grok_prfpreg (abfd, note);
85495796c8dcSSimon Schubert 
85505796c8dcSSimon Schubert     case NT_WIN32PSTATUS:
85515796c8dcSSimon Schubert       return elfcore_grok_win32pstatus (abfd, note);
85525796c8dcSSimon Schubert 
85535796c8dcSSimon Schubert     case NT_PRXFPREG:		/* Linux SSE extension */
85545796c8dcSSimon Schubert       if (note->namesz == 6
85555796c8dcSSimon Schubert 	  && strcmp (note->namedata, "LINUX") == 0)
85565796c8dcSSimon Schubert 	return elfcore_grok_prxfpreg (abfd, note);
85575796c8dcSSimon Schubert       else
85585796c8dcSSimon Schubert 	return TRUE;
85595796c8dcSSimon Schubert 
8560cf7f2e2dSJohn Marino     case NT_X86_XSTATE:		/* Linux XSAVE extension */
8561cf7f2e2dSJohn Marino       if (note->namesz == 6
8562cf7f2e2dSJohn Marino 	  && strcmp (note->namedata, "LINUX") == 0)
8563cf7f2e2dSJohn Marino 	return elfcore_grok_xstatereg (abfd, note);
8564cf7f2e2dSJohn Marino       else
8565cf7f2e2dSJohn Marino 	return TRUE;
8566cf7f2e2dSJohn Marino 
85675796c8dcSSimon Schubert     case NT_PPC_VMX:
85685796c8dcSSimon Schubert       if (note->namesz == 6
85695796c8dcSSimon Schubert 	  && strcmp (note->namedata, "LINUX") == 0)
85705796c8dcSSimon Schubert 	return elfcore_grok_ppc_vmx (abfd, note);
85715796c8dcSSimon Schubert       else
85725796c8dcSSimon Schubert 	return TRUE;
85735796c8dcSSimon Schubert 
85745796c8dcSSimon Schubert     case NT_PPC_VSX:
85755796c8dcSSimon Schubert       if (note->namesz == 6
85765796c8dcSSimon Schubert           && strcmp (note->namedata, "LINUX") == 0)
85775796c8dcSSimon Schubert         return elfcore_grok_ppc_vsx (abfd, note);
85785796c8dcSSimon Schubert       else
85795796c8dcSSimon Schubert         return TRUE;
85805796c8dcSSimon Schubert 
8581cf7f2e2dSJohn Marino     case NT_S390_HIGH_GPRS:
8582cf7f2e2dSJohn Marino       if (note->namesz == 6
8583cf7f2e2dSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8584cf7f2e2dSJohn Marino         return elfcore_grok_s390_high_gprs (abfd, note);
8585cf7f2e2dSJohn Marino       else
8586cf7f2e2dSJohn Marino         return TRUE;
8587cf7f2e2dSJohn Marino 
8588cf7f2e2dSJohn Marino     case NT_S390_TIMER:
8589cf7f2e2dSJohn Marino       if (note->namesz == 6
8590cf7f2e2dSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8591cf7f2e2dSJohn Marino         return elfcore_grok_s390_timer (abfd, note);
8592cf7f2e2dSJohn Marino       else
8593cf7f2e2dSJohn Marino         return TRUE;
8594cf7f2e2dSJohn Marino 
8595cf7f2e2dSJohn Marino     case NT_S390_TODCMP:
8596cf7f2e2dSJohn Marino       if (note->namesz == 6
8597cf7f2e2dSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8598cf7f2e2dSJohn Marino         return elfcore_grok_s390_todcmp (abfd, note);
8599cf7f2e2dSJohn Marino       else
8600cf7f2e2dSJohn Marino         return TRUE;
8601cf7f2e2dSJohn Marino 
8602cf7f2e2dSJohn Marino     case NT_S390_TODPREG:
8603cf7f2e2dSJohn Marino       if (note->namesz == 6
8604cf7f2e2dSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8605cf7f2e2dSJohn Marino         return elfcore_grok_s390_todpreg (abfd, note);
8606cf7f2e2dSJohn Marino       else
8607cf7f2e2dSJohn Marino         return TRUE;
8608cf7f2e2dSJohn Marino 
8609cf7f2e2dSJohn Marino     case NT_S390_CTRS:
8610cf7f2e2dSJohn Marino       if (note->namesz == 6
8611cf7f2e2dSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8612cf7f2e2dSJohn Marino         return elfcore_grok_s390_ctrs (abfd, note);
8613cf7f2e2dSJohn Marino       else
8614cf7f2e2dSJohn Marino         return TRUE;
8615cf7f2e2dSJohn Marino 
8616cf7f2e2dSJohn Marino     case NT_S390_PREFIX:
8617cf7f2e2dSJohn Marino       if (note->namesz == 6
8618cf7f2e2dSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8619cf7f2e2dSJohn Marino         return elfcore_grok_s390_prefix (abfd, note);
8620cf7f2e2dSJohn Marino       else
8621cf7f2e2dSJohn Marino         return TRUE;
8622cf7f2e2dSJohn Marino 
8623a45ae5f8SJohn Marino     case NT_S390_LAST_BREAK:
8624a45ae5f8SJohn Marino       if (note->namesz == 6
8625a45ae5f8SJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8626a45ae5f8SJohn Marino         return elfcore_grok_s390_last_break (abfd, note);
8627a45ae5f8SJohn Marino       else
8628a45ae5f8SJohn Marino         return TRUE;
8629a45ae5f8SJohn Marino 
8630a45ae5f8SJohn Marino     case NT_S390_SYSTEM_CALL:
8631a45ae5f8SJohn Marino       if (note->namesz == 6
8632a45ae5f8SJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8633a45ae5f8SJohn Marino         return elfcore_grok_s390_system_call (abfd, note);
8634a45ae5f8SJohn Marino       else
8635a45ae5f8SJohn Marino         return TRUE;
8636a45ae5f8SJohn Marino 
8637*ef5ccd6cSJohn Marino     case NT_S390_TDB:
8638*ef5ccd6cSJohn Marino       if (note->namesz == 6
8639*ef5ccd6cSJohn Marino           && strcmp (note->namedata, "LINUX") == 0)
8640*ef5ccd6cSJohn Marino         return elfcore_grok_s390_tdb (abfd, note);
8641*ef5ccd6cSJohn Marino       else
8642*ef5ccd6cSJohn Marino         return TRUE;
8643*ef5ccd6cSJohn Marino 
8644a45ae5f8SJohn Marino     case NT_ARM_VFP:
8645a45ae5f8SJohn Marino       if (note->namesz == 6
8646a45ae5f8SJohn Marino 	  && strcmp (note->namedata, "LINUX") == 0)
8647a45ae5f8SJohn Marino 	return elfcore_grok_arm_vfp (abfd, note);
8648a45ae5f8SJohn Marino       else
8649a45ae5f8SJohn Marino 	return TRUE;
8650a45ae5f8SJohn Marino 
8651*ef5ccd6cSJohn Marino     case NT_ARM_TLS:
8652*ef5ccd6cSJohn Marino       if (note->namesz == 6
8653*ef5ccd6cSJohn Marino 	  && strcmp (note->namedata, "LINUX") == 0)
8654*ef5ccd6cSJohn Marino 	return elfcore_grok_aarch_tls (abfd, note);
8655*ef5ccd6cSJohn Marino       else
8656*ef5ccd6cSJohn Marino 	return TRUE;
8657*ef5ccd6cSJohn Marino 
8658*ef5ccd6cSJohn Marino     case NT_ARM_HW_BREAK:
8659*ef5ccd6cSJohn Marino       if (note->namesz == 6
8660*ef5ccd6cSJohn Marino 	  && strcmp (note->namedata, "LINUX") == 0)
8661*ef5ccd6cSJohn Marino 	return elfcore_grok_aarch_hw_break (abfd, note);
8662*ef5ccd6cSJohn Marino       else
8663*ef5ccd6cSJohn Marino 	return TRUE;
8664*ef5ccd6cSJohn Marino 
8665*ef5ccd6cSJohn Marino     case NT_ARM_HW_WATCH:
8666*ef5ccd6cSJohn Marino       if (note->namesz == 6
8667*ef5ccd6cSJohn Marino 	  && strcmp (note->namedata, "LINUX") == 0)
8668*ef5ccd6cSJohn Marino 	return elfcore_grok_aarch_hw_watch (abfd, note);
8669*ef5ccd6cSJohn Marino       else
8670*ef5ccd6cSJohn Marino 	return TRUE;
8671*ef5ccd6cSJohn Marino 
86725796c8dcSSimon Schubert     case NT_PRPSINFO:
86735796c8dcSSimon Schubert     case NT_PSINFO:
86745796c8dcSSimon Schubert       if (bed->elf_backend_grok_psinfo)
86755796c8dcSSimon Schubert 	if ((*bed->elf_backend_grok_psinfo) (abfd, note))
86765796c8dcSSimon Schubert 	  return TRUE;
86775796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
86785796c8dcSSimon Schubert       return elfcore_grok_psinfo (abfd, note);
86795796c8dcSSimon Schubert #else
86805796c8dcSSimon Schubert       return TRUE;
86815796c8dcSSimon Schubert #endif
86825796c8dcSSimon Schubert 
86835796c8dcSSimon Schubert     case NT_AUXV:
86845796c8dcSSimon Schubert       {
86855796c8dcSSimon Schubert 	asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
86865796c8dcSSimon Schubert 							     SEC_HAS_CONTENTS);
86875796c8dcSSimon Schubert 
86885796c8dcSSimon Schubert 	if (sect == NULL)
86895796c8dcSSimon Schubert 	  return FALSE;
86905796c8dcSSimon Schubert 	sect->size = note->descsz;
86915796c8dcSSimon Schubert 	sect->filepos = note->descpos;
86925796c8dcSSimon Schubert 	sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
86935796c8dcSSimon Schubert 
86945796c8dcSSimon Schubert 	return TRUE;
86955796c8dcSSimon Schubert       }
8696*ef5ccd6cSJohn Marino 
8697*ef5ccd6cSJohn Marino     case NT_FILE:
8698*ef5ccd6cSJohn Marino       return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
8699*ef5ccd6cSJohn Marino 					      note);
8700*ef5ccd6cSJohn Marino 
8701*ef5ccd6cSJohn Marino     case NT_SIGINFO:
8702*ef5ccd6cSJohn Marino       return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
8703*ef5ccd6cSJohn Marino 					      note);
87045796c8dcSSimon Schubert     }
87055796c8dcSSimon Schubert }
87065796c8dcSSimon Schubert 
87075796c8dcSSimon Schubert static bfd_boolean
elfobj_grok_gnu_build_id(bfd * abfd,Elf_Internal_Note * note)87085796c8dcSSimon Schubert elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
87095796c8dcSSimon Schubert {
8710*ef5ccd6cSJohn Marino   struct elf_obj_tdata *t;
8711*ef5ccd6cSJohn Marino 
8712*ef5ccd6cSJohn Marino   if (note->descsz == 0)
87135796c8dcSSimon Schubert     return FALSE;
87145796c8dcSSimon Schubert 
8715*ef5ccd6cSJohn Marino   t = elf_tdata (abfd);
8716*ef5ccd6cSJohn Marino   t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
8717*ef5ccd6cSJohn Marino   if (t->build_id == NULL)
8718*ef5ccd6cSJohn Marino     return FALSE;
8719*ef5ccd6cSJohn Marino 
8720*ef5ccd6cSJohn Marino   t->build_id->size = note->descsz;
8721*ef5ccd6cSJohn Marino   memcpy (t->build_id->data, note->descdata, note->descsz);
87225796c8dcSSimon Schubert 
87235796c8dcSSimon Schubert   return TRUE;
87245796c8dcSSimon Schubert }
87255796c8dcSSimon Schubert 
87265796c8dcSSimon Schubert static bfd_boolean
elfobj_grok_gnu_note(bfd * abfd,Elf_Internal_Note * note)87275796c8dcSSimon Schubert elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
87285796c8dcSSimon Schubert {
87295796c8dcSSimon Schubert   switch (note->type)
87305796c8dcSSimon Schubert     {
87315796c8dcSSimon Schubert     default:
87325796c8dcSSimon Schubert       return TRUE;
87335796c8dcSSimon Schubert 
87345796c8dcSSimon Schubert     case NT_GNU_BUILD_ID:
87355796c8dcSSimon Schubert       return elfobj_grok_gnu_build_id (abfd, note);
87365796c8dcSSimon Schubert     }
87375796c8dcSSimon Schubert }
87385796c8dcSSimon Schubert 
87395796c8dcSSimon Schubert static bfd_boolean
elfobj_grok_stapsdt_note_1(bfd * abfd,Elf_Internal_Note * note)8740a45ae5f8SJohn Marino elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note)
8741a45ae5f8SJohn Marino {
8742a45ae5f8SJohn Marino   struct sdt_note *cur =
8743a45ae5f8SJohn Marino     (struct sdt_note *) bfd_alloc (abfd, sizeof (struct sdt_note)
8744a45ae5f8SJohn Marino 				   + note->descsz);
8745a45ae5f8SJohn Marino 
8746a45ae5f8SJohn Marino   cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head;
8747a45ae5f8SJohn Marino   cur->size = (bfd_size_type) note->descsz;
8748a45ae5f8SJohn Marino   memcpy (cur->data, note->descdata, note->descsz);
8749a45ae5f8SJohn Marino 
8750a45ae5f8SJohn Marino   elf_tdata (abfd)->sdt_note_head = cur;
8751a45ae5f8SJohn Marino 
8752a45ae5f8SJohn Marino   return TRUE;
8753a45ae5f8SJohn Marino }
8754a45ae5f8SJohn Marino 
8755a45ae5f8SJohn Marino static bfd_boolean
elfobj_grok_stapsdt_note(bfd * abfd,Elf_Internal_Note * note)8756a45ae5f8SJohn Marino elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
8757a45ae5f8SJohn Marino {
8758a45ae5f8SJohn Marino   switch (note->type)
8759a45ae5f8SJohn Marino     {
8760a45ae5f8SJohn Marino     case NT_STAPSDT:
8761a45ae5f8SJohn Marino       return elfobj_grok_stapsdt_note_1 (abfd, note);
8762a45ae5f8SJohn Marino 
8763a45ae5f8SJohn Marino     default:
8764a45ae5f8SJohn Marino       return TRUE;
8765a45ae5f8SJohn Marino     }
8766a45ae5f8SJohn Marino }
8767a45ae5f8SJohn Marino 
8768a45ae5f8SJohn Marino static bfd_boolean
elfcore_netbsd_get_lwpid(Elf_Internal_Note * note,int * lwpidp)87695796c8dcSSimon Schubert elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
87705796c8dcSSimon Schubert {
87715796c8dcSSimon Schubert   char *cp;
87725796c8dcSSimon Schubert 
87735796c8dcSSimon Schubert   cp = strchr (note->namedata, '@');
87745796c8dcSSimon Schubert   if (cp != NULL)
87755796c8dcSSimon Schubert     {
87765796c8dcSSimon Schubert       *lwpidp = atoi(cp + 1);
87775796c8dcSSimon Schubert       return TRUE;
87785796c8dcSSimon Schubert     }
87795796c8dcSSimon Schubert   return FALSE;
87805796c8dcSSimon Schubert }
87815796c8dcSSimon Schubert 
87825796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_netbsd_procinfo(bfd * abfd,Elf_Internal_Note * note)87835796c8dcSSimon Schubert elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
87845796c8dcSSimon Schubert {
87855796c8dcSSimon Schubert   /* Signal number at offset 0x08. */
8786*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->signal
87875796c8dcSSimon Schubert     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
87885796c8dcSSimon Schubert 
87895796c8dcSSimon Schubert   /* Process ID at offset 0x50. */
8790*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->pid
87915796c8dcSSimon Schubert     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
87925796c8dcSSimon Schubert 
87935796c8dcSSimon Schubert   /* Command name at 0x7c (max 32 bytes, including nul). */
8794*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->command
87955796c8dcSSimon Schubert     = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
87965796c8dcSSimon Schubert 
87975796c8dcSSimon Schubert   return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
87985796c8dcSSimon Schubert 					  note);
87995796c8dcSSimon Schubert }
88005796c8dcSSimon Schubert 
88015796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_netbsd_note(bfd * abfd,Elf_Internal_Note * note)88025796c8dcSSimon Schubert elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
88035796c8dcSSimon Schubert {
88045796c8dcSSimon Schubert   int lwp;
88055796c8dcSSimon Schubert 
88065796c8dcSSimon Schubert   if (elfcore_netbsd_get_lwpid (note, &lwp))
8807*ef5ccd6cSJohn Marino     elf_tdata (abfd)->core->lwpid = lwp;
88085796c8dcSSimon Schubert 
88095796c8dcSSimon Schubert   if (note->type == NT_NETBSDCORE_PROCINFO)
88105796c8dcSSimon Schubert     {
88115796c8dcSSimon Schubert       /* NetBSD-specific core "procinfo".  Note that we expect to
88125796c8dcSSimon Schubert 	 find this note before any of the others, which is fine,
88135796c8dcSSimon Schubert 	 since the kernel writes this note out first when it
88145796c8dcSSimon Schubert 	 creates a core file.  */
88155796c8dcSSimon Schubert 
88165796c8dcSSimon Schubert       return elfcore_grok_netbsd_procinfo (abfd, note);
88175796c8dcSSimon Schubert     }
88185796c8dcSSimon Schubert 
88195796c8dcSSimon Schubert   /* As of Jan 2002 there are no other machine-independent notes
88205796c8dcSSimon Schubert      defined for NetBSD core files.  If the note type is less
88215796c8dcSSimon Schubert      than the start of the machine-dependent note types, we don't
88225796c8dcSSimon Schubert      understand it.  */
88235796c8dcSSimon Schubert 
88245796c8dcSSimon Schubert   if (note->type < NT_NETBSDCORE_FIRSTMACH)
88255796c8dcSSimon Schubert     return TRUE;
88265796c8dcSSimon Schubert 
88275796c8dcSSimon Schubert 
88285796c8dcSSimon Schubert   switch (bfd_get_arch (abfd))
88295796c8dcSSimon Schubert     {
88305796c8dcSSimon Schubert       /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
88315796c8dcSSimon Schubert 	 PT_GETFPREGS == mach+2.  */
88325796c8dcSSimon Schubert 
88335796c8dcSSimon Schubert     case bfd_arch_alpha:
88345796c8dcSSimon Schubert     case bfd_arch_sparc:
88355796c8dcSSimon Schubert       switch (note->type)
88365796c8dcSSimon Schubert 	{
88375796c8dcSSimon Schubert 	case NT_NETBSDCORE_FIRSTMACH+0:
88385796c8dcSSimon Schubert 	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
88395796c8dcSSimon Schubert 
88405796c8dcSSimon Schubert 	case NT_NETBSDCORE_FIRSTMACH+2:
88415796c8dcSSimon Schubert 	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
88425796c8dcSSimon Schubert 
88435796c8dcSSimon Schubert 	default:
88445796c8dcSSimon Schubert 	  return TRUE;
88455796c8dcSSimon Schubert 	}
88465796c8dcSSimon Schubert 
88475796c8dcSSimon Schubert       /* On all other arch's, PT_GETREGS == mach+1 and
88485796c8dcSSimon Schubert 	 PT_GETFPREGS == mach+3.  */
88495796c8dcSSimon Schubert 
88505796c8dcSSimon Schubert     default:
88515796c8dcSSimon Schubert       switch (note->type)
88525796c8dcSSimon Schubert 	{
88535796c8dcSSimon Schubert 	case NT_NETBSDCORE_FIRSTMACH+1:
88545796c8dcSSimon Schubert 	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
88555796c8dcSSimon Schubert 
88565796c8dcSSimon Schubert 	case NT_NETBSDCORE_FIRSTMACH+3:
88575796c8dcSSimon Schubert 	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
88585796c8dcSSimon Schubert 
88595796c8dcSSimon Schubert 	default:
88605796c8dcSSimon Schubert 	  return TRUE;
88615796c8dcSSimon Schubert 	}
88625796c8dcSSimon Schubert     }
88635796c8dcSSimon Schubert     /* NOTREACHED */
88645796c8dcSSimon Schubert }
88655796c8dcSSimon Schubert 
88665796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_openbsd_procinfo(bfd * abfd,Elf_Internal_Note * note)88675796c8dcSSimon Schubert elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
88685796c8dcSSimon Schubert {
88695796c8dcSSimon Schubert   /* Signal number at offset 0x08. */
8870*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->signal
88715796c8dcSSimon Schubert     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
88725796c8dcSSimon Schubert 
88735796c8dcSSimon Schubert   /* Process ID at offset 0x20. */
8874*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->pid
88755796c8dcSSimon Schubert     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
88765796c8dcSSimon Schubert 
88775796c8dcSSimon Schubert   /* Command name at 0x48 (max 32 bytes, including nul). */
8878*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->command
88795796c8dcSSimon Schubert     = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
88805796c8dcSSimon Schubert 
88815796c8dcSSimon Schubert   return TRUE;
88825796c8dcSSimon Schubert }
88835796c8dcSSimon Schubert 
88845796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_openbsd_note(bfd * abfd,Elf_Internal_Note * note)88855796c8dcSSimon Schubert elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
88865796c8dcSSimon Schubert {
88875796c8dcSSimon Schubert   if (note->type == NT_OPENBSD_PROCINFO)
88885796c8dcSSimon Schubert     return elfcore_grok_openbsd_procinfo (abfd, note);
88895796c8dcSSimon Schubert 
88905796c8dcSSimon Schubert   if (note->type == NT_OPENBSD_REGS)
88915796c8dcSSimon Schubert     return elfcore_make_note_pseudosection (abfd, ".reg", note);
88925796c8dcSSimon Schubert 
88935796c8dcSSimon Schubert   if (note->type == NT_OPENBSD_FPREGS)
88945796c8dcSSimon Schubert     return elfcore_make_note_pseudosection (abfd, ".reg2", note);
88955796c8dcSSimon Schubert 
88965796c8dcSSimon Schubert   if (note->type == NT_OPENBSD_XFPREGS)
88975796c8dcSSimon Schubert     return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
88985796c8dcSSimon Schubert 
88995796c8dcSSimon Schubert   if (note->type == NT_OPENBSD_AUXV)
89005796c8dcSSimon Schubert     {
89015796c8dcSSimon Schubert       asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
89025796c8dcSSimon Schubert 							   SEC_HAS_CONTENTS);
89035796c8dcSSimon Schubert 
89045796c8dcSSimon Schubert       if (sect == NULL)
89055796c8dcSSimon Schubert 	return FALSE;
89065796c8dcSSimon Schubert       sect->size = note->descsz;
89075796c8dcSSimon Schubert       sect->filepos = note->descpos;
89085796c8dcSSimon Schubert       sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
89095796c8dcSSimon Schubert 
89105796c8dcSSimon Schubert       return TRUE;
89115796c8dcSSimon Schubert     }
89125796c8dcSSimon Schubert 
89135796c8dcSSimon Schubert   if (note->type == NT_OPENBSD_WCOOKIE)
89145796c8dcSSimon Schubert     {
89155796c8dcSSimon Schubert       asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
89165796c8dcSSimon Schubert 							   SEC_HAS_CONTENTS);
89175796c8dcSSimon Schubert 
89185796c8dcSSimon Schubert       if (sect == NULL)
89195796c8dcSSimon Schubert 	return FALSE;
89205796c8dcSSimon Schubert       sect->size = note->descsz;
89215796c8dcSSimon Schubert       sect->filepos = note->descpos;
89225796c8dcSSimon Schubert       sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
89235796c8dcSSimon Schubert 
89245796c8dcSSimon Schubert       return TRUE;
89255796c8dcSSimon Schubert     }
89265796c8dcSSimon Schubert 
89275796c8dcSSimon Schubert   return TRUE;
89285796c8dcSSimon Schubert }
89295796c8dcSSimon Schubert 
89305796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_nto_status(bfd * abfd,Elf_Internal_Note * note,long * tid)89315796c8dcSSimon Schubert elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
89325796c8dcSSimon Schubert {
89335796c8dcSSimon Schubert   void *ddata = note->descdata;
89345796c8dcSSimon Schubert   char buf[100];
89355796c8dcSSimon Schubert   char *name;
89365796c8dcSSimon Schubert   asection *sect;
89375796c8dcSSimon Schubert   short sig;
89385796c8dcSSimon Schubert   unsigned flags;
89395796c8dcSSimon Schubert 
89405796c8dcSSimon Schubert   /* nto_procfs_status 'pid' field is at offset 0.  */
8941*ef5ccd6cSJohn Marino   elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
89425796c8dcSSimon Schubert 
89435796c8dcSSimon Schubert   /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
89445796c8dcSSimon Schubert   *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
89455796c8dcSSimon Schubert 
89465796c8dcSSimon Schubert   /* nto_procfs_status 'flags' field is at offset 8.  */
89475796c8dcSSimon Schubert   flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
89485796c8dcSSimon Schubert 
89495796c8dcSSimon Schubert   /* nto_procfs_status 'what' field is at offset 14.  */
89505796c8dcSSimon Schubert   if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
89515796c8dcSSimon Schubert     {
8952*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->signal = sig;
8953*ef5ccd6cSJohn Marino       elf_tdata (abfd)->core->lwpid = *tid;
89545796c8dcSSimon Schubert     }
89555796c8dcSSimon Schubert 
89565796c8dcSSimon Schubert   /* _DEBUG_FLAG_CURTID (current thread) is 0x80.  Some cores
89575796c8dcSSimon Schubert      do not come from signals so we make sure we set the current
89585796c8dcSSimon Schubert      thread just in case.  */
89595796c8dcSSimon Schubert   if (flags & 0x00000080)
8960*ef5ccd6cSJohn Marino     elf_tdata (abfd)->core->lwpid = *tid;
89615796c8dcSSimon Schubert 
89625796c8dcSSimon Schubert   /* Make a ".qnx_core_status/%d" section.  */
89635796c8dcSSimon Schubert   sprintf (buf, ".qnx_core_status/%ld", *tid);
89645796c8dcSSimon Schubert 
89655796c8dcSSimon Schubert   name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
89665796c8dcSSimon Schubert   if (name == NULL)
89675796c8dcSSimon Schubert     return FALSE;
89685796c8dcSSimon Schubert   strcpy (name, buf);
89695796c8dcSSimon Schubert 
89705796c8dcSSimon Schubert   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
89715796c8dcSSimon Schubert   if (sect == NULL)
89725796c8dcSSimon Schubert     return FALSE;
89735796c8dcSSimon Schubert 
89745796c8dcSSimon Schubert   sect->size            = note->descsz;
89755796c8dcSSimon Schubert   sect->filepos         = note->descpos;
89765796c8dcSSimon Schubert   sect->alignment_power = 2;
89775796c8dcSSimon Schubert 
89785796c8dcSSimon Schubert   return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
89795796c8dcSSimon Schubert }
89805796c8dcSSimon Schubert 
89815796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_nto_regs(bfd * abfd,Elf_Internal_Note * note,long tid,char * base)89825796c8dcSSimon Schubert elfcore_grok_nto_regs (bfd *abfd,
89835796c8dcSSimon Schubert 		       Elf_Internal_Note *note,
89845796c8dcSSimon Schubert 		       long tid,
89855796c8dcSSimon Schubert 		       char *base)
89865796c8dcSSimon Schubert {
89875796c8dcSSimon Schubert   char buf[100];
89885796c8dcSSimon Schubert   char *name;
89895796c8dcSSimon Schubert   asection *sect;
89905796c8dcSSimon Schubert 
89915796c8dcSSimon Schubert   /* Make a "(base)/%d" section.  */
89925796c8dcSSimon Schubert   sprintf (buf, "%s/%ld", base, tid);
89935796c8dcSSimon Schubert 
89945796c8dcSSimon Schubert   name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
89955796c8dcSSimon Schubert   if (name == NULL)
89965796c8dcSSimon Schubert     return FALSE;
89975796c8dcSSimon Schubert   strcpy (name, buf);
89985796c8dcSSimon Schubert 
89995796c8dcSSimon Schubert   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
90005796c8dcSSimon Schubert   if (sect == NULL)
90015796c8dcSSimon Schubert     return FALSE;
90025796c8dcSSimon Schubert 
90035796c8dcSSimon Schubert   sect->size            = note->descsz;
90045796c8dcSSimon Schubert   sect->filepos         = note->descpos;
90055796c8dcSSimon Schubert   sect->alignment_power = 2;
90065796c8dcSSimon Schubert 
90075796c8dcSSimon Schubert   /* This is the current thread.  */
9008*ef5ccd6cSJohn Marino   if (elf_tdata (abfd)->core->lwpid == tid)
90095796c8dcSSimon Schubert     return elfcore_maybe_make_sect (abfd, base, sect);
90105796c8dcSSimon Schubert 
90115796c8dcSSimon Schubert   return TRUE;
90125796c8dcSSimon Schubert }
90135796c8dcSSimon Schubert 
90145796c8dcSSimon Schubert #define BFD_QNT_CORE_INFO	7
90155796c8dcSSimon Schubert #define BFD_QNT_CORE_STATUS	8
90165796c8dcSSimon Schubert #define BFD_QNT_CORE_GREG	9
90175796c8dcSSimon Schubert #define BFD_QNT_CORE_FPREG	10
90185796c8dcSSimon Schubert 
90195796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_nto_note(bfd * abfd,Elf_Internal_Note * note)90205796c8dcSSimon Schubert elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
90215796c8dcSSimon Schubert {
90225796c8dcSSimon Schubert   /* Every GREG section has a STATUS section before it.  Store the
90235796c8dcSSimon Schubert      tid from the previous call to pass down to the next gregs
90245796c8dcSSimon Schubert      function.  */
90255796c8dcSSimon Schubert   static long tid = 1;
90265796c8dcSSimon Schubert 
90275796c8dcSSimon Schubert   switch (note->type)
90285796c8dcSSimon Schubert     {
90295796c8dcSSimon Schubert     case BFD_QNT_CORE_INFO:
90305796c8dcSSimon Schubert       return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
90315796c8dcSSimon Schubert     case BFD_QNT_CORE_STATUS:
90325796c8dcSSimon Schubert       return elfcore_grok_nto_status (abfd, note, &tid);
90335796c8dcSSimon Schubert     case BFD_QNT_CORE_GREG:
90345796c8dcSSimon Schubert       return elfcore_grok_nto_regs (abfd, note, tid, ".reg");
90355796c8dcSSimon Schubert     case BFD_QNT_CORE_FPREG:
90365796c8dcSSimon Schubert       return elfcore_grok_nto_regs (abfd, note, tid, ".reg2");
90375796c8dcSSimon Schubert     default:
90385796c8dcSSimon Schubert       return TRUE;
90395796c8dcSSimon Schubert     }
90405796c8dcSSimon Schubert }
90415796c8dcSSimon Schubert 
90425796c8dcSSimon Schubert static bfd_boolean
elfcore_grok_spu_note(bfd * abfd,Elf_Internal_Note * note)90435796c8dcSSimon Schubert elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note)
90445796c8dcSSimon Schubert {
90455796c8dcSSimon Schubert   char *name;
90465796c8dcSSimon Schubert   asection *sect;
90475796c8dcSSimon Schubert   size_t len;
90485796c8dcSSimon Schubert 
90495796c8dcSSimon Schubert   /* Use note name as section name.  */
90505796c8dcSSimon Schubert   len = note->namesz;
90515796c8dcSSimon Schubert   name = (char *) bfd_alloc (abfd, len);
90525796c8dcSSimon Schubert   if (name == NULL)
90535796c8dcSSimon Schubert     return FALSE;
90545796c8dcSSimon Schubert   memcpy (name, note->namedata, len);
90555796c8dcSSimon Schubert   name[len - 1] = '\0';
90565796c8dcSSimon Schubert 
90575796c8dcSSimon Schubert   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
90585796c8dcSSimon Schubert   if (sect == NULL)
90595796c8dcSSimon Schubert     return FALSE;
90605796c8dcSSimon Schubert 
90615796c8dcSSimon Schubert   sect->size            = note->descsz;
90625796c8dcSSimon Schubert   sect->filepos         = note->descpos;
90635796c8dcSSimon Schubert   sect->alignment_power = 1;
90645796c8dcSSimon Schubert 
90655796c8dcSSimon Schubert   return TRUE;
90665796c8dcSSimon Schubert }
90675796c8dcSSimon Schubert 
90685796c8dcSSimon Schubert /* Function: elfcore_write_note
90695796c8dcSSimon Schubert 
90705796c8dcSSimon Schubert    Inputs:
90715796c8dcSSimon Schubert      buffer to hold note, and current size of buffer
90725796c8dcSSimon Schubert      name of note
90735796c8dcSSimon Schubert      type of note
90745796c8dcSSimon Schubert      data for note
90755796c8dcSSimon Schubert      size of data for note
90765796c8dcSSimon Schubert 
90775796c8dcSSimon Schubert    Writes note to end of buffer.  ELF64 notes are written exactly as
90785796c8dcSSimon Schubert    for ELF32, despite the current (as of 2006) ELF gabi specifying
90795796c8dcSSimon Schubert    that they ought to have 8-byte namesz and descsz field, and have
90805796c8dcSSimon Schubert    8-byte alignment.  Other writers, eg. Linux kernel, do the same.
90815796c8dcSSimon Schubert 
90825796c8dcSSimon Schubert    Return:
90835796c8dcSSimon Schubert    Pointer to realloc'd buffer, *BUFSIZ updated.  */
90845796c8dcSSimon Schubert 
90855796c8dcSSimon Schubert char *
elfcore_write_note(bfd * abfd,char * buf,int * bufsiz,const char * name,int type,const void * input,int size)90865796c8dcSSimon Schubert elfcore_write_note (bfd *abfd,
90875796c8dcSSimon Schubert 		    char *buf,
90885796c8dcSSimon Schubert 		    int *bufsiz,
90895796c8dcSSimon Schubert 		    const char *name,
90905796c8dcSSimon Schubert 		    int type,
90915796c8dcSSimon Schubert 		    const void *input,
90925796c8dcSSimon Schubert 		    int size)
90935796c8dcSSimon Schubert {
90945796c8dcSSimon Schubert   Elf_External_Note *xnp;
90955796c8dcSSimon Schubert   size_t namesz;
90965796c8dcSSimon Schubert   size_t newspace;
90975796c8dcSSimon Schubert   char *dest;
90985796c8dcSSimon Schubert 
90995796c8dcSSimon Schubert   namesz = 0;
91005796c8dcSSimon Schubert   if (name != NULL)
91015796c8dcSSimon Schubert     namesz = strlen (name) + 1;
91025796c8dcSSimon Schubert 
91035796c8dcSSimon Schubert   newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
91045796c8dcSSimon Schubert 
91055796c8dcSSimon Schubert   buf = (char *) realloc (buf, *bufsiz + newspace);
91065796c8dcSSimon Schubert   if (buf == NULL)
91075796c8dcSSimon Schubert     return buf;
91085796c8dcSSimon Schubert   dest = buf + *bufsiz;
91095796c8dcSSimon Schubert   *bufsiz += newspace;
91105796c8dcSSimon Schubert   xnp = (Elf_External_Note *) dest;
91115796c8dcSSimon Schubert   H_PUT_32 (abfd, namesz, xnp->namesz);
91125796c8dcSSimon Schubert   H_PUT_32 (abfd, size, xnp->descsz);
91135796c8dcSSimon Schubert   H_PUT_32 (abfd, type, xnp->type);
91145796c8dcSSimon Schubert   dest = xnp->name;
91155796c8dcSSimon Schubert   if (name != NULL)
91165796c8dcSSimon Schubert     {
91175796c8dcSSimon Schubert       memcpy (dest, name, namesz);
91185796c8dcSSimon Schubert       dest += namesz;
91195796c8dcSSimon Schubert       while (namesz & 3)
91205796c8dcSSimon Schubert 	{
91215796c8dcSSimon Schubert 	  *dest++ = '\0';
91225796c8dcSSimon Schubert 	  ++namesz;
91235796c8dcSSimon Schubert 	}
91245796c8dcSSimon Schubert     }
91255796c8dcSSimon Schubert   memcpy (dest, input, size);
91265796c8dcSSimon Schubert   dest += size;
91275796c8dcSSimon Schubert   while (size & 3)
91285796c8dcSSimon Schubert     {
91295796c8dcSSimon Schubert       *dest++ = '\0';
91305796c8dcSSimon Schubert       ++size;
91315796c8dcSSimon Schubert     }
91325796c8dcSSimon Schubert   return buf;
91335796c8dcSSimon Schubert }
91345796c8dcSSimon Schubert 
91355796c8dcSSimon Schubert char *
elfcore_write_prpsinfo(bfd * abfd,char * buf,int * bufsiz,const char * fname,const char * psargs)91365796c8dcSSimon Schubert elfcore_write_prpsinfo (bfd  *abfd,
91375796c8dcSSimon Schubert 			char *buf,
91385796c8dcSSimon Schubert 			int  *bufsiz,
91395796c8dcSSimon Schubert 			const char *fname,
91405796c8dcSSimon Schubert 			const char *psargs)
91415796c8dcSSimon Schubert {
91425796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
91435796c8dcSSimon Schubert 
91445796c8dcSSimon Schubert   if (bed->elf_backend_write_core_note != NULL)
91455796c8dcSSimon Schubert     {
91465796c8dcSSimon Schubert       char *ret;
91475796c8dcSSimon Schubert       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
91485796c8dcSSimon Schubert 						 NT_PRPSINFO, fname, psargs);
91495796c8dcSSimon Schubert       if (ret != NULL)
91505796c8dcSSimon Schubert 	return ret;
91515796c8dcSSimon Schubert     }
91525796c8dcSSimon Schubert 
9153*ef5ccd6cSJohn Marino #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
91545796c8dcSSimon Schubert #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
91555796c8dcSSimon Schubert   if (bed->s->elfclass == ELFCLASS32)
91565796c8dcSSimon Schubert     {
91575796c8dcSSimon Schubert #if defined (HAVE_PSINFO32_T)
91585796c8dcSSimon Schubert       psinfo32_t data;
91595796c8dcSSimon Schubert       int note_type = NT_PSINFO;
91605796c8dcSSimon Schubert #else
91615796c8dcSSimon Schubert       prpsinfo32_t data;
91625796c8dcSSimon Schubert       int note_type = NT_PRPSINFO;
91635796c8dcSSimon Schubert #endif
91645796c8dcSSimon Schubert 
91655796c8dcSSimon Schubert       memset (&data, 0, sizeof (data));
91665796c8dcSSimon Schubert       strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
91675796c8dcSSimon Schubert       strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
91685796c8dcSSimon Schubert       return elfcore_write_note (abfd, buf, bufsiz,
9169*ef5ccd6cSJohn Marino 				 "CORE", note_type, &data, sizeof (data));
91705796c8dcSSimon Schubert     }
91715796c8dcSSimon Schubert   else
91725796c8dcSSimon Schubert #endif
91735796c8dcSSimon Schubert     {
91745796c8dcSSimon Schubert #if defined (HAVE_PSINFO_T)
91755796c8dcSSimon Schubert       psinfo_t data;
91765796c8dcSSimon Schubert       int note_type = NT_PSINFO;
91775796c8dcSSimon Schubert #else
91785796c8dcSSimon Schubert       prpsinfo_t data;
91795796c8dcSSimon Schubert       int note_type = NT_PRPSINFO;
91805796c8dcSSimon Schubert #endif
91815796c8dcSSimon Schubert 
91825796c8dcSSimon Schubert       memset (&data, 0, sizeof (data));
91835796c8dcSSimon Schubert       strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
91845796c8dcSSimon Schubert       strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
91855796c8dcSSimon Schubert       return elfcore_write_note (abfd, buf, bufsiz,
9186*ef5ccd6cSJohn Marino 				 "CORE", note_type, &data, sizeof (data));
91875796c8dcSSimon Schubert     }
91885796c8dcSSimon Schubert #endif	/* PSINFO_T or PRPSINFO_T */
91895796c8dcSSimon Schubert 
9190*ef5ccd6cSJohn Marino   free (buf);
9191*ef5ccd6cSJohn Marino   return NULL;
9192*ef5ccd6cSJohn Marino }
9193*ef5ccd6cSJohn Marino 
9194*ef5ccd6cSJohn Marino char *
elfcore_write_linux_prpsinfo32(bfd * abfd,char * buf,int * bufsiz,const struct elf_internal_linux_prpsinfo * prpsinfo)9195*ef5ccd6cSJohn Marino elfcore_write_linux_prpsinfo32
9196*ef5ccd6cSJohn Marino   (bfd *abfd, char *buf, int *bufsiz,
9197*ef5ccd6cSJohn Marino    const struct elf_internal_linux_prpsinfo *prpsinfo)
9198*ef5ccd6cSJohn Marino {
9199*ef5ccd6cSJohn Marino   struct elf_external_linux_prpsinfo32 data;
9200*ef5ccd6cSJohn Marino 
9201*ef5ccd6cSJohn Marino   memset (&data, 0, sizeof (data));
9202*ef5ccd6cSJohn Marino   LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
9203*ef5ccd6cSJohn Marino 
9204*ef5ccd6cSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
9205*ef5ccd6cSJohn Marino 			     &data, sizeof (data));
9206*ef5ccd6cSJohn Marino }
9207*ef5ccd6cSJohn Marino 
9208*ef5ccd6cSJohn Marino char *
elfcore_write_linux_prpsinfo64(bfd * abfd,char * buf,int * bufsiz,const struct elf_internal_linux_prpsinfo * prpsinfo)9209*ef5ccd6cSJohn Marino elfcore_write_linux_prpsinfo64
9210*ef5ccd6cSJohn Marino   (bfd *abfd, char *buf, int *bufsiz,
9211*ef5ccd6cSJohn Marino    const struct elf_internal_linux_prpsinfo *prpsinfo)
9212*ef5ccd6cSJohn Marino {
9213*ef5ccd6cSJohn Marino   struct elf_external_linux_prpsinfo64 data;
9214*ef5ccd6cSJohn Marino 
9215*ef5ccd6cSJohn Marino   memset (&data, 0, sizeof (data));
9216*ef5ccd6cSJohn Marino   LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
9217*ef5ccd6cSJohn Marino 
9218*ef5ccd6cSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9219*ef5ccd6cSJohn Marino 			     "CORE", NT_PRPSINFO, &data, sizeof (data));
9220*ef5ccd6cSJohn Marino }
9221*ef5ccd6cSJohn Marino 
92225796c8dcSSimon Schubert char *
elfcore_write_prstatus(bfd * abfd,char * buf,int * bufsiz,long pid,int cursig,const void * gregs)92235796c8dcSSimon Schubert elfcore_write_prstatus (bfd *abfd,
92245796c8dcSSimon Schubert 			char *buf,
92255796c8dcSSimon Schubert 			int *bufsiz,
92265796c8dcSSimon Schubert 			long pid,
92275796c8dcSSimon Schubert 			int cursig,
92285796c8dcSSimon Schubert 			const void *gregs)
92295796c8dcSSimon Schubert {
92305796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
92315796c8dcSSimon Schubert 
92325796c8dcSSimon Schubert   if (bed->elf_backend_write_core_note != NULL)
92335796c8dcSSimon Schubert     {
92345796c8dcSSimon Schubert       char *ret;
92355796c8dcSSimon Schubert       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
92365796c8dcSSimon Schubert 						 NT_PRSTATUS,
92375796c8dcSSimon Schubert 						 pid, cursig, gregs);
92385796c8dcSSimon Schubert       if (ret != NULL)
92395796c8dcSSimon Schubert 	return ret;
92405796c8dcSSimon Schubert     }
92415796c8dcSSimon Schubert 
9242*ef5ccd6cSJohn Marino #if defined (HAVE_PRSTATUS_T)
92435796c8dcSSimon Schubert #if defined (HAVE_PRSTATUS32_T)
92445796c8dcSSimon Schubert   if (bed->s->elfclass == ELFCLASS32)
92455796c8dcSSimon Schubert     {
92465796c8dcSSimon Schubert       prstatus32_t prstat;
92475796c8dcSSimon Schubert 
92485796c8dcSSimon Schubert       memset (&prstat, 0, sizeof (prstat));
92495796c8dcSSimon Schubert       prstat.pr_pid = pid;
92505796c8dcSSimon Schubert       prstat.pr_cursig = cursig;
92515796c8dcSSimon Schubert       memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
9252*ef5ccd6cSJohn Marino       return elfcore_write_note (abfd, buf, bufsiz, "CORE",
92535796c8dcSSimon Schubert 				 NT_PRSTATUS, &prstat, sizeof (prstat));
92545796c8dcSSimon Schubert     }
92555796c8dcSSimon Schubert   else
92565796c8dcSSimon Schubert #endif
92575796c8dcSSimon Schubert     {
92585796c8dcSSimon Schubert       prstatus_t prstat;
92595796c8dcSSimon Schubert 
92605796c8dcSSimon Schubert       memset (&prstat, 0, sizeof (prstat));
92615796c8dcSSimon Schubert       prstat.pr_pid = pid;
92625796c8dcSSimon Schubert       prstat.pr_cursig = cursig;
92635796c8dcSSimon Schubert       memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
9264*ef5ccd6cSJohn Marino       return elfcore_write_note (abfd, buf, bufsiz, "CORE",
92655796c8dcSSimon Schubert 				 NT_PRSTATUS, &prstat, sizeof (prstat));
92665796c8dcSSimon Schubert     }
92675796c8dcSSimon Schubert #endif /* HAVE_PRSTATUS_T */
92685796c8dcSSimon Schubert 
9269*ef5ccd6cSJohn Marino   free (buf);
9270*ef5ccd6cSJohn Marino   return NULL;
9271*ef5ccd6cSJohn Marino }
9272*ef5ccd6cSJohn Marino 
92735796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T)
92745796c8dcSSimon Schubert char *
elfcore_write_lwpstatus(bfd * abfd,char * buf,int * bufsiz,long pid,int cursig,const void * gregs)92755796c8dcSSimon Schubert elfcore_write_lwpstatus (bfd *abfd,
92765796c8dcSSimon Schubert 			 char *buf,
92775796c8dcSSimon Schubert 			 int *bufsiz,
92785796c8dcSSimon Schubert 			 long pid,
92795796c8dcSSimon Schubert 			 int cursig,
92805796c8dcSSimon Schubert 			 const void *gregs)
92815796c8dcSSimon Schubert {
92825796c8dcSSimon Schubert   lwpstatus_t lwpstat;
92835796c8dcSSimon Schubert   const char *note_name = "CORE";
92845796c8dcSSimon Schubert 
92855796c8dcSSimon Schubert   memset (&lwpstat, 0, sizeof (lwpstat));
92865796c8dcSSimon Schubert   lwpstat.pr_lwpid  = pid >> 16;
92875796c8dcSSimon Schubert   lwpstat.pr_cursig = cursig;
92885796c8dcSSimon Schubert #if defined (HAVE_LWPSTATUS_T_PR_REG)
92895796c8dcSSimon Schubert   memcpy (lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
92905796c8dcSSimon Schubert #elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
92915796c8dcSSimon Schubert #if !defined(gregs)
92925796c8dcSSimon Schubert   memcpy (lwpstat.pr_context.uc_mcontext.gregs,
92935796c8dcSSimon Schubert 	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
92945796c8dcSSimon Schubert #else
92955796c8dcSSimon Schubert   memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
92965796c8dcSSimon Schubert 	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
92975796c8dcSSimon Schubert #endif
92985796c8dcSSimon Schubert #endif
92995796c8dcSSimon Schubert   return elfcore_write_note (abfd, buf, bufsiz, note_name,
93005796c8dcSSimon Schubert 			     NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
93015796c8dcSSimon Schubert }
93025796c8dcSSimon Schubert #endif /* HAVE_LWPSTATUS_T */
93035796c8dcSSimon Schubert 
93045796c8dcSSimon Schubert #if defined (HAVE_PSTATUS_T)
93055796c8dcSSimon Schubert char *
elfcore_write_pstatus(bfd * abfd,char * buf,int * bufsiz,long pid,int cursig ATTRIBUTE_UNUSED,const void * gregs ATTRIBUTE_UNUSED)93065796c8dcSSimon Schubert elfcore_write_pstatus (bfd *abfd,
93075796c8dcSSimon Schubert 		       char *buf,
93085796c8dcSSimon Schubert 		       int *bufsiz,
93095796c8dcSSimon Schubert 		       long pid,
93105796c8dcSSimon Schubert 		       int cursig ATTRIBUTE_UNUSED,
93115796c8dcSSimon Schubert 		       const void *gregs ATTRIBUTE_UNUSED)
93125796c8dcSSimon Schubert {
93135796c8dcSSimon Schubert   const char *note_name = "CORE";
93145796c8dcSSimon Schubert #if defined (HAVE_PSTATUS32_T)
93155796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
93165796c8dcSSimon Schubert 
93175796c8dcSSimon Schubert   if (bed->s->elfclass == ELFCLASS32)
93185796c8dcSSimon Schubert     {
93195796c8dcSSimon Schubert       pstatus32_t pstat;
93205796c8dcSSimon Schubert 
93215796c8dcSSimon Schubert       memset (&pstat, 0, sizeof (pstat));
93225796c8dcSSimon Schubert       pstat.pr_pid = pid & 0xffff;
93235796c8dcSSimon Schubert       buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
93245796c8dcSSimon Schubert 				NT_PSTATUS, &pstat, sizeof (pstat));
93255796c8dcSSimon Schubert       return buf;
93265796c8dcSSimon Schubert     }
93275796c8dcSSimon Schubert   else
93285796c8dcSSimon Schubert #endif
93295796c8dcSSimon Schubert     {
93305796c8dcSSimon Schubert       pstatus_t pstat;
93315796c8dcSSimon Schubert 
93325796c8dcSSimon Schubert       memset (&pstat, 0, sizeof (pstat));
93335796c8dcSSimon Schubert       pstat.pr_pid = pid & 0xffff;
93345796c8dcSSimon Schubert       buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
93355796c8dcSSimon Schubert 				NT_PSTATUS, &pstat, sizeof (pstat));
93365796c8dcSSimon Schubert       return buf;
93375796c8dcSSimon Schubert     }
93385796c8dcSSimon Schubert }
93395796c8dcSSimon Schubert #endif /* HAVE_PSTATUS_T */
93405796c8dcSSimon Schubert 
93415796c8dcSSimon Schubert char *
elfcore_write_prfpreg(bfd * abfd,char * buf,int * bufsiz,const void * fpregs,int size)93425796c8dcSSimon Schubert elfcore_write_prfpreg (bfd *abfd,
93435796c8dcSSimon Schubert 		       char *buf,
93445796c8dcSSimon Schubert 		       int *bufsiz,
93455796c8dcSSimon Schubert 		       const void *fpregs,
93465796c8dcSSimon Schubert 		       int size)
93475796c8dcSSimon Schubert {
93485796c8dcSSimon Schubert   const char *note_name = "CORE";
93495796c8dcSSimon Schubert   return elfcore_write_note (abfd, buf, bufsiz,
93505796c8dcSSimon Schubert 			     note_name, NT_FPREGSET, fpregs, size);
93515796c8dcSSimon Schubert }
93525796c8dcSSimon Schubert 
93535796c8dcSSimon Schubert char *
elfcore_write_prxfpreg(bfd * abfd,char * buf,int * bufsiz,const void * xfpregs,int size)93545796c8dcSSimon Schubert elfcore_write_prxfpreg (bfd *abfd,
93555796c8dcSSimon Schubert 			char *buf,
93565796c8dcSSimon Schubert 			int *bufsiz,
93575796c8dcSSimon Schubert 			const void *xfpregs,
93585796c8dcSSimon Schubert 			int size)
93595796c8dcSSimon Schubert {
93605796c8dcSSimon Schubert   char *note_name = "LINUX";
93615796c8dcSSimon Schubert   return elfcore_write_note (abfd, buf, bufsiz,
93625796c8dcSSimon Schubert 			     note_name, NT_PRXFPREG, xfpregs, size);
93635796c8dcSSimon Schubert }
93645796c8dcSSimon Schubert 
93655796c8dcSSimon Schubert char *
elfcore_write_xstatereg(bfd * abfd,char * buf,int * bufsiz,const void * xfpregs,int size)9366cf7f2e2dSJohn Marino elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
9367cf7f2e2dSJohn Marino 			 const void *xfpregs, int size)
9368cf7f2e2dSJohn Marino {
9369cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9370cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9371cf7f2e2dSJohn Marino 			     note_name, NT_X86_XSTATE, xfpregs, size);
9372cf7f2e2dSJohn Marino }
9373cf7f2e2dSJohn Marino 
9374cf7f2e2dSJohn Marino char *
elfcore_write_ppc_vmx(bfd * abfd,char * buf,int * bufsiz,const void * ppc_vmx,int size)93755796c8dcSSimon Schubert elfcore_write_ppc_vmx (bfd *abfd,
93765796c8dcSSimon Schubert 		       char *buf,
93775796c8dcSSimon Schubert 		       int *bufsiz,
93785796c8dcSSimon Schubert 		       const void *ppc_vmx,
93795796c8dcSSimon Schubert 		       int size)
93805796c8dcSSimon Schubert {
93815796c8dcSSimon Schubert   char *note_name = "LINUX";
93825796c8dcSSimon Schubert   return elfcore_write_note (abfd, buf, bufsiz,
93835796c8dcSSimon Schubert 			     note_name, NT_PPC_VMX, ppc_vmx, size);
93845796c8dcSSimon Schubert }
93855796c8dcSSimon Schubert 
93865796c8dcSSimon Schubert char *
elfcore_write_ppc_vsx(bfd * abfd,char * buf,int * bufsiz,const void * ppc_vsx,int size)93875796c8dcSSimon Schubert elfcore_write_ppc_vsx (bfd *abfd,
93885796c8dcSSimon Schubert                        char *buf,
93895796c8dcSSimon Schubert                        int *bufsiz,
93905796c8dcSSimon Schubert                        const void *ppc_vsx,
93915796c8dcSSimon Schubert                        int size)
93925796c8dcSSimon Schubert {
93935796c8dcSSimon Schubert   char *note_name = "LINUX";
93945796c8dcSSimon Schubert   return elfcore_write_note (abfd, buf, bufsiz,
93955796c8dcSSimon Schubert                              note_name, NT_PPC_VSX, ppc_vsx, size);
93965796c8dcSSimon Schubert }
93975796c8dcSSimon Schubert 
9398cf7f2e2dSJohn Marino static char *
elfcore_write_s390_high_gprs(bfd * abfd,char * buf,int * bufsiz,const void * s390_high_gprs,int size)9399cf7f2e2dSJohn Marino elfcore_write_s390_high_gprs (bfd *abfd,
9400cf7f2e2dSJohn Marino 			      char *buf,
9401cf7f2e2dSJohn Marino 			      int *bufsiz,
9402cf7f2e2dSJohn Marino 			      const void *s390_high_gprs,
9403cf7f2e2dSJohn Marino 			      int size)
9404cf7f2e2dSJohn Marino {
9405cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9406cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9407cf7f2e2dSJohn Marino                              note_name, NT_S390_HIGH_GPRS,
9408cf7f2e2dSJohn Marino 			     s390_high_gprs, size);
9409cf7f2e2dSJohn Marino }
9410cf7f2e2dSJohn Marino 
9411cf7f2e2dSJohn Marino char *
elfcore_write_s390_timer(bfd * abfd,char * buf,int * bufsiz,const void * s390_timer,int size)9412cf7f2e2dSJohn Marino elfcore_write_s390_timer (bfd *abfd,
9413cf7f2e2dSJohn Marino                           char *buf,
9414cf7f2e2dSJohn Marino                           int *bufsiz,
9415cf7f2e2dSJohn Marino                           const void *s390_timer,
9416cf7f2e2dSJohn Marino                           int size)
9417cf7f2e2dSJohn Marino {
9418cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9419cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9420cf7f2e2dSJohn Marino                              note_name, NT_S390_TIMER, s390_timer, size);
9421cf7f2e2dSJohn Marino }
9422cf7f2e2dSJohn Marino 
9423cf7f2e2dSJohn Marino char *
elfcore_write_s390_todcmp(bfd * abfd,char * buf,int * bufsiz,const void * s390_todcmp,int size)9424cf7f2e2dSJohn Marino elfcore_write_s390_todcmp (bfd *abfd,
9425cf7f2e2dSJohn Marino                            char *buf,
9426cf7f2e2dSJohn Marino                            int *bufsiz,
9427cf7f2e2dSJohn Marino                            const void *s390_todcmp,
9428cf7f2e2dSJohn Marino                            int size)
9429cf7f2e2dSJohn Marino {
9430cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9431cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9432cf7f2e2dSJohn Marino                              note_name, NT_S390_TODCMP, s390_todcmp, size);
9433cf7f2e2dSJohn Marino }
9434cf7f2e2dSJohn Marino 
9435cf7f2e2dSJohn Marino char *
elfcore_write_s390_todpreg(bfd * abfd,char * buf,int * bufsiz,const void * s390_todpreg,int size)9436cf7f2e2dSJohn Marino elfcore_write_s390_todpreg (bfd *abfd,
9437cf7f2e2dSJohn Marino                             char *buf,
9438cf7f2e2dSJohn Marino                             int *bufsiz,
9439cf7f2e2dSJohn Marino                             const void *s390_todpreg,
9440cf7f2e2dSJohn Marino                             int size)
9441cf7f2e2dSJohn Marino {
9442cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9443cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9444cf7f2e2dSJohn Marino                              note_name, NT_S390_TODPREG, s390_todpreg, size);
9445cf7f2e2dSJohn Marino }
9446cf7f2e2dSJohn Marino 
9447cf7f2e2dSJohn Marino char *
elfcore_write_s390_ctrs(bfd * abfd,char * buf,int * bufsiz,const void * s390_ctrs,int size)9448cf7f2e2dSJohn Marino elfcore_write_s390_ctrs (bfd *abfd,
9449cf7f2e2dSJohn Marino                          char *buf,
9450cf7f2e2dSJohn Marino                          int *bufsiz,
9451cf7f2e2dSJohn Marino                          const void *s390_ctrs,
9452cf7f2e2dSJohn Marino                          int size)
9453cf7f2e2dSJohn Marino {
9454cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9455cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9456cf7f2e2dSJohn Marino                              note_name, NT_S390_CTRS, s390_ctrs, size);
9457cf7f2e2dSJohn Marino }
9458cf7f2e2dSJohn Marino 
9459cf7f2e2dSJohn Marino char *
elfcore_write_s390_prefix(bfd * abfd,char * buf,int * bufsiz,const void * s390_prefix,int size)9460cf7f2e2dSJohn Marino elfcore_write_s390_prefix (bfd *abfd,
9461cf7f2e2dSJohn Marino                            char *buf,
9462cf7f2e2dSJohn Marino                            int *bufsiz,
9463cf7f2e2dSJohn Marino                            const void *s390_prefix,
9464cf7f2e2dSJohn Marino                            int size)
9465cf7f2e2dSJohn Marino {
9466cf7f2e2dSJohn Marino   char *note_name = "LINUX";
9467cf7f2e2dSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9468cf7f2e2dSJohn Marino                              note_name, NT_S390_PREFIX, s390_prefix, size);
9469cf7f2e2dSJohn Marino }
9470cf7f2e2dSJohn Marino 
94715796c8dcSSimon Schubert char *
elfcore_write_s390_last_break(bfd * abfd,char * buf,int * bufsiz,const void * s390_last_break,int size)9472a45ae5f8SJohn Marino elfcore_write_s390_last_break (bfd *abfd,
9473a45ae5f8SJohn Marino 			       char *buf,
9474a45ae5f8SJohn Marino 			       int *bufsiz,
9475a45ae5f8SJohn Marino 			       const void *s390_last_break,
9476a45ae5f8SJohn Marino 			       int size)
9477a45ae5f8SJohn Marino {
9478a45ae5f8SJohn Marino   char *note_name = "LINUX";
9479a45ae5f8SJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9480a45ae5f8SJohn Marino                              note_name, NT_S390_LAST_BREAK,
9481a45ae5f8SJohn Marino 			     s390_last_break, size);
9482a45ae5f8SJohn Marino }
9483a45ae5f8SJohn Marino 
9484a45ae5f8SJohn Marino char *
elfcore_write_s390_system_call(bfd * abfd,char * buf,int * bufsiz,const void * s390_system_call,int size)9485a45ae5f8SJohn Marino elfcore_write_s390_system_call (bfd *abfd,
9486a45ae5f8SJohn Marino 				char *buf,
9487a45ae5f8SJohn Marino 				int *bufsiz,
9488a45ae5f8SJohn Marino 				const void *s390_system_call,
9489a45ae5f8SJohn Marino 				int size)
9490a45ae5f8SJohn Marino {
9491a45ae5f8SJohn Marino   char *note_name = "LINUX";
9492a45ae5f8SJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9493a45ae5f8SJohn Marino                              note_name, NT_S390_SYSTEM_CALL,
9494a45ae5f8SJohn Marino 			     s390_system_call, size);
9495a45ae5f8SJohn Marino }
9496a45ae5f8SJohn Marino 
9497a45ae5f8SJohn Marino char *
elfcore_write_s390_tdb(bfd * abfd,char * buf,int * bufsiz,const void * s390_tdb,int size)9498*ef5ccd6cSJohn Marino elfcore_write_s390_tdb (bfd *abfd,
9499*ef5ccd6cSJohn Marino 			char *buf,
9500*ef5ccd6cSJohn Marino 			int *bufsiz,
9501*ef5ccd6cSJohn Marino 			const void *s390_tdb,
9502*ef5ccd6cSJohn Marino 			int size)
9503*ef5ccd6cSJohn Marino {
9504*ef5ccd6cSJohn Marino   char *note_name = "LINUX";
9505*ef5ccd6cSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9506*ef5ccd6cSJohn Marino                              note_name, NT_S390_TDB, s390_tdb, size);
9507*ef5ccd6cSJohn Marino }
9508*ef5ccd6cSJohn Marino 
9509*ef5ccd6cSJohn Marino char *
elfcore_write_arm_vfp(bfd * abfd,char * buf,int * bufsiz,const void * arm_vfp,int size)9510a45ae5f8SJohn Marino elfcore_write_arm_vfp (bfd *abfd,
9511a45ae5f8SJohn Marino 		       char *buf,
9512a45ae5f8SJohn Marino 		       int *bufsiz,
9513a45ae5f8SJohn Marino 		       const void *arm_vfp,
9514a45ae5f8SJohn Marino 		       int size)
9515a45ae5f8SJohn Marino {
9516a45ae5f8SJohn Marino   char *note_name = "LINUX";
9517a45ae5f8SJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9518a45ae5f8SJohn Marino 			     note_name, NT_ARM_VFP, arm_vfp, size);
9519a45ae5f8SJohn Marino }
9520a45ae5f8SJohn Marino 
9521a45ae5f8SJohn Marino char *
elfcore_write_aarch_tls(bfd * abfd,char * buf,int * bufsiz,const void * aarch_tls,int size)9522*ef5ccd6cSJohn Marino elfcore_write_aarch_tls (bfd *abfd,
9523*ef5ccd6cSJohn Marino 		       char *buf,
9524*ef5ccd6cSJohn Marino 		       int *bufsiz,
9525*ef5ccd6cSJohn Marino 		       const void *aarch_tls,
9526*ef5ccd6cSJohn Marino 		       int size)
9527*ef5ccd6cSJohn Marino {
9528*ef5ccd6cSJohn Marino   char *note_name = "LINUX";
9529*ef5ccd6cSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9530*ef5ccd6cSJohn Marino 			     note_name, NT_ARM_TLS, aarch_tls, size);
9531*ef5ccd6cSJohn Marino }
9532*ef5ccd6cSJohn Marino 
9533*ef5ccd6cSJohn Marino char *
elfcore_write_aarch_hw_break(bfd * abfd,char * buf,int * bufsiz,const void * aarch_hw_break,int size)9534*ef5ccd6cSJohn Marino elfcore_write_aarch_hw_break (bfd *abfd,
9535*ef5ccd6cSJohn Marino 			    char *buf,
9536*ef5ccd6cSJohn Marino 			    int *bufsiz,
9537*ef5ccd6cSJohn Marino 			    const void *aarch_hw_break,
9538*ef5ccd6cSJohn Marino 			    int size)
9539*ef5ccd6cSJohn Marino {
9540*ef5ccd6cSJohn Marino   char *note_name = "LINUX";
9541*ef5ccd6cSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9542*ef5ccd6cSJohn Marino 			     note_name, NT_ARM_HW_BREAK, aarch_hw_break, size);
9543*ef5ccd6cSJohn Marino }
9544*ef5ccd6cSJohn Marino 
9545*ef5ccd6cSJohn Marino char *
elfcore_write_aarch_hw_watch(bfd * abfd,char * buf,int * bufsiz,const void * aarch_hw_watch,int size)9546*ef5ccd6cSJohn Marino elfcore_write_aarch_hw_watch (bfd *abfd,
9547*ef5ccd6cSJohn Marino 			    char *buf,
9548*ef5ccd6cSJohn Marino 			    int *bufsiz,
9549*ef5ccd6cSJohn Marino 			    const void *aarch_hw_watch,
9550*ef5ccd6cSJohn Marino 			    int size)
9551*ef5ccd6cSJohn Marino {
9552*ef5ccd6cSJohn Marino   char *note_name = "LINUX";
9553*ef5ccd6cSJohn Marino   return elfcore_write_note (abfd, buf, bufsiz,
9554*ef5ccd6cSJohn Marino 			     note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size);
9555*ef5ccd6cSJohn Marino }
9556*ef5ccd6cSJohn Marino 
9557*ef5ccd6cSJohn Marino char *
elfcore_write_register_note(bfd * abfd,char * buf,int * bufsiz,const char * section,const void * data,int size)95585796c8dcSSimon Schubert elfcore_write_register_note (bfd *abfd,
95595796c8dcSSimon Schubert 			     char *buf,
95605796c8dcSSimon Schubert 			     int *bufsiz,
95615796c8dcSSimon Schubert 			     const char *section,
95625796c8dcSSimon Schubert 			     const void *data,
95635796c8dcSSimon Schubert 			     int size)
95645796c8dcSSimon Schubert {
95655796c8dcSSimon Schubert   if (strcmp (section, ".reg2") == 0)
95665796c8dcSSimon Schubert     return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
95675796c8dcSSimon Schubert   if (strcmp (section, ".reg-xfp") == 0)
95685796c8dcSSimon Schubert     return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
9569cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-xstate") == 0)
9570cf7f2e2dSJohn Marino     return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size);
95715796c8dcSSimon Schubert   if (strcmp (section, ".reg-ppc-vmx") == 0)
95725796c8dcSSimon Schubert     return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
95735796c8dcSSimon Schubert   if (strcmp (section, ".reg-ppc-vsx") == 0)
95745796c8dcSSimon Schubert     return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
9575cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-s390-high-gprs") == 0)
9576cf7f2e2dSJohn Marino     return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size);
9577cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-s390-timer") == 0)
9578cf7f2e2dSJohn Marino     return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size);
9579cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-s390-todcmp") == 0)
9580cf7f2e2dSJohn Marino     return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size);
9581cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-s390-todpreg") == 0)
9582cf7f2e2dSJohn Marino     return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
9583cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-s390-ctrs") == 0)
9584cf7f2e2dSJohn Marino     return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
9585cf7f2e2dSJohn Marino   if (strcmp (section, ".reg-s390-prefix") == 0)
9586cf7f2e2dSJohn Marino     return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
9587a45ae5f8SJohn Marino   if (strcmp (section, ".reg-s390-last-break") == 0)
9588a45ae5f8SJohn Marino     return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
9589a45ae5f8SJohn Marino   if (strcmp (section, ".reg-s390-system-call") == 0)
9590a45ae5f8SJohn Marino     return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
9591*ef5ccd6cSJohn Marino   if (strcmp (section, ".reg-s390-tdb") == 0)
9592*ef5ccd6cSJohn Marino     return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
9593a45ae5f8SJohn Marino   if (strcmp (section, ".reg-arm-vfp") == 0)
9594a45ae5f8SJohn Marino     return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
9595*ef5ccd6cSJohn Marino   if (strcmp (section, ".reg-aarch-tls") == 0)
9596*ef5ccd6cSJohn Marino     return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size);
9597*ef5ccd6cSJohn Marino   if (strcmp (section, ".reg-aarch-hw-break") == 0)
9598*ef5ccd6cSJohn Marino     return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size);
9599*ef5ccd6cSJohn Marino   if (strcmp (section, ".reg-aarch-hw-watch") == 0)
9600*ef5ccd6cSJohn Marino     return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size);
96015796c8dcSSimon Schubert   return NULL;
96025796c8dcSSimon Schubert }
96035796c8dcSSimon Schubert 
96045796c8dcSSimon Schubert static bfd_boolean
elf_parse_notes(bfd * abfd,char * buf,size_t size,file_ptr offset)96055796c8dcSSimon Schubert elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
96065796c8dcSSimon Schubert {
96075796c8dcSSimon Schubert   char *p;
96085796c8dcSSimon Schubert 
96095796c8dcSSimon Schubert   p = buf;
96105796c8dcSSimon Schubert   while (p < buf + size)
96115796c8dcSSimon Schubert     {
96125796c8dcSSimon Schubert       /* FIXME: bad alignment assumption.  */
96135796c8dcSSimon Schubert       Elf_External_Note *xnp = (Elf_External_Note *) p;
96145796c8dcSSimon Schubert       Elf_Internal_Note in;
96155796c8dcSSimon Schubert 
96165796c8dcSSimon Schubert       if (offsetof (Elf_External_Note, name) > buf - p + size)
96175796c8dcSSimon Schubert 	return FALSE;
96185796c8dcSSimon Schubert 
96195796c8dcSSimon Schubert       in.type = H_GET_32 (abfd, xnp->type);
96205796c8dcSSimon Schubert 
96215796c8dcSSimon Schubert       in.namesz = H_GET_32 (abfd, xnp->namesz);
96225796c8dcSSimon Schubert       in.namedata = xnp->name;
96235796c8dcSSimon Schubert       if (in.namesz > buf - in.namedata + size)
96245796c8dcSSimon Schubert 	return FALSE;
96255796c8dcSSimon Schubert 
96265796c8dcSSimon Schubert       in.descsz = H_GET_32 (abfd, xnp->descsz);
96275796c8dcSSimon Schubert       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);
96285796c8dcSSimon Schubert       in.descpos = offset + (in.descdata - buf);
96295796c8dcSSimon Schubert       if (in.descsz != 0
96305796c8dcSSimon Schubert 	  && (in.descdata >= buf + size
96315796c8dcSSimon Schubert 	      || in.descsz > buf - in.descdata + size))
96325796c8dcSSimon Schubert 	return FALSE;
96335796c8dcSSimon Schubert 
96345796c8dcSSimon Schubert       switch (bfd_get_format (abfd))
96355796c8dcSSimon Schubert         {
96365796c8dcSSimon Schubert 	default:
96375796c8dcSSimon Schubert 	  return TRUE;
96385796c8dcSSimon Schubert 
96395796c8dcSSimon Schubert 	case bfd_core:
96405796c8dcSSimon Schubert 	  if (CONST_STRNEQ (in.namedata, "NetBSD-CORE"))
96415796c8dcSSimon Schubert 	    {
96425796c8dcSSimon Schubert 	      if (! elfcore_grok_netbsd_note (abfd, &in))
96435796c8dcSSimon Schubert 		return FALSE;
96445796c8dcSSimon Schubert 	    }
96455796c8dcSSimon Schubert 	  else if (CONST_STRNEQ (in.namedata, "OpenBSD"))
96465796c8dcSSimon Schubert 	    {
96475796c8dcSSimon Schubert 	      if (! elfcore_grok_openbsd_note (abfd, &in))
96485796c8dcSSimon Schubert 		return FALSE;
96495796c8dcSSimon Schubert 	    }
96505796c8dcSSimon Schubert 	  else if (CONST_STRNEQ (in.namedata, "QNX"))
96515796c8dcSSimon Schubert 	    {
96525796c8dcSSimon Schubert 	      if (! elfcore_grok_nto_note (abfd, &in))
96535796c8dcSSimon Schubert 		return FALSE;
96545796c8dcSSimon Schubert 	    }
96555796c8dcSSimon Schubert 	  else if (CONST_STRNEQ (in.namedata, "SPU/"))
96565796c8dcSSimon Schubert 	    {
96575796c8dcSSimon Schubert 	      if (! elfcore_grok_spu_note (abfd, &in))
96585796c8dcSSimon Schubert 		return FALSE;
96595796c8dcSSimon Schubert 	    }
96605796c8dcSSimon Schubert 	  else
96615796c8dcSSimon Schubert 	    {
96625796c8dcSSimon Schubert 	      if (! elfcore_grok_note (abfd, &in))
96635796c8dcSSimon Schubert 		return FALSE;
96645796c8dcSSimon Schubert 	    }
96655796c8dcSSimon Schubert 	  break;
96665796c8dcSSimon Schubert 
96675796c8dcSSimon Schubert 	case bfd_object:
96685796c8dcSSimon Schubert 	  if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
96695796c8dcSSimon Schubert 	    {
96705796c8dcSSimon Schubert 	      if (! elfobj_grok_gnu_note (abfd, &in))
96715796c8dcSSimon Schubert 		return FALSE;
96725796c8dcSSimon Schubert 	    }
9673a45ae5f8SJohn Marino 	  else if (in.namesz == sizeof "stapsdt"
9674a45ae5f8SJohn Marino 		   && strcmp (in.namedata, "stapsdt") == 0)
9675a45ae5f8SJohn Marino 	    {
9676a45ae5f8SJohn Marino 	      if (! elfobj_grok_stapsdt_note (abfd, &in))
9677a45ae5f8SJohn Marino 		return FALSE;
9678a45ae5f8SJohn Marino 	    }
96795796c8dcSSimon Schubert 	  break;
96805796c8dcSSimon Schubert 	}
96815796c8dcSSimon Schubert 
96825796c8dcSSimon Schubert       p = in.descdata + BFD_ALIGN (in.descsz, 4);
96835796c8dcSSimon Schubert     }
96845796c8dcSSimon Schubert 
96855796c8dcSSimon Schubert   return TRUE;
96865796c8dcSSimon Schubert }
96875796c8dcSSimon Schubert 
96885796c8dcSSimon Schubert static bfd_boolean
elf_read_notes(bfd * abfd,file_ptr offset,bfd_size_type size)96895796c8dcSSimon Schubert elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size)
96905796c8dcSSimon Schubert {
96915796c8dcSSimon Schubert   char *buf;
96925796c8dcSSimon Schubert 
96935796c8dcSSimon Schubert   if (size <= 0)
96945796c8dcSSimon Schubert     return TRUE;
96955796c8dcSSimon Schubert 
96965796c8dcSSimon Schubert   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
96975796c8dcSSimon Schubert     return FALSE;
96985796c8dcSSimon Schubert 
96995796c8dcSSimon Schubert   buf = (char *) bfd_malloc (size);
97005796c8dcSSimon Schubert   if (buf == NULL)
97015796c8dcSSimon Schubert     return FALSE;
97025796c8dcSSimon Schubert 
97035796c8dcSSimon Schubert   if (bfd_bread (buf, size, abfd) != size
97045796c8dcSSimon Schubert       || !elf_parse_notes (abfd, buf, size, offset))
97055796c8dcSSimon Schubert     {
97065796c8dcSSimon Schubert       free (buf);
97075796c8dcSSimon Schubert       return FALSE;
97085796c8dcSSimon Schubert     }
97095796c8dcSSimon Schubert 
97105796c8dcSSimon Schubert   free (buf);
97115796c8dcSSimon Schubert   return TRUE;
97125796c8dcSSimon Schubert }
97135796c8dcSSimon Schubert 
97145796c8dcSSimon Schubert /* Providing external access to the ELF program header table.  */
97155796c8dcSSimon Schubert 
97165796c8dcSSimon Schubert /* Return an upper bound on the number of bytes required to store a
97175796c8dcSSimon Schubert    copy of ABFD's program header table entries.  Return -1 if an error
97185796c8dcSSimon Schubert    occurs; bfd_get_error will return an appropriate code.  */
97195796c8dcSSimon Schubert 
97205796c8dcSSimon Schubert long
bfd_get_elf_phdr_upper_bound(bfd * abfd)97215796c8dcSSimon Schubert bfd_get_elf_phdr_upper_bound (bfd *abfd)
97225796c8dcSSimon Schubert {
97235796c8dcSSimon Schubert   if (abfd->xvec->flavour != bfd_target_elf_flavour)
97245796c8dcSSimon Schubert     {
97255796c8dcSSimon Schubert       bfd_set_error (bfd_error_wrong_format);
97265796c8dcSSimon Schubert       return -1;
97275796c8dcSSimon Schubert     }
97285796c8dcSSimon Schubert 
97295796c8dcSSimon Schubert   return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
97305796c8dcSSimon Schubert }
97315796c8dcSSimon Schubert 
97325796c8dcSSimon Schubert /* Copy ABFD's program header table entries to *PHDRS.  The entries
97335796c8dcSSimon Schubert    will be stored as an array of Elf_Internal_Phdr structures, as
97345796c8dcSSimon Schubert    defined in include/elf/internal.h.  To find out how large the
97355796c8dcSSimon Schubert    buffer needs to be, call bfd_get_elf_phdr_upper_bound.
97365796c8dcSSimon Schubert 
97375796c8dcSSimon Schubert    Return the number of program header table entries read, or -1 if an
97385796c8dcSSimon Schubert    error occurs; bfd_get_error will return an appropriate code.  */
97395796c8dcSSimon Schubert 
97405796c8dcSSimon Schubert int
bfd_get_elf_phdrs(bfd * abfd,void * phdrs)97415796c8dcSSimon Schubert bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
97425796c8dcSSimon Schubert {
97435796c8dcSSimon Schubert   int num_phdrs;
97445796c8dcSSimon Schubert 
97455796c8dcSSimon Schubert   if (abfd->xvec->flavour != bfd_target_elf_flavour)
97465796c8dcSSimon Schubert     {
97475796c8dcSSimon Schubert       bfd_set_error (bfd_error_wrong_format);
97485796c8dcSSimon Schubert       return -1;
97495796c8dcSSimon Schubert     }
97505796c8dcSSimon Schubert 
97515796c8dcSSimon Schubert   num_phdrs = elf_elfheader (abfd)->e_phnum;
97525796c8dcSSimon Schubert   memcpy (phdrs, elf_tdata (abfd)->phdr,
97535796c8dcSSimon Schubert 	  num_phdrs * sizeof (Elf_Internal_Phdr));
97545796c8dcSSimon Schubert 
97555796c8dcSSimon Schubert   return num_phdrs;
97565796c8dcSSimon Schubert }
97575796c8dcSSimon Schubert 
97585796c8dcSSimon Schubert enum elf_reloc_type_class
_bfd_elf_reloc_type_class(const Elf_Internal_Rela * rela ATTRIBUTE_UNUSED)97595796c8dcSSimon Schubert _bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
97605796c8dcSSimon Schubert {
97615796c8dcSSimon Schubert   return reloc_class_normal;
97625796c8dcSSimon Schubert }
97635796c8dcSSimon Schubert 
97645796c8dcSSimon Schubert /* For RELA architectures, return the relocation value for a
97655796c8dcSSimon Schubert    relocation against a local symbol.  */
97665796c8dcSSimon Schubert 
97675796c8dcSSimon Schubert bfd_vma
_bfd_elf_rela_local_sym(bfd * abfd,Elf_Internal_Sym * sym,asection ** psec,Elf_Internal_Rela * rel)97685796c8dcSSimon Schubert _bfd_elf_rela_local_sym (bfd *abfd,
97695796c8dcSSimon Schubert 			 Elf_Internal_Sym *sym,
97705796c8dcSSimon Schubert 			 asection **psec,
97715796c8dcSSimon Schubert 			 Elf_Internal_Rela *rel)
97725796c8dcSSimon Schubert {
97735796c8dcSSimon Schubert   asection *sec = *psec;
97745796c8dcSSimon Schubert   bfd_vma relocation;
97755796c8dcSSimon Schubert 
97765796c8dcSSimon Schubert   relocation = (sec->output_section->vma
97775796c8dcSSimon Schubert 		+ sec->output_offset
97785796c8dcSSimon Schubert 		+ sym->st_value);
97795796c8dcSSimon Schubert   if ((sec->flags & SEC_MERGE)
97805796c8dcSSimon Schubert       && ELF_ST_TYPE (sym->st_info) == STT_SECTION
9781*ef5ccd6cSJohn Marino       && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
97825796c8dcSSimon Schubert     {
97835796c8dcSSimon Schubert       rel->r_addend =
97845796c8dcSSimon Schubert 	_bfd_merged_section_offset (abfd, psec,
97855796c8dcSSimon Schubert 				    elf_section_data (sec)->sec_info,
97865796c8dcSSimon Schubert 				    sym->st_value + rel->r_addend);
97875796c8dcSSimon Schubert       if (sec != *psec)
97885796c8dcSSimon Schubert 	{
97895796c8dcSSimon Schubert 	  /* If we have changed the section, and our original section is
97905796c8dcSSimon Schubert 	     marked with SEC_EXCLUDE, it means that the original
97915796c8dcSSimon Schubert 	     SEC_MERGE section has been completely subsumed in some
97925796c8dcSSimon Schubert 	     other SEC_MERGE section.  In this case, we need to leave
97935796c8dcSSimon Schubert 	     some info around for --emit-relocs.  */
97945796c8dcSSimon Schubert 	  if ((sec->flags & SEC_EXCLUDE) != 0)
97955796c8dcSSimon Schubert 	    sec->kept_section = *psec;
97965796c8dcSSimon Schubert 	  sec = *psec;
97975796c8dcSSimon Schubert 	}
97985796c8dcSSimon Schubert       rel->r_addend -= relocation;
97995796c8dcSSimon Schubert       rel->r_addend += sec->output_section->vma + sec->output_offset;
98005796c8dcSSimon Schubert     }
98015796c8dcSSimon Schubert   return relocation;
98025796c8dcSSimon Schubert }
98035796c8dcSSimon Schubert 
98045796c8dcSSimon Schubert bfd_vma
_bfd_elf_rel_local_sym(bfd * abfd,Elf_Internal_Sym * sym,asection ** psec,bfd_vma addend)98055796c8dcSSimon Schubert _bfd_elf_rel_local_sym (bfd *abfd,
98065796c8dcSSimon Schubert 			Elf_Internal_Sym *sym,
98075796c8dcSSimon Schubert 			asection **psec,
98085796c8dcSSimon Schubert 			bfd_vma addend)
98095796c8dcSSimon Schubert {
98105796c8dcSSimon Schubert   asection *sec = *psec;
98115796c8dcSSimon Schubert 
9812*ef5ccd6cSJohn Marino   if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
98135796c8dcSSimon Schubert     return sym->st_value + addend;
98145796c8dcSSimon Schubert 
98155796c8dcSSimon Schubert   return _bfd_merged_section_offset (abfd, psec,
98165796c8dcSSimon Schubert 				     elf_section_data (sec)->sec_info,
98175796c8dcSSimon Schubert 				     sym->st_value + addend);
98185796c8dcSSimon Schubert }
98195796c8dcSSimon Schubert 
98205796c8dcSSimon Schubert bfd_vma
_bfd_elf_section_offset(bfd * abfd,struct bfd_link_info * info,asection * sec,bfd_vma offset)98215796c8dcSSimon Schubert _bfd_elf_section_offset (bfd *abfd,
98225796c8dcSSimon Schubert 			 struct bfd_link_info *info,
98235796c8dcSSimon Schubert 			 asection *sec,
98245796c8dcSSimon Schubert 			 bfd_vma offset)
98255796c8dcSSimon Schubert {
98265796c8dcSSimon Schubert   switch (sec->sec_info_type)
98275796c8dcSSimon Schubert     {
9828*ef5ccd6cSJohn Marino     case SEC_INFO_TYPE_STABS:
98295796c8dcSSimon Schubert       return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
98305796c8dcSSimon Schubert 				       offset);
9831*ef5ccd6cSJohn Marino     case SEC_INFO_TYPE_EH_FRAME:
98325796c8dcSSimon Schubert       return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
98335796c8dcSSimon Schubert     default:
9834a45ae5f8SJohn Marino       if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
9835a45ae5f8SJohn Marino 	{
9836a45ae5f8SJohn Marino 	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
9837a45ae5f8SJohn Marino 	  bfd_size_type address_size = bed->s->arch_size / 8;
9838a45ae5f8SJohn Marino 	  offset = sec->size - offset - address_size;
9839a45ae5f8SJohn Marino 	}
98405796c8dcSSimon Schubert       return offset;
98415796c8dcSSimon Schubert     }
98425796c8dcSSimon Schubert }
98435796c8dcSSimon Schubert 
98445796c8dcSSimon Schubert /* Create a new BFD as if by bfd_openr.  Rather than opening a file,
98455796c8dcSSimon Schubert    reconstruct an ELF file by reading the segments out of remote memory
98465796c8dcSSimon Schubert    based on the ELF file header at EHDR_VMA and the ELF program headers it
98475796c8dcSSimon Schubert    points to.  If not null, *LOADBASEP is filled in with the difference
98485796c8dcSSimon Schubert    between the VMAs from which the segments were read, and the VMAs the
98495796c8dcSSimon Schubert    file headers (and hence BFD's idea of each section's VMA) put them at.
98505796c8dcSSimon Schubert 
98515796c8dcSSimon Schubert    The function TARGET_READ_MEMORY is called to copy LEN bytes from the
98525796c8dcSSimon Schubert    remote memory at target address VMA into the local buffer at MYADDR; it
98535796c8dcSSimon Schubert    should return zero on success or an `errno' code on failure.  TEMPL must
98545796c8dcSSimon Schubert    be a BFD for an ELF target with the word size and byte order found in
98555796c8dcSSimon Schubert    the remote memory.  */
98565796c8dcSSimon Schubert 
98575796c8dcSSimon Schubert bfd *
bfd_elf_bfd_from_remote_memory(bfd * templ,bfd_vma ehdr_vma,bfd_vma * loadbasep,int (* target_read_memory)(bfd_vma,bfd_byte *,bfd_size_type))98585796c8dcSSimon Schubert bfd_elf_bfd_from_remote_memory
98595796c8dcSSimon Schubert   (bfd *templ,
98605796c8dcSSimon Schubert    bfd_vma ehdr_vma,
98615796c8dcSSimon Schubert    bfd_vma *loadbasep,
9862*ef5ccd6cSJohn Marino    int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
98635796c8dcSSimon Schubert {
98645796c8dcSSimon Schubert   return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
98655796c8dcSSimon Schubert     (templ, ehdr_vma, loadbasep, target_read_memory);
98665796c8dcSSimon Schubert }
98675796c8dcSSimon Schubert 
98685796c8dcSSimon Schubert long
_bfd_elf_get_synthetic_symtab(bfd * abfd,long symcount ATTRIBUTE_UNUSED,asymbol ** syms ATTRIBUTE_UNUSED,long dynsymcount,asymbol ** dynsyms,asymbol ** ret)98695796c8dcSSimon Schubert _bfd_elf_get_synthetic_symtab (bfd *abfd,
98705796c8dcSSimon Schubert 			       long symcount ATTRIBUTE_UNUSED,
98715796c8dcSSimon Schubert 			       asymbol **syms ATTRIBUTE_UNUSED,
98725796c8dcSSimon Schubert 			       long dynsymcount,
98735796c8dcSSimon Schubert 			       asymbol **dynsyms,
98745796c8dcSSimon Schubert 			       asymbol **ret)
98755796c8dcSSimon Schubert {
98765796c8dcSSimon Schubert   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
98775796c8dcSSimon Schubert   asection *relplt;
98785796c8dcSSimon Schubert   asymbol *s;
98795796c8dcSSimon Schubert   const char *relplt_name;
98805796c8dcSSimon Schubert   bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
98815796c8dcSSimon Schubert   arelent *p;
98825796c8dcSSimon Schubert   long count, i, n;
98835796c8dcSSimon Schubert   size_t size;
98845796c8dcSSimon Schubert   Elf_Internal_Shdr *hdr;
98855796c8dcSSimon Schubert   char *names;
98865796c8dcSSimon Schubert   asection *plt;
98875796c8dcSSimon Schubert 
98885796c8dcSSimon Schubert   *ret = NULL;
98895796c8dcSSimon Schubert 
98905796c8dcSSimon Schubert   if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
98915796c8dcSSimon Schubert     return 0;
98925796c8dcSSimon Schubert 
98935796c8dcSSimon Schubert   if (dynsymcount <= 0)
98945796c8dcSSimon Schubert     return 0;
98955796c8dcSSimon Schubert 
98965796c8dcSSimon Schubert   if (!bed->plt_sym_val)
98975796c8dcSSimon Schubert     return 0;
98985796c8dcSSimon Schubert 
98995796c8dcSSimon Schubert   relplt_name = bed->relplt_name;
99005796c8dcSSimon Schubert   if (relplt_name == NULL)
99015796c8dcSSimon Schubert     relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
99025796c8dcSSimon Schubert   relplt = bfd_get_section_by_name (abfd, relplt_name);
99035796c8dcSSimon Schubert   if (relplt == NULL)
99045796c8dcSSimon Schubert     return 0;
99055796c8dcSSimon Schubert 
99065796c8dcSSimon Schubert   hdr = &elf_section_data (relplt)->this_hdr;
99075796c8dcSSimon Schubert   if (hdr->sh_link != elf_dynsymtab (abfd)
99085796c8dcSSimon Schubert       || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
99095796c8dcSSimon Schubert     return 0;
99105796c8dcSSimon Schubert 
99115796c8dcSSimon Schubert   plt = bfd_get_section_by_name (abfd, ".plt");
99125796c8dcSSimon Schubert   if (plt == NULL)
99135796c8dcSSimon Schubert     return 0;
99145796c8dcSSimon Schubert 
99155796c8dcSSimon Schubert   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
99165796c8dcSSimon Schubert   if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
99175796c8dcSSimon Schubert     return -1;
99185796c8dcSSimon Schubert 
99195796c8dcSSimon Schubert   count = relplt->size / hdr->sh_entsize;
99205796c8dcSSimon Schubert   size = count * sizeof (asymbol);
99215796c8dcSSimon Schubert   p = relplt->relocation;
99225796c8dcSSimon Schubert   for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
99235796c8dcSSimon Schubert     {
99245796c8dcSSimon Schubert       size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
99255796c8dcSSimon Schubert       if (p->addend != 0)
99265796c8dcSSimon Schubert 	{
99275796c8dcSSimon Schubert #ifdef BFD64
99285796c8dcSSimon Schubert 	  size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
99295796c8dcSSimon Schubert #else
99305796c8dcSSimon Schubert 	  size += sizeof ("+0x") - 1 + 8;
99315796c8dcSSimon Schubert #endif
99325796c8dcSSimon Schubert 	}
99335796c8dcSSimon Schubert     }
99345796c8dcSSimon Schubert 
99355796c8dcSSimon Schubert   s = *ret = (asymbol *) bfd_malloc (size);
99365796c8dcSSimon Schubert   if (s == NULL)
99375796c8dcSSimon Schubert     return -1;
99385796c8dcSSimon Schubert 
99395796c8dcSSimon Schubert   names = (char *) (s + count);
99405796c8dcSSimon Schubert   p = relplt->relocation;
99415796c8dcSSimon Schubert   n = 0;
99425796c8dcSSimon Schubert   for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
99435796c8dcSSimon Schubert     {
99445796c8dcSSimon Schubert       size_t len;
99455796c8dcSSimon Schubert       bfd_vma addr;
99465796c8dcSSimon Schubert 
99475796c8dcSSimon Schubert       addr = bed->plt_sym_val (i, plt, p);
99485796c8dcSSimon Schubert       if (addr == (bfd_vma) -1)
99495796c8dcSSimon Schubert 	continue;
99505796c8dcSSimon Schubert 
99515796c8dcSSimon Schubert       *s = **p->sym_ptr_ptr;
99525796c8dcSSimon Schubert       /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
99535796c8dcSSimon Schubert 	 we are defining a symbol, ensure one of them is set.  */
99545796c8dcSSimon Schubert       if ((s->flags & BSF_LOCAL) == 0)
99555796c8dcSSimon Schubert 	s->flags |= BSF_GLOBAL;
99565796c8dcSSimon Schubert       s->flags |= BSF_SYNTHETIC;
99575796c8dcSSimon Schubert       s->section = plt;
99585796c8dcSSimon Schubert       s->value = addr - plt->vma;
99595796c8dcSSimon Schubert       s->name = names;
99605796c8dcSSimon Schubert       s->udata.p = NULL;
99615796c8dcSSimon Schubert       len = strlen ((*p->sym_ptr_ptr)->name);
99625796c8dcSSimon Schubert       memcpy (names, (*p->sym_ptr_ptr)->name, len);
99635796c8dcSSimon Schubert       names += len;
99645796c8dcSSimon Schubert       if (p->addend != 0)
99655796c8dcSSimon Schubert 	{
99665796c8dcSSimon Schubert 	  char buf[30], *a;
9967cf7f2e2dSJohn Marino 
99685796c8dcSSimon Schubert 	  memcpy (names, "+0x", sizeof ("+0x") - 1);
99695796c8dcSSimon Schubert 	  names += sizeof ("+0x") - 1;
99705796c8dcSSimon Schubert 	  bfd_sprintf_vma (abfd, buf, p->addend);
99715796c8dcSSimon Schubert 	  for (a = buf; *a == '0'; ++a)
99725796c8dcSSimon Schubert 	    ;
99735796c8dcSSimon Schubert 	  len = strlen (a);
99745796c8dcSSimon Schubert 	  memcpy (names, a, len);
99755796c8dcSSimon Schubert 	  names += len;
99765796c8dcSSimon Schubert 	}
99775796c8dcSSimon Schubert       memcpy (names, "@plt", sizeof ("@plt"));
99785796c8dcSSimon Schubert       names += sizeof ("@plt");
99795796c8dcSSimon Schubert       ++s, ++n;
99805796c8dcSSimon Schubert     }
99815796c8dcSSimon Schubert 
99825796c8dcSSimon Schubert   return n;
99835796c8dcSSimon Schubert }
99845796c8dcSSimon Schubert 
99855796c8dcSSimon Schubert /* It is only used by x86-64 so far.  */
99865796c8dcSSimon Schubert asection _bfd_elf_large_com_section
99875796c8dcSSimon Schubert   = BFD_FAKE_SECTION (_bfd_elf_large_com_section,
99885796c8dcSSimon Schubert 		      SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
99895796c8dcSSimon Schubert 
99905796c8dcSSimon Schubert void
_bfd_elf_set_osabi(bfd * abfd,struct bfd_link_info * link_info ATTRIBUTE_UNUSED)99915796c8dcSSimon Schubert _bfd_elf_set_osabi (bfd * abfd,
99925796c8dcSSimon Schubert 		    struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
99935796c8dcSSimon Schubert {
99945796c8dcSSimon Schubert   Elf_Internal_Ehdr * i_ehdrp;	/* ELF file header, internal form.  */
99955796c8dcSSimon Schubert 
99965796c8dcSSimon Schubert   i_ehdrp = elf_elfheader (abfd);
99975796c8dcSSimon Schubert 
99985796c8dcSSimon Schubert   i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
99995796c8dcSSimon Schubert 
100005796c8dcSSimon Schubert   /* To make things simpler for the loader on Linux systems we set the
10001a45ae5f8SJohn Marino      osabi field to ELFOSABI_GNU if the binary contains symbols of
10002a45ae5f8SJohn Marino      the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding.  */
100035796c8dcSSimon Schubert   if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
10004a45ae5f8SJohn Marino       && elf_tdata (abfd)->has_gnu_symbols)
10005a45ae5f8SJohn Marino     i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
100065796c8dcSSimon Schubert }
100075796c8dcSSimon Schubert 
100085796c8dcSSimon Schubert 
100095796c8dcSSimon Schubert /* Return TRUE for ELF symbol types that represent functions.
100105796c8dcSSimon Schubert    This is the default version of this function, which is sufficient for
100115796c8dcSSimon Schubert    most targets.  It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC.  */
100125796c8dcSSimon Schubert 
100135796c8dcSSimon Schubert bfd_boolean
_bfd_elf_is_function_type(unsigned int type)100145796c8dcSSimon Schubert _bfd_elf_is_function_type (unsigned int type)
100155796c8dcSSimon Schubert {
100165796c8dcSSimon Schubert   return (type == STT_FUNC
100175796c8dcSSimon Schubert 	  || type == STT_GNU_IFUNC);
100185796c8dcSSimon Schubert }
10019*ef5ccd6cSJohn Marino 
10020*ef5ccd6cSJohn Marino /* If the ELF symbol SYM might be a function in SEC, return the
10021*ef5ccd6cSJohn Marino    function size and set *CODE_OFF to the function's entry point,
10022*ef5ccd6cSJohn Marino    otherwise return zero.  */
10023*ef5ccd6cSJohn Marino 
10024*ef5ccd6cSJohn Marino bfd_size_type
_bfd_elf_maybe_function_sym(const asymbol * sym,asection * sec,bfd_vma * code_off)10025*ef5ccd6cSJohn Marino _bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
10026*ef5ccd6cSJohn Marino 			     bfd_vma *code_off)
10027*ef5ccd6cSJohn Marino {
10028*ef5ccd6cSJohn Marino   bfd_size_type size;
10029*ef5ccd6cSJohn Marino 
10030*ef5ccd6cSJohn Marino   if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
10031*ef5ccd6cSJohn Marino 		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
10032*ef5ccd6cSJohn Marino       || sym->section != sec)
10033*ef5ccd6cSJohn Marino     return 0;
10034*ef5ccd6cSJohn Marino 
10035*ef5ccd6cSJohn Marino   *code_off = sym->value;
10036*ef5ccd6cSJohn Marino   size = 0;
10037*ef5ccd6cSJohn Marino   if (!(sym->flags & BSF_SYNTHETIC))
10038*ef5ccd6cSJohn Marino     size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
10039*ef5ccd6cSJohn Marino   if (size == 0)
10040*ef5ccd6cSJohn Marino     size = 1;
10041*ef5ccd6cSJohn Marino   return size;
10042*ef5ccd6cSJohn Marino }
10043