Radix cross Linux Toolchains

Toolchains for all supported by Radix cross Linux devices

80 Commits   2 Branches   13 Tags
     9         kx /* ELF executable support for BFD.
     9         kx 
     9         kx    Copyright (C) 1993-2023 Free Software Foundation, Inc.
     9         kx 
     9         kx    This file is part of BFD, the Binary File Descriptor library.
     9         kx 
     9         kx    This program is free software; you can redistribute it and/or modify
     9         kx    it under the terms of the GNU General Public License as published by
     9         kx    the Free Software Foundation; either version 3 of the License, or
     9         kx    (at your option) any later version.
     9         kx 
     9         kx    This program is distributed in the hope that it will be useful,
     9         kx    but WITHOUT ANY WARRANTY; without even the implied warranty of
     9         kx    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     9         kx    GNU General Public License for more details.
     9         kx 
     9         kx    You should have received a copy of the GNU General Public License
     9         kx    along with this program; if not, write to the Free Software
     9         kx    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     9         kx    MA 02110-1301, USA.  */
     9         kx 
     9         kx 
     9         kx /*
     9         kx SECTION
     9         kx 	ELF backends
     9         kx 
     9         kx 	BFD support for ELF formats is being worked on.
     9         kx 	Currently, the best supported back ends are for sparc and i386
     9         kx 	(running svr4 or Solaris 2).
     9         kx 
     9         kx 	Documentation of the internals of the support code still needs
     9         kx 	to be written.  The code is changing quickly enough that we
     9         kx 	haven't bothered yet.  */
     9         kx 
     9         kx /* For sparc64-cross-sparc32.  */
     9         kx #define _SYSCALL32
     9         kx #include "sysdep.h"
     9         kx #include <limits.h>
     9         kx #include "bfd.h"
     9         kx #include "bfdlink.h"
     9         kx #include "libbfd.h"
     9         kx #define ARCH_SIZE 0
     9         kx #include "elf-bfd.h"
     9         kx #include "libiberty.h"
     9         kx #include "safe-ctype.h"
     9         kx #include "elf-linux-core.h"
     9         kx 
     9         kx #ifdef CORE_HEADER
     9         kx #include CORE_HEADER
     9         kx #endif
     9         kx 
     9         kx static int elf_sort_sections (const void *, const void *);
     9         kx static bool assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
     9         kx static bool swap_out_syms (bfd *, struct elf_strtab_hash **, int,
     9         kx 			   struct bfd_link_info *);
     9         kx static bool elf_parse_notes (bfd *abfd, char *buf, size_t size,
     9         kx 			     file_ptr offset, size_t align);
     9         kx 
     9         kx /* Swap version information in and out.  The version information is
     9         kx    currently size independent.  If that ever changes, this code will
     9         kx    need to move into elfcode.h.  */
     9         kx 
     9         kx /* Swap in a Verdef structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_verdef_in (bfd *abfd,
     9         kx 			 const Elf_External_Verdef *src,
     9         kx 			 Elf_Internal_Verdef *dst)
     9         kx {
     9         kx   dst->vd_version = H_GET_16 (abfd, src->vd_version);
     9         kx   dst->vd_flags   = H_GET_16 (abfd, src->vd_flags);
     9         kx   dst->vd_ndx     = H_GET_16 (abfd, src->vd_ndx);
     9         kx   dst->vd_cnt     = H_GET_16 (abfd, src->vd_cnt);
     9         kx   dst->vd_hash    = H_GET_32 (abfd, src->vd_hash);
     9         kx   dst->vd_aux     = H_GET_32 (abfd, src->vd_aux);
     9         kx   dst->vd_next    = H_GET_32 (abfd, src->vd_next);
     9         kx }
     9         kx 
     9         kx /* Swap out a Verdef structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_verdef_out (bfd *abfd,
     9         kx 			  const Elf_Internal_Verdef *src,
     9         kx 			  Elf_External_Verdef *dst)
     9         kx {
     9         kx   H_PUT_16 (abfd, src->vd_version, dst->vd_version);
     9         kx   H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
     9         kx   H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
     9         kx   H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
     9         kx   H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
     9         kx   H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
     9         kx   H_PUT_32 (abfd, src->vd_next, dst->vd_next);
     9         kx }
     9         kx 
     9         kx /* Swap in a Verdaux structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_verdaux_in (bfd *abfd,
     9         kx 			  const Elf_External_Verdaux *src,
     9         kx 			  Elf_Internal_Verdaux *dst)
     9         kx {
     9         kx   dst->vda_name = H_GET_32 (abfd, src->vda_name);
     9         kx   dst->vda_next = H_GET_32 (abfd, src->vda_next);
     9         kx }
     9         kx 
     9         kx /* Swap out a Verdaux structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_verdaux_out (bfd *abfd,
     9         kx 			   const Elf_Internal_Verdaux *src,
     9         kx 			   Elf_External_Verdaux *dst)
     9         kx {
     9         kx   H_PUT_32 (abfd, src->vda_name, dst->vda_name);
     9         kx   H_PUT_32 (abfd, src->vda_next, dst->vda_next);
     9         kx }
     9         kx 
     9         kx /* Swap in a Verneed structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_verneed_in (bfd *abfd,
     9         kx 			  const Elf_External_Verneed *src,
     9         kx 			  Elf_Internal_Verneed *dst)
     9         kx {
     9         kx   dst->vn_version = H_GET_16 (abfd, src->vn_version);
     9         kx   dst->vn_cnt     = H_GET_16 (abfd, src->vn_cnt);
     9         kx   dst->vn_file    = H_GET_32 (abfd, src->vn_file);
     9         kx   dst->vn_aux     = H_GET_32 (abfd, src->vn_aux);
     9         kx   dst->vn_next    = H_GET_32 (abfd, src->vn_next);
     9         kx }
     9         kx 
     9         kx /* Swap out a Verneed structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_verneed_out (bfd *abfd,
     9         kx 			   const Elf_Internal_Verneed *src,
     9         kx 			   Elf_External_Verneed *dst)
     9         kx {
     9         kx   H_PUT_16 (abfd, src->vn_version, dst->vn_version);
     9         kx   H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
     9         kx   H_PUT_32 (abfd, src->vn_file, dst->vn_file);
     9         kx   H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
     9         kx   H_PUT_32 (abfd, src->vn_next, dst->vn_next);
     9         kx }
     9         kx 
     9         kx /* Swap in a Vernaux structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_vernaux_in (bfd *abfd,
     9         kx 			  const Elf_External_Vernaux *src,
     9         kx 			  Elf_Internal_Vernaux *dst)
     9         kx {
     9         kx   dst->vna_hash  = H_GET_32 (abfd, src->vna_hash);
     9         kx   dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
     9         kx   dst->vna_other = H_GET_16 (abfd, src->vna_other);
     9         kx   dst->vna_name  = H_GET_32 (abfd, src->vna_name);
     9         kx   dst->vna_next  = H_GET_32 (abfd, src->vna_next);
     9         kx }
     9         kx 
     9         kx /* Swap out a Vernaux structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_vernaux_out (bfd *abfd,
     9         kx 			   const Elf_Internal_Vernaux *src,
     9         kx 			   Elf_External_Vernaux *dst)
     9         kx {
     9         kx   H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
     9         kx   H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
     9         kx   H_PUT_16 (abfd, src->vna_other, dst->vna_other);
     9         kx   H_PUT_32 (abfd, src->vna_name, dst->vna_name);
     9         kx   H_PUT_32 (abfd, src->vna_next, dst->vna_next);
     9         kx }
     9         kx 
     9         kx /* Swap in a Versym structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_versym_in (bfd *abfd,
     9         kx 			 const Elf_External_Versym *src,
     9         kx 			 Elf_Internal_Versym *dst)
     9         kx {
     9         kx   dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
     9         kx }
     9         kx 
     9         kx /* Swap out a Versym structure.  */
     9         kx 
     9         kx void
     9         kx _bfd_elf_swap_versym_out (bfd *abfd,
     9         kx 			  const Elf_Internal_Versym *src,
     9         kx 			  Elf_External_Versym *dst)
     9         kx {
     9         kx   H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
     9         kx }
     9         kx 
     9         kx /* Standard ELF hash function.  Do not change this function; you will
     9         kx    cause invalid hash tables to be generated.  */
     9         kx 
     9         kx unsigned long
     9         kx bfd_elf_hash (const char *namearg)
     9         kx {
     9         kx   const unsigned char *name = (const unsigned char *) namearg;
     9         kx   unsigned long h = 0;
     9         kx   unsigned long g;
     9         kx   int ch;
     9         kx 
     9         kx   while ((ch = *name++) != '\0')
     9         kx     {
     9         kx       h = (h << 4) + ch;
     9         kx       if ((g = (h & 0xf0000000)) != 0)
     9         kx 	{
     9         kx 	  h ^= g >> 24;
     9         kx 	  /* The ELF ABI says `h &= ~g', but this is equivalent in
     9         kx 	     this case and on some machines one insn instead of two.  */
     9         kx 	  h ^= g;
     9         kx 	}
     9         kx     }
     9         kx   return h & 0xffffffff;
     9         kx }
     9         kx 
     9         kx /* DT_GNU_HASH hash function.  Do not change this function; you will
     9         kx    cause invalid hash tables to be generated.  */
     9         kx 
     9         kx unsigned long
     9         kx bfd_elf_gnu_hash (const char *namearg)
     9         kx {
     9         kx   const unsigned char *name = (const unsigned char *) namearg;
     9         kx   unsigned long h = 5381;
     9         kx   unsigned char ch;
     9         kx 
     9         kx   while ((ch = *name++) != '\0')
     9         kx     h = (h << 5) + h + ch;
     9         kx   return h & 0xffffffff;
     9         kx }
     9         kx 
     9         kx /* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
     9         kx    the object_id field of an elf_obj_tdata field set to OBJECT_ID.  */
     9         kx bool
     9         kx bfd_elf_allocate_object (bfd *abfd,
     9         kx 			 size_t object_size,
     9         kx 			 enum elf_target_id object_id)
     9         kx {
     9         kx   BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
     9         kx   abfd->tdata.any = bfd_zalloc (abfd, object_size);
     9         kx   if (abfd->tdata.any == NULL)
     9         kx     return false;
     9         kx 
     9         kx   elf_object_id (abfd) = object_id;
     9         kx   if (abfd->direction != read_direction)
     9         kx     {
     9         kx       struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
     9         kx       if (o == NULL)
     9         kx 	return false;
     9         kx       elf_tdata (abfd)->o = o;
     9         kx       elf_program_header_size (abfd) = (bfd_size_type) -1;
     9         kx     }
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx 
     9         kx bool
     9         kx bfd_elf_make_object (bfd *abfd)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
     9         kx 				  bed->target_id);
     9         kx }
     9         kx 
     9         kx bool
     9         kx bfd_elf_mkcorefile (bfd *abfd)
     9         kx {
     9         kx   /* I think this can be done just like an object file.  */
     9         kx   if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
     9         kx     return false;
     9         kx   elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
     9         kx   return elf_tdata (abfd)->core != NULL;
     9         kx }
     9         kx 
     9         kx char *
     9         kx bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
     9         kx {
     9         kx   Elf_Internal_Shdr **i_shdrp;
     9         kx   bfd_byte *shstrtab = NULL;
     9         kx   file_ptr offset;
     9         kx   bfd_size_type shstrtabsize;
     9         kx 
     9         kx   i_shdrp = elf_elfsections (abfd);
     9         kx   if (i_shdrp == 0
     9         kx       || shindex >= elf_numsections (abfd)
     9         kx       || i_shdrp[shindex] == 0)
     9         kx     return NULL;
     9         kx 
     9         kx   shstrtab = i_shdrp[shindex]->contents;
     9         kx   if (shstrtab == NULL)
     9         kx     {
     9         kx       /* No cached one, attempt to read, and cache what we read.  */
     9         kx       offset = i_shdrp[shindex]->sh_offset;
     9         kx       shstrtabsize = i_shdrp[shindex]->sh_size;
     9         kx 
     9         kx       /* Allocate and clear an extra byte at the end, to prevent crashes
     9         kx 	 in case the string table is not terminated.  */
     9         kx       if (shstrtabsize + 1 <= 1
     9         kx 	  || bfd_seek (abfd, offset, SEEK_SET) != 0
     9         kx 	  || (shstrtab = _bfd_alloc_and_read (abfd, shstrtabsize + 1,
     9         kx 					      shstrtabsize)) == NULL)
     9         kx 	{
     9         kx 	  /* Once we've failed to read it, make sure we don't keep
     9         kx 	     trying.  Otherwise, we'll keep allocating space for
     9         kx 	     the string table over and over.  */
     9         kx 	  i_shdrp[shindex]->sh_size = 0;
     9         kx 	}
     9         kx       else
     9         kx 	shstrtab[shstrtabsize] = '\0';
     9         kx       i_shdrp[shindex]->contents = shstrtab;
     9         kx     }
     9         kx   return (char *) shstrtab;
     9         kx }
     9         kx 
     9         kx char *
     9         kx bfd_elf_string_from_elf_section (bfd *abfd,
     9         kx 				 unsigned int shindex,
     9         kx 				 unsigned int strindex)
     9         kx {
     9         kx   Elf_Internal_Shdr *hdr;
     9         kx 
     9         kx   if (strindex == 0)
     9         kx     return "";
     9         kx 
     9         kx   if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd))
     9         kx     return NULL;
     9         kx 
     9         kx   hdr = elf_elfsections (abfd)[shindex];
     9         kx 
     9         kx   if (hdr->contents == NULL)
     9         kx     {
     9         kx       if (hdr->sh_type != SHT_STRTAB && hdr->sh_type < SHT_LOOS)
     9         kx 	{
     9         kx 	  /* PR 17512: file: f057ec89.  */
     9         kx 	  /* xgettext:c-format */
     9         kx 	  _bfd_error_handler (_("%pB: attempt to load strings from"
     9         kx 				" a non-string section (number %d)"),
     9         kx 			      abfd, shindex);
     9         kx 	  return NULL;
     9         kx 	}
     9         kx 
     9         kx       if (bfd_elf_get_str_section (abfd, shindex) == NULL)
     9         kx 	return NULL;
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       /* PR 24273: The string section's contents may have already
     9         kx 	 been loaded elsewhere, eg because a corrupt file has the
     9         kx 	 string section index in the ELF header pointing at a group
     9         kx 	 section.  So be paranoid, and test that the last byte of
     9         kx 	 the section is zero.  */
     9         kx       if (hdr->sh_size == 0 || hdr->contents[hdr->sh_size - 1] != 0)
     9         kx 	return NULL;
     9         kx     }
     9         kx 
     9         kx   if (strindex >= hdr->sh_size)
     9         kx     {
     9         kx       unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
     9         kx       _bfd_error_handler
     9         kx 	/* xgettext:c-format */
     9         kx 	(_("%pB: invalid string offset %u >= %" PRIu64 " for section `%s'"),
     9         kx 	 abfd, strindex, (uint64_t) hdr->sh_size,
     9         kx 	 (shindex == shstrndx && strindex == hdr->sh_name
     9         kx 	  ? ".shstrtab"
     9         kx 	  : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
     9         kx       return NULL;
     9         kx     }
     9         kx 
     9         kx   return ((char *) hdr->contents) + strindex;
     9         kx }
     9         kx 
     9         kx /* Read and convert symbols to internal format.
     9         kx    SYMCOUNT specifies the number of symbols to read, starting from
     9         kx    symbol SYMOFFSET.  If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
     9         kx    are non-NULL, they are used to store the internal symbols, external
     9         kx    symbols, and symbol section index extensions, respectively.
     9         kx    Returns a pointer to the internal symbol buffer (malloced if necessary)
     9         kx    or NULL if there were no symbols or some kind of problem.  */
     9         kx 
     9         kx Elf_Internal_Sym *
     9         kx bfd_elf_get_elf_syms (bfd *ibfd,
     9         kx 		      Elf_Internal_Shdr *symtab_hdr,
     9         kx 		      size_t symcount,
     9         kx 		      size_t symoffset,
     9         kx 		      Elf_Internal_Sym *intsym_buf,
     9         kx 		      void *extsym_buf,
     9         kx 		      Elf_External_Sym_Shndx *extshndx_buf)
     9         kx {
     9         kx   Elf_Internal_Shdr *shndx_hdr;
     9         kx   void *alloc_ext;
     9         kx   const bfd_byte *esym;
     9         kx   Elf_External_Sym_Shndx *alloc_extshndx;
     9         kx   Elf_External_Sym_Shndx *shndx;
     9         kx   Elf_Internal_Sym *alloc_intsym;
     9         kx   Elf_Internal_Sym *isym;
     9         kx   Elf_Internal_Sym *isymend;
     9         kx   const struct elf_backend_data *bed;
     9         kx   size_t extsym_size;
     9         kx   size_t amt;
     9         kx   file_ptr pos;
     9         kx 
     9         kx   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
     9         kx     abort ();
     9         kx 
     9         kx   if (symcount == 0)
     9         kx     return intsym_buf;
     9         kx 
     9         kx   /* Normal syms might have section extension entries.  */
     9         kx   shndx_hdr = NULL;
     9         kx   if (elf_symtab_shndx_list (ibfd) != NULL)
     9         kx     {
     9         kx       elf_section_list * entry;
     9         kx       Elf_Internal_Shdr **sections = elf_elfsections (ibfd);
     9         kx 
     9         kx       /* Find an index section that is linked to this symtab section.  */
     9         kx       for (entry = elf_symtab_shndx_list (ibfd); entry != NULL; entry = entry->next)
     9         kx 	{
     9         kx 	  /* PR 20063.  */
     9         kx 	  if (entry->hdr.sh_link >= elf_numsections (ibfd))
     9         kx 	    continue;
     9         kx 
     9         kx 	  if (sections[entry->hdr.sh_link] == symtab_hdr)
     9         kx 	    {
     9         kx 	      shndx_hdr = & entry->hdr;
     9         kx 	      break;
     9         kx 	    };
     9         kx 	}
     9         kx 
     9         kx       if (shndx_hdr == NULL)
     9         kx 	{
     9         kx 	  if (symtab_hdr == &elf_symtab_hdr (ibfd))
     9         kx 	    /* Not really accurate, but this was how the old code used
     9         kx 	       to work.  */
     9         kx 	    shndx_hdr = &elf_symtab_shndx_list (ibfd)->hdr;
     9         kx 	  /* Otherwise we do nothing.  The assumption is that
     9         kx 	     the index table will not be needed.  */
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Read the symbols.  */
     9         kx   alloc_ext = NULL;
     9         kx   alloc_extshndx = NULL;
     9         kx   alloc_intsym = NULL;
     9         kx   bed = get_elf_backend_data (ibfd);
     9         kx   extsym_size = bed->s->sizeof_sym;
     9         kx   if (_bfd_mul_overflow (symcount, extsym_size, &amt))
     9         kx     {
     9         kx       bfd_set_error (bfd_error_file_too_big);
     9         kx       intsym_buf = NULL;
     9         kx       goto out;
     9         kx     }
     9         kx   pos = symtab_hdr->sh_offset + symoffset * extsym_size;
     9         kx   if (extsym_buf == NULL)
     9         kx     {
     9         kx       alloc_ext = bfd_malloc (amt);
     9         kx       extsym_buf = alloc_ext;
     9         kx     }
     9         kx   if (extsym_buf == NULL
     9         kx       || bfd_seek (ibfd, pos, SEEK_SET) != 0
     9         kx       || bfd_bread (extsym_buf, amt, ibfd) != amt)
     9         kx     {
     9         kx       intsym_buf = NULL;
     9         kx       goto out;
     9         kx     }
     9         kx 
     9         kx   if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
     9         kx     extshndx_buf = NULL;
     9         kx   else
     9         kx     {
     9         kx       if (_bfd_mul_overflow (symcount, sizeof (Elf_External_Sym_Shndx), &amt))
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_too_big);
     9         kx 	  intsym_buf = NULL;
     9         kx 	  goto out;
     9         kx 	}
     9         kx       pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
     9         kx       if (extshndx_buf == NULL)
     9         kx 	{
     9         kx 	  alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
     9         kx 	  extshndx_buf = alloc_extshndx;
     9         kx 	}
     9         kx       if (extshndx_buf == NULL
     9         kx 	  || bfd_seek (ibfd, pos, SEEK_SET) != 0
     9         kx 	  || bfd_bread (extshndx_buf, amt, ibfd) != amt)
     9         kx 	{
     9         kx 	  intsym_buf = NULL;
     9         kx 	  goto out;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   if (intsym_buf == NULL)
     9         kx     {
     9         kx       if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt))
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_too_big);
     9         kx 	  goto out;
     9         kx 	}
     9         kx       alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt);
     9         kx       intsym_buf = alloc_intsym;
     9         kx       if (intsym_buf == NULL)
     9         kx 	goto out;
     9         kx     }
     9         kx 
     9         kx   /* Convert the symbols to internal form.  */
     9         kx   isymend = intsym_buf + symcount;
     9         kx   for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf,
     9         kx 	   shndx = extshndx_buf;
     9         kx        isym < isymend;
     9         kx        esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
     9         kx     if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
     9         kx       {
     9         kx 	symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
     9         kx 	/* xgettext:c-format */
     9         kx 	_bfd_error_handler (_("%pB symbol number %lu references"
     9         kx 			      " nonexistent SHT_SYMTAB_SHNDX section"),
     9         kx 			    ibfd, (unsigned long) symoffset);
     9         kx 	free (alloc_intsym);
     9         kx 	intsym_buf = NULL;
     9         kx 	goto out;
     9         kx       }
     9         kx 
     9         kx  out:
     9         kx   free (alloc_ext);
     9         kx   free (alloc_extshndx);
     9         kx 
     9         kx   return intsym_buf;
     9         kx }
     9         kx 
     9         kx /* Look up a symbol name.  */
     9         kx const char *
     9         kx bfd_elf_sym_name (bfd *abfd,
     9         kx 		  Elf_Internal_Shdr *symtab_hdr,
     9         kx 		  Elf_Internal_Sym *isym,
     9         kx 		  asection *sym_sec)
     9         kx {
     9         kx   const char *name;
     9         kx   unsigned int iname = isym->st_name;
     9         kx   unsigned int shindex = symtab_hdr->sh_link;
     9         kx 
     9         kx   if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
     9         kx       /* Check for a bogus st_shndx to avoid crashing.  */
     9         kx       && isym->st_shndx < elf_numsections (abfd))
     9         kx     {
     9         kx       iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
     9         kx       shindex = elf_elfheader (abfd)->e_shstrndx;
     9         kx     }
     9         kx 
     9         kx   name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
     9         kx   if (name == NULL)
     9         kx     name = "(null)";
     9         kx   else if (sym_sec && *name == '\0')
     9         kx     name = bfd_section_name (sym_sec);
     9         kx 
     9         kx   return name;
     9         kx }
     9         kx 
     9         kx /* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
     9         kx    sections.  The first element is the flags, the rest are section
     9         kx    pointers.  */
     9         kx 
     9         kx typedef union elf_internal_group {
     9         kx   Elf_Internal_Shdr *shdr;
     9         kx   unsigned int flags;
     9         kx } Elf_Internal_Group;
     9         kx 
     9         kx /* Return the name of the group signature symbol.  Why isn't the
     9         kx    signature just a string?  */
     9         kx 
     9         kx static const char *
     9         kx group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
     9         kx {
     9         kx   Elf_Internal_Shdr *hdr;
     9         kx   unsigned char esym[sizeof (Elf64_External_Sym)];
     9         kx   Elf_External_Sym_Shndx eshndx;
     9         kx   Elf_Internal_Sym isym;
     9         kx 
     9         kx   /* First we need to ensure the symbol table is available.  Make sure
     9         kx      that it is a symbol table section.  */
     9         kx   if (ghdr->sh_link >= elf_numsections (abfd))
     9         kx     return NULL;
     9         kx   hdr = elf_elfsections (abfd) [ghdr->sh_link];
     9         kx   if (hdr->sh_type != SHT_SYMTAB
     9         kx       || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
     9         kx     return NULL;
     9         kx 
     9         kx   /* Go read the symbol.  */
     9         kx   hdr = &elf_tdata (abfd)->symtab_hdr;
     9         kx   if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
     9         kx 			    &isym, esym, &eshndx) == NULL)
     9         kx     return NULL;
     9         kx 
     9         kx   return bfd_elf_sym_name (abfd, hdr, &isym, NULL);
     9         kx }
     9         kx 
     9         kx /* Set next_in_group list pointer, and group name for NEWSECT.  */
     9         kx 
     9         kx static bool
     9         kx setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
     9         kx {
     9         kx   unsigned int num_group = elf_tdata (abfd)->num_group;
     9         kx 
     9         kx   /* If num_group is zero, read in all SHT_GROUP sections.  The count
     9         kx      is set to -1 if there are no SHT_GROUP sections.  */
     9         kx   if (num_group == 0)
     9         kx     {
     9         kx       unsigned int i, shnum;
     9         kx 
     9         kx       /* First count the number of groups.  If we have a SHT_GROUP
     9         kx 	 section with just a flag word (ie. sh_size is 4), ignore it.  */
     9         kx       shnum = elf_numsections (abfd);
     9         kx       num_group = 0;
     9         kx 
     9         kx #define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize)	\
     9         kx 	(   (shdr)->sh_type == SHT_GROUP		\
     9         kx 	 && (shdr)->sh_size >= minsize			\
     9         kx 	 && (shdr)->sh_entsize == GRP_ENTRY_SIZE	\
     9         kx 	 && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
     9         kx 
     9         kx       for (i = 0; i < shnum; i++)
     9         kx 	{
     9         kx 	  Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
     9         kx 
     9         kx 	  if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
     9         kx 	    num_group += 1;
     9         kx 	}
     9         kx 
     9         kx       if (num_group == 0)
     9         kx 	{
     9         kx 	  num_group = (unsigned) -1;
     9         kx 	  elf_tdata (abfd)->num_group = num_group;
     9         kx 	  elf_tdata (abfd)->group_sect_ptr = NULL;
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  /* We keep a list of elf section headers for group sections,
     9         kx 	     so we can find them quickly.  */
     9         kx 	  size_t amt;
     9         kx 
     9         kx 	  elf_tdata (abfd)->num_group = num_group;
     9         kx 	  amt = num_group * sizeof (Elf_Internal_Shdr *);
     9         kx 	  elf_tdata (abfd)->group_sect_ptr
     9         kx 	    = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
     9         kx 	  if (elf_tdata (abfd)->group_sect_ptr == NULL)
     9         kx 	    return false;
     9         kx 	  num_group = 0;
     9         kx 
     9         kx 	  for (i = 0; i < shnum; i++)
     9         kx 	    {
     9         kx 	      Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
     9         kx 
     9         kx 	      if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
     9         kx 		{
     9         kx 		  unsigned char *src;
     9         kx 		  Elf_Internal_Group *dest;
     9         kx 
     9         kx 		  /* Make sure the group section has a BFD section
     9         kx 		     attached to it.  */
     9         kx 		  if (!bfd_section_from_shdr (abfd, i))
     9         kx 		    return false;
     9         kx 
     9         kx 		  /* Add to list of sections.  */
     9         kx 		  elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
     9         kx 		  num_group += 1;
     9         kx 
     9         kx 		  /* Read the raw contents.  */
     9         kx 		  BFD_ASSERT (sizeof (*dest) >= 4 && sizeof (*dest) % 4 == 0);
     9         kx 		  shdr->contents = NULL;
     9         kx 		  if (_bfd_mul_overflow (shdr->sh_size,
     9         kx 					 sizeof (*dest) / 4, &amt)
     9         kx 		      || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
     9         kx 		      || !(shdr->contents
     9         kx 			   = _bfd_alloc_and_read (abfd, amt, shdr->sh_size)))
     9         kx 		    {
     9         kx 		      _bfd_error_handler
     9         kx 			/* xgettext:c-format */
     9         kx 			(_("%pB: invalid size field in group section"
     9         kx 			   " header: %#" PRIx64 ""),
     9         kx 			 abfd, (uint64_t) shdr->sh_size);
     9         kx 		      bfd_set_error (bfd_error_bad_value);
     9         kx 		      -- num_group;
     9         kx 		      continue;
     9         kx 		    }
     9         kx 
     9         kx 		  /* Translate raw contents, a flag word followed by an
     9         kx 		     array of elf section indices all in target byte order,
     9         kx 		     to the flag word followed by an array of elf section
     9         kx 		     pointers.  */
     9         kx 		  src = shdr->contents + shdr->sh_size;
     9         kx 		  dest = (Elf_Internal_Group *) (shdr->contents + amt);
     9         kx 
     9         kx 		  while (1)
     9         kx 		    {
     9         kx 		      unsigned int idx;
     9         kx 
     9         kx 		      src -= 4;
     9         kx 		      --dest;
     9         kx 		      idx = H_GET_32 (abfd, src);
     9         kx 		      if (src == shdr->contents)
     9         kx 			{
     9         kx 			  dest->shdr = NULL;
     9         kx 			  dest->flags = idx;
     9         kx 			  if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
     9         kx 			    shdr->bfd_section->flags
     9         kx 			      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
     9         kx 			  break;
     9         kx 			}
     9         kx 		      if (idx < shnum)
     9         kx 			{
     9         kx 			  dest->shdr = elf_elfsections (abfd)[idx];
     9         kx 			  /* PR binutils/23199: All sections in a
     9         kx 			     section group should be marked with
     9         kx 			     SHF_GROUP.  But some tools generate
     9         kx 			     broken objects without SHF_GROUP.  Fix
     9         kx 			     them up here.  */
     9         kx 			  dest->shdr->sh_flags |= SHF_GROUP;
     9         kx 			}
     9         kx 		      if (idx >= shnum
     9         kx 			  || dest->shdr->sh_type == SHT_GROUP)
     9         kx 			{
     9         kx 			  _bfd_error_handler
     9         kx 			    (_("%pB: invalid entry in SHT_GROUP section [%u]"),
     9         kx 			       abfd, i);
     9         kx 			  dest->shdr = NULL;
     9         kx 			}
     9         kx 		    }
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  /* PR 17510: Corrupt binaries might contain invalid groups.  */
     9         kx 	  if (num_group != (unsigned) elf_tdata (abfd)->num_group)
     9         kx 	    {
     9         kx 	      elf_tdata (abfd)->num_group = num_group;
     9         kx 
     9         kx 	      /* If all groups are invalid then fail.  */
     9         kx 	      if (num_group == 0)
     9         kx 		{
     9         kx 		  elf_tdata (abfd)->group_sect_ptr = NULL;
     9         kx 		  elf_tdata (abfd)->num_group = num_group = -1;
     9         kx 		  _bfd_error_handler
     9         kx 		    (_("%pB: no valid group sections found"), abfd);
     9         kx 		  bfd_set_error (bfd_error_bad_value);
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   if (num_group != (unsigned) -1)
     9         kx     {
     9         kx       unsigned int search_offset = elf_tdata (abfd)->group_search_offset;
     9         kx       unsigned int j;
     9         kx 
     9         kx       for (j = 0; j < num_group; j++)
     9         kx 	{
     9         kx 	  /* Begin search from previous found group.  */
     9         kx 	  unsigned i = (j + search_offset) % num_group;
     9         kx 
     9         kx 	  Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
     9         kx 	  Elf_Internal_Group *idx;
     9         kx 	  bfd_size_type n_elt;
     9         kx 
     9         kx 	  if (shdr == NULL)
     9         kx 	    continue;
     9         kx 
     9         kx 	  idx = (Elf_Internal_Group *) shdr->contents;
     9         kx 	  if (idx == NULL || shdr->sh_size < 4)
     9         kx 	    {
     9         kx 	      /* See PR 21957 for a reproducer.  */
     9         kx 	      /* xgettext:c-format */
     9         kx 	      _bfd_error_handler (_("%pB: group section '%pA' has no contents"),
     9         kx 				  abfd, shdr->bfd_section);
     9         kx 	      elf_tdata (abfd)->group_sect_ptr[i] = NULL;
     9         kx 	      bfd_set_error (bfd_error_bad_value);
     9         kx 	      return false;
     9         kx 	    }
     9         kx 	  n_elt = shdr->sh_size / 4;
     9         kx 
     9         kx 	  /* Look through this group's sections to see if current
     9         kx 	     section is a member.  */
     9         kx 	  while (--n_elt != 0)
     9         kx 	    if ((++idx)->shdr == hdr)
     9         kx 	      {
     9         kx 		asection *s = NULL;
     9         kx 
     9         kx 		/* We are a member of this group.  Go looking through
     9         kx 		   other members to see if any others are linked via
     9         kx 		   next_in_group.  */
     9         kx 		idx = (Elf_Internal_Group *) shdr->contents;
     9         kx 		n_elt = shdr->sh_size / 4;
     9         kx 		while (--n_elt != 0)
     9         kx 		  if ((++idx)->shdr != NULL
     9         kx 		      && (s = idx->shdr->bfd_section) != NULL
     9         kx 		      && elf_next_in_group (s) != NULL)
     9         kx 		    break;
     9         kx 		if (n_elt != 0)
     9         kx 		  {
     9         kx 		    /* Snarf the group name from other member, and
     9         kx 		       insert current section in circular list.  */
     9         kx 		    elf_group_name (newsect) = elf_group_name (s);
     9         kx 		    elf_next_in_group (newsect) = elf_next_in_group (s);
     9         kx 		    elf_next_in_group (s) = newsect;
     9         kx 		  }
     9         kx 		else
     9         kx 		  {
     9         kx 		    const char *gname;
     9         kx 
     9         kx 		    gname = group_signature (abfd, shdr);
     9         kx 		    if (gname == NULL)
     9         kx 		      return false;
     9         kx 		    elf_group_name (newsect) = gname;
     9         kx 
     9         kx 		    /* Start a circular list with one element.  */
     9         kx 		    elf_next_in_group (newsect) = newsect;
     9         kx 		  }
     9         kx 
     9         kx 		/* If the group section has been created, point to the
     9         kx 		   new member.  */
     9         kx 		if (shdr->bfd_section != NULL)
     9         kx 		  elf_next_in_group (shdr->bfd_section) = newsect;
     9         kx 
     9         kx 		elf_tdata (abfd)->group_search_offset = i;
     9         kx 		j = num_group - 1;
     9         kx 		break;
     9         kx 	      }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   if (elf_group_name (newsect) == NULL
     9         kx       /* OS specific sections might be in a group (eg ARM's ARM_EXIDX section)
     9         kx 	 but they will not have been added to the group because they do not
     9         kx 	 have contents that the ELF code in the BFD library knows how to
     9         kx 	 process.  This is OK though - we rely upon the target backends to
     9         kx 	 handle these sections for us.  */
     9         kx       && hdr->sh_type < SHT_LOOS)
     9         kx     {
     9         kx       /* xgettext:c-format */
     9         kx       _bfd_error_handler (_("%pB: no group info for section '%pA'"),
     9         kx 			  abfd, newsect);
     9         kx       /* PR 29532: Return true here, even though the group info has not been
     9         kx 	 read.  Separate debug info files can have empty group sections, but
     9         kx 	 we do not want this to prevent them from being loaded as otherwise
     9         kx 	 GDB will not be able to use them.  */
     9         kx       return true;
     9         kx     }
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_setup_sections (bfd *abfd)
     9         kx {
     9         kx   unsigned int i;
     9         kx   unsigned int num_group = elf_tdata (abfd)->num_group;
     9         kx   bool result = true;
     9         kx   asection *s;
     9         kx 
     9         kx   /* Process SHF_LINK_ORDER.  */
     9         kx   for (s = abfd->sections; s != NULL; s = s->next)
     9         kx     {
     9         kx       Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
     9         kx       if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
     9         kx 	{
     9         kx 	  unsigned int elfsec = this_hdr->sh_link;
     9         kx 	  /* An sh_link value of 0 is now allowed.  It indicates that linked
     9         kx 	     to section has already been discarded, but that the current
     9         kx 	     section has been retained for some other reason.  This linking
     9         kx 	     section is still a candidate for later garbage collection
     9         kx 	     however.  */
     9         kx 	  if (elfsec == 0)
     9         kx 	    {
     9         kx 	      elf_linked_to_section (s) = NULL;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      asection *linksec = NULL;
     9         kx 
     9         kx 	      if (elfsec < elf_numsections (abfd))
     9         kx 		{
     9         kx 		  this_hdr = elf_elfsections (abfd)[elfsec];
     9         kx 		  linksec = this_hdr->bfd_section;
     9         kx 		}
     9         kx 
     9         kx 	      /* PR 1991, 2008:
     9         kx 		 Some strip/objcopy may leave an incorrect value in
     9         kx 		 sh_link.  We don't want to proceed.  */
     9         kx 	      if (linksec == NULL)
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB: sh_link [%d] in section `%pA' is incorrect"),
     9         kx 		     s->owner, elfsec, s);
     9         kx 		  result = false;
     9         kx 		}
     9         kx 
     9         kx 	      elf_linked_to_section (s) = linksec;
     9         kx 	    }
     9         kx 	}
     9         kx       else if (this_hdr->sh_type == SHT_GROUP
     9         kx 	       && elf_next_in_group (s) == NULL)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    /* xgettext:c-format */
     9         kx 	    (_("%pB: SHT_GROUP section [index %d] has no SHF_GROUP sections"),
     9         kx 	     abfd, elf_section_data (s)->this_idx);
     9         kx 	  result = false;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Process section groups.  */
     9         kx   if (num_group == (unsigned) -1)
     9         kx     return result;
     9         kx 
     9         kx   for (i = 0; i < num_group; i++)
     9         kx     {
     9         kx       Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
     9         kx       Elf_Internal_Group *idx;
     9         kx       unsigned int n_elt;
     9         kx 
     9         kx       /* PR binutils/18758: Beware of corrupt binaries with invalid
     9         kx 	 group data.  */
     9         kx       if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    /* xgettext:c-format */
     9         kx 	    (_("%pB: section group entry number %u is corrupt"),
     9         kx 	     abfd, i);
     9         kx 	  result = false;
     9         kx 	  continue;
     9         kx 	}
     9         kx 
     9         kx       idx = (Elf_Internal_Group *) shdr->contents;
     9         kx       n_elt = shdr->sh_size / 4;
     9         kx 
     9         kx       while (--n_elt != 0)
     9         kx 	{
     9         kx 	  ++ idx;
     9         kx 
     9         kx 	  if (idx->shdr == NULL)
     9         kx 	    continue;
     9         kx 	  else if (idx->shdr->bfd_section)
     9         kx 	    elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
     9         kx 	  else if (idx->shdr->sh_type != SHT_RELA
     9         kx 		   && idx->shdr->sh_type != SHT_REL
     9         kx 		   && idx->shdr->sh_type < SHT_LOOS)
     9         kx 	    {
     9         kx 	      /* There are some unknown sections in the group.  */
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB: unknown type [%#x] section `%s' in group [%pA]"),
     9         kx 		 abfd,
     9         kx 		 idx->shdr->sh_type,
     9         kx 		 bfd_elf_string_from_elf_section (abfd,
     9         kx 						  (elf_elfheader (abfd)
     9         kx 						   ->e_shstrndx),
     9         kx 						  idx->shdr->sh_name),
     9         kx 		 shdr->bfd_section);
     9         kx 	      result = false;
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return result;
     9         kx }
     9         kx 
     9         kx bool
     9         kx bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
     9         kx {
     9         kx   return elf_next_in_group (sec) != NULL;
     9         kx }
     9         kx 
     9         kx const char *
     9         kx bfd_elf_group_name (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
     9         kx {
     9         kx   if (elf_sec_group (sec) != NULL)
     9         kx     return elf_group_name (sec);
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx /* This a copy of lto_section defined in GCC (lto-streamer.h).  */
     9         kx 
     9         kx struct lto_section
     9         kx {
     9         kx   int16_t major_version;
     9         kx   int16_t minor_version;
     9         kx   unsigned char slim_object;
     9         kx 
     9         kx   /* Flags is a private field that is not defined publicly.  */
     9         kx   uint16_t flags;
     9         kx };
     9         kx 
     9         kx /* Make a BFD section from an ELF section.  We store a pointer to the
     9         kx    BFD section in the bfd_section field of the header.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_make_section_from_shdr (bfd *abfd,
     9         kx 				 Elf_Internal_Shdr *hdr,
     9         kx 				 const char *name,
     9         kx 				 int shindex)
     9         kx {
     9         kx   asection *newsect;
     9         kx   flagword flags;
     9         kx   const struct elf_backend_data *bed;
     9         kx   unsigned int opb = bfd_octets_per_byte (abfd, NULL);
     9         kx 
     9         kx   if (hdr->bfd_section != NULL)
     9         kx     return true;
     9         kx 
     9         kx   newsect = bfd_make_section_anyway (abfd, name);
     9         kx   if (newsect == NULL)
     9         kx     return false;
     9         kx 
     9         kx   hdr->bfd_section = newsect;
     9         kx   elf_section_data (newsect)->this_hdr = *hdr;
     9         kx   elf_section_data (newsect)->this_idx = shindex;
     9         kx 
     9         kx   /* Always use the real type/flags.  */
     9         kx   elf_section_type (newsect) = hdr->sh_type;
     9         kx   elf_section_flags (newsect) = hdr->sh_flags;
     9         kx 
     9         kx   newsect->filepos = hdr->sh_offset;
     9         kx 
     9         kx   flags = SEC_NO_FLAGS;
     9         kx   if (hdr->sh_type != SHT_NOBITS)
     9         kx     flags |= SEC_HAS_CONTENTS;
     9         kx   if (hdr->sh_type == SHT_GROUP)
     9         kx     flags |= SEC_GROUP;
     9         kx   if ((hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx     {
     9         kx       flags |= SEC_ALLOC;
     9         kx       if (hdr->sh_type != SHT_NOBITS)
     9         kx 	flags |= SEC_LOAD;
     9         kx     }
     9         kx   if ((hdr->sh_flags & SHF_WRITE) == 0)
     9         kx     flags |= SEC_READONLY;
     9         kx   if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
     9         kx     flags |= SEC_CODE;
     9         kx   else if ((flags & SEC_LOAD) != 0)
     9         kx     flags |= SEC_DATA;
     9         kx   if ((hdr->sh_flags & SHF_MERGE) != 0)
     9         kx     {
     9         kx       flags |= SEC_MERGE;
     9         kx       newsect->entsize = hdr->sh_entsize;
     9         kx     }
     9         kx   if ((hdr->sh_flags & SHF_STRINGS) != 0)
     9         kx     flags |= SEC_STRINGS;
     9         kx   if (hdr->sh_flags & SHF_GROUP)
     9         kx     if (!setup_group (abfd, hdr, newsect))
     9         kx       return false;
     9         kx   if ((hdr->sh_flags & SHF_TLS) != 0)
     9         kx     flags |= SEC_THREAD_LOCAL;
     9         kx   if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
     9         kx     flags |= SEC_EXCLUDE;
     9         kx 
     9         kx   switch (elf_elfheader (abfd)->e_ident[EI_OSABI])
     9         kx     {
     9         kx       /* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
     9         kx 	 but binutils as of 2019-07-23 did not set the EI_OSABI header
     9         kx 	 byte.  */
     9         kx     case ELFOSABI_GNU:
     9         kx     case ELFOSABI_FREEBSD:
     9         kx       if ((hdr->sh_flags & SHF_GNU_RETAIN) != 0)
     9         kx 	elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_retain;
     9         kx       /* Fall through */
     9         kx     case ELFOSABI_NONE:
     9         kx       if ((hdr->sh_flags & SHF_GNU_MBIND) != 0)
     9         kx 	elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
     9         kx       break;
     9         kx     }
     9         kx 
     9         kx   if ((flags & SEC_ALLOC) == 0)
     9         kx     {
     9         kx       /* The debugging sections appear to be recognized only by name,
     9         kx 	 not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
     9         kx       if (name [0] == '.')
     9         kx 	{
     9         kx 	  if (startswith (name, ".debug")
     9         kx 	      || startswith (name, ".gnu.debuglto_.debug_")
     9         kx 	      || startswith (name, ".gnu.linkonce.wi.")
     9         kx 	      || startswith (name, ".zdebug"))
     9         kx 	    flags |= SEC_DEBUGGING | SEC_ELF_OCTETS;
     9         kx 	  else if (startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
     9         kx 		   || startswith (name, ".note.gnu"))
     9         kx 	    {
     9         kx 	      flags |= SEC_ELF_OCTETS;
     9         kx 	      opb = 1;
     9         kx 	    }
     9         kx 	  else if (startswith (name, ".line")
     9         kx 		   || startswith (name, ".stab")
     9         kx 		   || strcmp (name, ".gdb_index") == 0)
     9         kx 	    flags |= SEC_DEBUGGING;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb)
     9         kx       || !bfd_set_section_size (newsect, hdr->sh_size)
     9         kx       || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign
     9         kx 							& -hdr->sh_addralign)))
     9         kx     return false;
     9         kx 
     9         kx   /* As a GNU extension, if the name begins with .gnu.linkonce, we
     9         kx      only link a single copy of the section.  This is used to support
     9         kx      g++.  g++ will emit each template expansion in its own section.
     9         kx      The symbols will be defined as weak, so that multiple definitions
     9         kx      are permitted.  The GNU linker extension is to actually discard
     9         kx      all but one of the sections.  */
     9         kx   if (startswith (name, ".gnu.linkonce")
     9         kx       && elf_next_in_group (newsect) == NULL)
     9         kx     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
     9         kx 
     9         kx   if (!bfd_set_section_flags (newsect, flags))
     9         kx     return false;
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   if (bed->elf_backend_section_flags)
     9         kx     if (!bed->elf_backend_section_flags (hdr))
     9         kx       return false;
     9         kx 
     9         kx   /* We do not parse the PT_NOTE segments as we are interested even in the
     9         kx      separate debug info files which may have the segments offsets corrupted.
     9         kx      PT_NOTEs from the core files are currently not parsed using BFD.  */
     9         kx   if (hdr->sh_type == SHT_NOTE && hdr->sh_size != 0)
     9         kx     {
     9         kx       bfd_byte *contents;
     9         kx 
     9         kx       if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
     9         kx 	return false;
     9         kx 
     9         kx       elf_parse_notes (abfd, (char *) contents, hdr->sh_size,
     9         kx 		       hdr->sh_offset, hdr->sh_addralign);
     9         kx       free (contents);
     9         kx     }
     9         kx 
     9         kx   if ((newsect->flags & SEC_ALLOC) != 0)
     9         kx     {
     9         kx       Elf_Internal_Phdr *phdr;
     9         kx       unsigned int i, nload;
     9         kx 
     9         kx       /* Some ELF linkers produce binaries with all the program header
     9         kx 	 p_paddr fields zero.  If we have such a binary with more than
     9         kx 	 one PT_LOAD header, then leave the section lma equal to vma
     9         kx 	 so that we don't create sections with overlapping lma.  */
     9         kx       phdr = elf_tdata (abfd)->phdr;
     9         kx       for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
     9         kx 	if (phdr->p_paddr != 0)
     9         kx 	  break;
     9         kx 	else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
     9         kx 	  ++nload;
     9         kx       if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
     9         kx 	return true;
     9         kx 
     9         kx       phdr = elf_tdata (abfd)->phdr;
     9         kx       for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
     9         kx 	{
     9         kx 	  if (((phdr->p_type == PT_LOAD
     9         kx 		&& (hdr->sh_flags & SHF_TLS) == 0)
     9         kx 	       || phdr->p_type == PT_TLS)
     9         kx 	      && ELF_SECTION_IN_SEGMENT (hdr, phdr))
     9         kx 	    {
     9         kx 	      if ((newsect->flags & SEC_LOAD) == 0)
     9         kx 		newsect->lma = (phdr->p_paddr
     9         kx 				+ hdr->sh_addr - phdr->p_vaddr) / opb;
     9         kx 	      else
     9         kx 		/* We used to use the same adjustment for SEC_LOAD
     9         kx 		   sections, but that doesn't work if the segment
     9         kx 		   is packed with code from multiple VMAs.
     9         kx 		   Instead we calculate the section LMA based on
     9         kx 		   the segment LMA.  It is assumed that the
     9         kx 		   segment will contain sections with contiguous
     9         kx 		   LMAs, even if the VMAs are not.  */
     9         kx 		newsect->lma = (phdr->p_paddr
     9         kx 				+ hdr->sh_offset - phdr->p_offset) / opb;
     9         kx 
     9         kx 	      /* With contiguous segments, we can't tell from file
     9         kx 		 offsets whether a section with zero size should
     9         kx 		 be placed at the end of one segment or the
     9         kx 		 beginning of the next.  Decide based on vaddr.  */
     9         kx 	      if (hdr->sh_addr >= phdr->p_vaddr
     9         kx 		  && (hdr->sh_addr + hdr->sh_size
     9         kx 		      <= phdr->p_vaddr + phdr->p_memsz))
     9         kx 		break;
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Compress/decompress DWARF debug sections with names: .debug_*,
     9         kx      .zdebug_*, .gnu.debuglto_.debug_, after the section flags is set.  */
     9         kx   if ((newsect->flags & SEC_DEBUGGING) != 0
     9         kx       && (newsect->flags & SEC_HAS_CONTENTS) != 0
     9         kx       && (newsect->flags & SEC_ELF_OCTETS) != 0)
     9         kx     {
     9         kx       enum { nothing, compress, decompress } action = nothing;
     9         kx       int compression_header_size;
     9         kx       bfd_size_type uncompressed_size;
     9         kx       unsigned int uncompressed_align_power;
     9         kx       enum compression_type ch_type = ch_none;
     9         kx       bool compressed
     9         kx 	= bfd_is_section_compressed_info (abfd, newsect,
     9         kx 					  &compression_header_size,
     9         kx 					  &uncompressed_size,
     9         kx 					  &uncompressed_align_power,
     9         kx 					  &ch_type);
     9         kx 
     9         kx       /* Should we decompress?  */
     9         kx       if ((abfd->flags & BFD_DECOMPRESS) != 0 && compressed)
     9         kx 	action = decompress;
     9         kx 
     9         kx       /* Should we compress?  Or convert to a different compression?  */
     9         kx       else if ((abfd->flags & BFD_COMPRESS) != 0
     9         kx 	       && newsect->size != 0
     9         kx 	       && compression_header_size >= 0
     9         kx 	       && uncompressed_size > 0)
     9         kx 	{
     9         kx 	  if (!compressed)
     9         kx 	    action = compress;
     9         kx 	  else
     9         kx 	    {
     9         kx 	      enum compression_type new_ch_type = ch_none;
     9         kx 	      if ((abfd->flags & BFD_COMPRESS_GABI) != 0)
     9         kx 		new_ch_type = ((abfd->flags & BFD_COMPRESS_ZSTD) != 0
     9         kx 			       ? ch_compress_zstd : ch_compress_zlib);
     9         kx 	      if (new_ch_type != ch_type)
     9         kx 		action = compress;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (action == compress)
     9         kx 	{
     9         kx 	  if (!bfd_init_section_compress_status (abfd, newsect))
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB: unable to compress section %s"), abfd, name);
     9         kx 	      return false;
     9         kx 	    }
     9         kx 	}
     9         kx       else if (action == decompress)
     9         kx 	{
     9         kx 	  if (!bfd_init_section_decompress_status (abfd, newsect))
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB: unable to decompress section %s"), abfd, name);
     9         kx 	      return false;
     9         kx 	    }
     9         kx #ifndef HAVE_ZSTD
     9         kx 	  if (newsect->compress_status == DECOMPRESS_SECTION_ZSTD)
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		  /* xgettext:c-format */
     9         kx 		  (_ ("%pB: section %s is compressed with zstd, but BFD "
     9         kx 		      "is not built with zstd support"),
     9         kx 		   abfd, name);
     9         kx 	      newsect->compress_status = COMPRESS_SECTION_NONE;
     9         kx 	      return false;
     9         kx 	    }
     9         kx #endif
     9         kx 	  if (abfd->is_linker_input
     9         kx 	      && name[1] == 'z')
     9         kx 	    {
     9         kx 	      /* Rename section from .zdebug_* to .debug_* so that ld
     9         kx 		 scripts will see this section as a debug section.  */
     9         kx 	      char *new_name = bfd_zdebug_name_to_debug (abfd, name);
     9         kx 	      if (new_name == NULL)
     9         kx 		return false;
     9         kx 	      bfd_rename_section (newsect, new_name);
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode information
     9         kx      section.  */
     9         kx   if (startswith (name, ".gnu.lto_.lto."))
     9         kx     {
     9         kx       struct lto_section lsection;
     9         kx       if (bfd_get_section_contents (abfd, newsect, &lsection, 0,
     9         kx 				    sizeof (struct lto_section)))
     9         kx 	abfd->lto_slim_object = lsection.slim_object;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx const char *const bfd_elf_section_type_names[] =
     9         kx {
     9         kx   "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
     9         kx   "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
     9         kx   "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
     9         kx };
     9         kx 
     9         kx /* ELF relocs are against symbols.  If we are producing relocatable
     9         kx    output, and the reloc is against an external symbol, and nothing
     9         kx    has given us any additional addend, the resulting reloc will also
     9         kx    be against the same symbol.  In such a case, we don't want to
     9         kx    change anything about the way the reloc is handled, since it will
     9         kx    all be done at final link time.  Rather than put special case code
     9         kx    into bfd_perform_relocation, all the reloc types use this howto
     9         kx    function, or should call this function for relocatable output.  */
     9         kx 
     9         kx bfd_reloc_status_type
     9         kx bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
     9         kx 		       arelent *reloc_entry,
     9         kx 		       asymbol *symbol,
     9         kx 		       void *data ATTRIBUTE_UNUSED,
     9         kx 		       asection *input_section,
     9         kx 		       bfd *output_bfd,
     9         kx 		       char **error_message ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   if (output_bfd != NULL
     9         kx       && (symbol->flags & BSF_SECTION_SYM) == 0
     9         kx       && (! reloc_entry->howto->partial_inplace
     9         kx 	  || reloc_entry->addend == 0))
     9         kx     {
     9         kx       reloc_entry->address += input_section->output_offset;
     9         kx       return bfd_reloc_ok;
     9         kx     }
     9         kx 
     9         kx   /* In some cases the relocation should be treated as output section
     9         kx      relative, as when linking ELF DWARF into PE COFF.  Many ELF
     9         kx      targets lack section relative relocations and instead use
     9         kx      ordinary absolute relocations for references between DWARF
     9         kx      sections.  That is arguably a bug in those targets but it happens
     9         kx      to work for the usual case of linking to non-loaded ELF debug
     9         kx      sections with VMAs forced to zero.  PE COFF on the other hand
     9         kx      doesn't allow a section VMA of zero.  */
     9         kx   if (output_bfd == NULL
     9         kx       && !reloc_entry->howto->pc_relative
     9         kx       && (symbol->section->flags & SEC_DEBUGGING) != 0
     9         kx       && (input_section->flags & SEC_DEBUGGING) != 0)
     9         kx     reloc_entry->addend -= symbol->section->output_section->vma;
     9         kx 
     9         kx   return bfd_reloc_continue;
     9         kx }
     9         kx 
     9         kx /* Returns TRUE if section A matches section B.
     9         kx    Names, addresses and links may be different, but everything else
     9         kx    should be the same.  */
     9         kx 
     9         kx static bool
     9         kx section_match (const Elf_Internal_Shdr * a,
     9         kx 	       const Elf_Internal_Shdr * b)
     9         kx {
     9         kx   if (a->sh_type != b->sh_type
     9         kx       || ((a->sh_flags ^ b->sh_flags) & ~SHF_INFO_LINK) != 0
     9         kx       || a->sh_addralign != b->sh_addralign
     9         kx       || a->sh_entsize != b->sh_entsize)
     9         kx     return false;
     9         kx   if (a->sh_type == SHT_SYMTAB
     9         kx       || a->sh_type == SHT_STRTAB)
     9         kx     return true;
     9         kx   return a->sh_size == b->sh_size;
     9         kx }
     9         kx 
     9         kx /* Find a section in OBFD that has the same characteristics
     9         kx    as IHEADER.  Return the index of this section or SHN_UNDEF if
     9         kx    none can be found.  Check's section HINT first, as this is likely
     9         kx    to be the correct section.  */
     9         kx 
     9         kx static unsigned int
     9         kx find_link (const bfd *obfd, const Elf_Internal_Shdr *iheader,
     9         kx 	   const unsigned int hint)
     9         kx {
     9         kx   Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
     9         kx   unsigned int i;
     9         kx 
     9         kx   BFD_ASSERT (iheader != NULL);
     9         kx 
     9         kx   /* See PR 20922 for a reproducer of the NULL test.  */
     9         kx   if (hint < elf_numsections (obfd)
     9         kx       && oheaders[hint] != NULL
     9         kx       && section_match (oheaders[hint], iheader))
     9         kx     return hint;
     9         kx 
     9         kx   for (i = 1; i < elf_numsections (obfd); i++)
     9         kx     {
     9         kx       Elf_Internal_Shdr * oheader = oheaders[i];
     9         kx 
     9         kx       if (oheader == NULL)
     9         kx 	continue;
     9         kx       if (section_match (oheader, iheader))
     9         kx 	/* FIXME: Do we care if there is a potential for
     9         kx 	   multiple matches ?  */
     9         kx 	return i;
     9         kx     }
     9         kx 
     9         kx   return SHN_UNDEF;
     9         kx }
     9         kx 
     9         kx /* PR 19938: Attempt to set the ELF section header fields of an OS or
     9         kx    Processor specific section, based upon a matching input section.
     9         kx    Returns TRUE upon success, FALSE otherwise.  */
     9         kx 
     9         kx static bool
     9         kx copy_special_section_fields (const bfd *ibfd,
     9         kx 			     bfd *obfd,
     9         kx 			     const Elf_Internal_Shdr *iheader,
     9         kx 			     Elf_Internal_Shdr *oheader,
     9         kx 			     const unsigned int secnum)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (obfd);
     9         kx   const Elf_Internal_Shdr **iheaders
     9         kx     = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
     9         kx   bool changed = false;
     9         kx   unsigned int sh_link;
     9         kx 
     9         kx   if (oheader->sh_type == SHT_NOBITS)
     9         kx     {
     9         kx       /* This is a feature for objcopy --only-keep-debug:
     9         kx 	 When a section's type is changed to NOBITS, we preserve
     9         kx 	 the sh_link and sh_info fields so that they can be
     9         kx 	 matched up with the original.
     9         kx 
     9         kx 	 Note: Strictly speaking these assignments are wrong.
     9         kx 	 The sh_link and sh_info fields should point to the
     9         kx 	 relevent sections in the output BFD, which may not be in
     9         kx 	 the same location as they were in the input BFD.  But
     9         kx 	 the whole point of this action is to preserve the
     9         kx 	 original values of the sh_link and sh_info fields, so
     9         kx 	 that they can be matched up with the section headers in
     9         kx 	 the original file.  So strictly speaking we may be
     9         kx 	 creating an invalid ELF file, but it is only for a file
     9         kx 	 that just contains debug info and only for sections
     9         kx 	 without any contents.  */
     9         kx       if (oheader->sh_link == 0)
     9         kx 	oheader->sh_link = iheader->sh_link;
     9         kx       if (oheader->sh_info == 0)
     9         kx 	oheader->sh_info = iheader->sh_info;
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   /* Allow the target a chance to decide how these fields should be set.  */
     9         kx   if (bed->elf_backend_copy_special_section_fields (ibfd, obfd,
     9         kx 						    iheader, oheader))
     9         kx     return true;
     9         kx 
     9         kx   /* We have an iheader which might match oheader, and which has non-zero
     9         kx      sh_info and/or sh_link fields.  Attempt to follow those links and find
     9         kx      the section in the output bfd which corresponds to the linked section
     9         kx      in the input bfd.  */
     9         kx   if (iheader->sh_link != SHN_UNDEF)
     9         kx     {
     9         kx       /* See PR 20931 for a reproducer.  */
     9         kx       if (iheader->sh_link >= elf_numsections (ibfd))
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    /* xgettext:c-format */
     9         kx 	    (_("%pB: invalid sh_link field (%d) in section number %d"),
     9         kx 	     ibfd, iheader->sh_link, secnum);
     9         kx 	  return false;
     9         kx 	}
     9         kx 
     9         kx       sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link);
     9         kx       if (sh_link != SHN_UNDEF)
     9         kx 	{
     9         kx 	  oheader->sh_link = sh_link;
     9         kx 	  changed = true;
     9         kx 	}
     9         kx       else
     9         kx 	/* FIXME: Should we install iheader->sh_link
     9         kx 	   if we could not find a match ?  */
     9         kx 	_bfd_error_handler
     9         kx 	  /* xgettext:c-format */
     9         kx 	  (_("%pB: failed to find link section for section %d"), obfd, secnum);
     9         kx     }
     9         kx 
     9         kx   if (iheader->sh_info)
     9         kx     {
     9         kx       /* The sh_info field can hold arbitrary information, but if the
     9         kx 	 SHF_LINK_INFO flag is set then it should be interpreted as a
     9         kx 	 section index.  */
     9         kx       if (iheader->sh_flags & SHF_INFO_LINK)
     9         kx 	{
     9         kx 	  sh_link = find_link (obfd, iheaders[iheader->sh_info],
     9         kx 			       iheader->sh_info);
     9         kx 	  if (sh_link != SHN_UNDEF)
     9         kx 	    oheader->sh_flags |= SHF_INFO_LINK;
     9         kx 	}
     9         kx       else
     9         kx 	/* No idea what it means - just copy it.  */
     9         kx 	sh_link = iheader->sh_info;
     9         kx 
     9         kx       if (sh_link != SHN_UNDEF)
     9         kx 	{
     9         kx 	  oheader->sh_info = sh_link;
     9         kx 	  changed = true;
     9         kx 	}
     9         kx       else
     9         kx 	_bfd_error_handler
     9         kx 	  /* xgettext:c-format */
     9         kx 	  (_("%pB: failed to find info section for section %d"), obfd, secnum);
     9         kx     }
     9         kx 
     9         kx   return changed;
     9         kx }
     9         kx 
     9         kx /* Copy the program header and other data from one object module to
     9         kx    another.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     9         kx {
     9         kx   const Elf_Internal_Shdr **iheaders
     9         kx     = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
     9         kx   Elf_Internal_Shdr **oheaders = elf_elfsections (obfd);
     9         kx   const struct elf_backend_data *bed;
     9         kx   unsigned int i;
     9         kx 
     9         kx   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
     9         kx     || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     9         kx     return true;
     9         kx 
     9         kx   if (!elf_flags_init (obfd))
     9         kx     {
     9         kx       elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
     9         kx       elf_flags_init (obfd) = true;
     9         kx     }
     9         kx 
     9         kx   elf_gp (obfd) = elf_gp (ibfd);
     9         kx 
     9         kx   /* Also copy the EI_OSABI field.  */
     9         kx   elf_elfheader (obfd)->e_ident[EI_OSABI] =
     9         kx     elf_elfheader (ibfd)->e_ident[EI_OSABI];
     9         kx 
     9         kx   /* If set, copy the EI_ABIVERSION field.  */
     9         kx   if (elf_elfheader (ibfd)->e_ident[EI_ABIVERSION])
     9         kx     elf_elfheader (obfd)->e_ident[EI_ABIVERSION]
     9         kx       = elf_elfheader (ibfd)->e_ident[EI_ABIVERSION];
     9         kx 
     9         kx   /* Copy object attributes.  */
     9         kx   _bfd_elf_copy_obj_attributes (ibfd, obfd);
     9         kx 
     9         kx   if (iheaders == NULL || oheaders == NULL)
     9         kx     return true;
     9         kx 
     9         kx   bed = get_elf_backend_data (obfd);
     9         kx 
     9         kx   /* Possibly copy other fields in the section header.  */
     9         kx   for (i = 1; i < elf_numsections (obfd); i++)
     9         kx     {
     9         kx       unsigned int j;
     9         kx       Elf_Internal_Shdr * oheader = oheaders[i];
     9         kx 
     9         kx       /* Ignore ordinary sections.  SHT_NOBITS sections are considered however
     9         kx 	 because of a special case need for generating separate debug info
     9         kx 	 files.  See below for more details.  */
     9         kx       if (oheader == NULL
     9         kx 	  || (oheader->sh_type != SHT_NOBITS
     9         kx 	      && oheader->sh_type < SHT_LOOS))
     9         kx 	continue;
     9         kx 
     9         kx       /* Ignore empty sections, and sections whose
     9         kx 	 fields have already been initialised.  */
     9         kx       if (oheader->sh_size == 0
     9         kx 	  || (oheader->sh_info != 0 && oheader->sh_link != 0))
     9         kx 	continue;
     9         kx 
     9         kx       /* Scan for the matching section in the input bfd.
     9         kx 	 First we try for a direct mapping between the input and
     9         kx 	 output sections.  */
     9         kx       for (j = 1; j < elf_numsections (ibfd); j++)
     9         kx 	{
     9         kx 	  const Elf_Internal_Shdr * iheader = iheaders[j];
     9         kx 
     9         kx 	  if (iheader == NULL)
     9         kx 	    continue;
     9         kx 
     9         kx 	  if (oheader->bfd_section != NULL
     9         kx 	      && iheader->bfd_section != NULL
     9         kx 	      && iheader->bfd_section->output_section != NULL
     9         kx 	      && iheader->bfd_section->output_section == oheader->bfd_section)
     9         kx 	    {
     9         kx 	      /* We have found a connection from the input section to
     9         kx 		 the output section.  Attempt to copy the header fields.
     9         kx 		 If this fails then do not try any further sections -
     9         kx 		 there should only be a one-to-one mapping between
     9         kx 		 input and output.  */
     9         kx 	      if (!copy_special_section_fields (ibfd, obfd,
     9         kx 						iheader, oheader, i))
     9         kx 		j = elf_numsections (ibfd);
     9         kx 	      break;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (j < elf_numsections (ibfd))
     9         kx 	continue;
     9         kx 
     9         kx       /* That failed.  So try to deduce the corresponding input section.
     9         kx 	 Unfortunately we cannot compare names as the output string table
     9         kx 	 is empty, so instead we check size, address and type.  */
     9         kx       for (j = 1; j < elf_numsections (ibfd); j++)
     9         kx 	{
     9         kx 	  const Elf_Internal_Shdr * iheader = iheaders[j];
     9         kx 
     9         kx 	  if (iheader == NULL)
     9         kx 	    continue;
     9         kx 
     9         kx 	  /* Try matching fields in the input section's header.
     9         kx 	     Since --only-keep-debug turns all non-debug sections into
     9         kx 	     SHT_NOBITS sections, the output SHT_NOBITS type matches any
     9         kx 	     input type.  */
     9         kx 	  if ((oheader->sh_type == SHT_NOBITS
     9         kx 	       || iheader->sh_type == oheader->sh_type)
     9         kx 	      && (iheader->sh_flags & ~ SHF_INFO_LINK)
     9         kx 	      == (oheader->sh_flags & ~ SHF_INFO_LINK)
     9         kx 	      && iheader->sh_addralign == oheader->sh_addralign
     9         kx 	      && iheader->sh_entsize == oheader->sh_entsize
     9         kx 	      && iheader->sh_size == oheader->sh_size
     9         kx 	      && iheader->sh_addr == oheader->sh_addr
     9         kx 	      && (iheader->sh_info != oheader->sh_info
     9         kx 		  || iheader->sh_link != oheader->sh_link))
     9         kx 	    {
     9         kx 	      if (copy_special_section_fields (ibfd, obfd, iheader, oheader, i))
     9         kx 		break;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (j == elf_numsections (ibfd) && oheader->sh_type >= SHT_LOOS)
     9         kx 	{
     9         kx 	  /* Final attempt.  Call the backend copy function
     9         kx 	     with a NULL input section.  */
     9         kx 	  (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd,
     9         kx 							       NULL, oheader);
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static const char *
     9         kx get_segment_type (unsigned int p_type)
     9         kx {
     9         kx   const char *pt;
     9         kx   switch (p_type)
     9         kx     {
     9         kx     case PT_NULL: pt = "NULL"; break;
     9         kx     case PT_LOAD: pt = "LOAD"; break;
     9         kx     case PT_DYNAMIC: pt = "DYNAMIC"; break;
     9         kx     case PT_INTERP: pt = "INTERP"; break;
     9         kx     case PT_NOTE: pt = "NOTE"; break;
     9         kx     case PT_SHLIB: pt = "SHLIB"; break;
     9         kx     case PT_PHDR: pt = "PHDR"; break;
     9         kx     case PT_TLS: pt = "TLS"; break;
     9         kx     case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
     9         kx     case PT_GNU_STACK: pt = "STACK"; break;
     9         kx     case PT_GNU_RELRO: pt = "RELRO"; break;
     9         kx     case PT_GNU_SFRAME: pt = "SFRAME"; break;
     9         kx     default: pt = NULL; break;
     9         kx     }
     9         kx   return pt;
     9         kx }
     9         kx 
     9         kx /* Print out the program headers.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
     9         kx {
     9         kx   FILE *f = (FILE *) farg;
     9         kx   Elf_Internal_Phdr *p;
     9         kx   asection *s;
     9         kx   bfd_byte *dynbuf = NULL;
     9         kx 
     9         kx   p = elf_tdata (abfd)->phdr;
     9         kx   if (p != NULL)
     9         kx     {
     9         kx       unsigned int i, c;
     9         kx 
     9         kx       fprintf (f, _("\nProgram Header:\n"));
     9         kx       c = elf_elfheader (abfd)->e_phnum;
     9         kx       for (i = 0; i < c; i++, p++)
     9         kx 	{
     9         kx 	  const char *pt = get_segment_type (p->p_type);
     9         kx 	  char buf[20];
     9         kx 
     9         kx 	  if (pt == NULL)
     9         kx 	    {
     9         kx 	      sprintf (buf, "0x%lx", p->p_type);
     9         kx 	      pt = buf;
     9         kx 	    }
     9         kx 	  fprintf (f, "%8s off    0x", pt);
     9         kx 	  bfd_fprintf_vma (abfd, f, p->p_offset);
     9         kx 	  fprintf (f, " vaddr 0x");
     9         kx 	  bfd_fprintf_vma (abfd, f, p->p_vaddr);
     9         kx 	  fprintf (f, " paddr 0x");
     9         kx 	  bfd_fprintf_vma (abfd, f, p->p_paddr);
     9         kx 	  fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
     9         kx 	  fprintf (f, "         filesz 0x");
     9         kx 	  bfd_fprintf_vma (abfd, f, p->p_filesz);
     9         kx 	  fprintf (f, " memsz 0x");
     9         kx 	  bfd_fprintf_vma (abfd, f, p->p_memsz);
     9         kx 	  fprintf (f, " flags %c%c%c",
     9         kx 		   (p->p_flags & PF_R) != 0 ? 'r' : '-',
     9         kx 		   (p->p_flags & PF_W) != 0 ? 'w' : '-',
     9         kx 		   (p->p_flags & PF_X) != 0 ? 'x' : '-');
     9         kx 	  if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
     9         kx 	    fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
     9         kx 	  fprintf (f, "\n");
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   s = bfd_get_section_by_name (abfd, ".dynamic");
     9         kx   if (s != NULL)
     9         kx     {
     9         kx       unsigned int elfsec;
     9         kx       unsigned long shlink;
     9         kx       bfd_byte *extdyn, *extdynend;
     9         kx       size_t extdynsize;
     9         kx       void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
     9         kx 
     9         kx       fprintf (f, _("\nDynamic Section:\n"));
     9         kx 
     9         kx       if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
     9         kx 	goto error_return;
     9         kx 
     9         kx       elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
     9         kx       if (elfsec == SHN_BAD)
     9         kx 	goto error_return;
     9         kx       shlink = elf_elfsections (abfd)[elfsec]->sh_link;
     9         kx 
     9         kx       extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
     9         kx       swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
     9         kx 
     9         kx       for (extdyn = dynbuf, extdynend = dynbuf + s->size;
     9         kx 	   (size_t) (extdynend - extdyn) >= extdynsize;
     9         kx 	   extdyn += extdynsize)
     9         kx 	{
     9         kx 	  Elf_Internal_Dyn dyn;
     9         kx 	  const char *name = "";
     9         kx 	  char ab[20];
     9         kx 	  bool stringp;
     9         kx 	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx 	  (*swap_dyn_in) (abfd, extdyn, &dyn);
     9         kx 
     9         kx 	  if (dyn.d_tag == DT_NULL)
     9         kx 	    break;
     9         kx 
     9         kx 	  stringp = false;
     9         kx 	  switch (dyn.d_tag)
     9         kx 	    {
     9         kx 	    default:
     9         kx 	      if (bed->elf_backend_get_target_dtag)
     9         kx 		name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
     9         kx 
     9         kx 	      if (!strcmp (name, ""))
     9         kx 		{
     9         kx 		  sprintf (ab, "%#" PRIx64, (uint64_t) dyn.d_tag);
     9         kx 		  name = ab;
     9         kx 		}
     9         kx 	      break;
     9         kx 
     9         kx 	    case DT_NEEDED: name = "NEEDED"; stringp = true; break;
     9         kx 	    case DT_PLTRELSZ: name = "PLTRELSZ"; break;
     9         kx 	    case DT_PLTGOT: name = "PLTGOT"; break;
     9         kx 	    case DT_HASH: name = "HASH"; break;
     9         kx 	    case DT_STRTAB: name = "STRTAB"; break;
     9         kx 	    case DT_SYMTAB: name = "SYMTAB"; break;
     9         kx 	    case DT_RELA: name = "RELA"; break;
     9         kx 	    case DT_RELASZ: name = "RELASZ"; break;
     9         kx 	    case DT_RELAENT: name = "RELAENT"; break;
     9         kx 	    case DT_STRSZ: name = "STRSZ"; break;
     9         kx 	    case DT_SYMENT: name = "SYMENT"; break;
     9         kx 	    case DT_INIT: name = "INIT"; break;
     9         kx 	    case DT_FINI: name = "FINI"; break;
     9         kx 	    case DT_SONAME: name = "SONAME"; stringp = true; break;
     9         kx 	    case DT_RPATH: name = "RPATH"; stringp = true; break;
     9         kx 	    case DT_SYMBOLIC: name = "SYMBOLIC"; break;
     9         kx 	    case DT_REL: name = "REL"; break;
     9         kx 	    case DT_RELSZ: name = "RELSZ"; break;
     9         kx 	    case DT_RELENT: name = "RELENT"; break;
     9         kx 	    case DT_RELR: name = "RELR"; break;
     9         kx 	    case DT_RELRSZ: name = "RELRSZ"; break;
     9         kx 	    case DT_RELRENT: name = "RELRENT"; break;
     9         kx 	    case DT_PLTREL: name = "PLTREL"; break;
     9         kx 	    case DT_DEBUG: name = "DEBUG"; break;
     9         kx 	    case DT_TEXTREL: name = "TEXTREL"; break;
     9         kx 	    case DT_JMPREL: name = "JMPREL"; break;
     9         kx 	    case DT_BIND_NOW: name = "BIND_NOW"; break;
     9         kx 	    case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
     9         kx 	    case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
     9         kx 	    case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
     9         kx 	    case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
     9         kx 	    case DT_RUNPATH: name = "RUNPATH"; stringp = true; break;
     9         kx 	    case DT_FLAGS: name = "FLAGS"; break;
     9         kx 	    case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
     9         kx 	    case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
     9         kx 	    case DT_CHECKSUM: name = "CHECKSUM"; break;
     9         kx 	    case DT_PLTPADSZ: name = "PLTPADSZ"; break;
     9         kx 	    case DT_MOVEENT: name = "MOVEENT"; break;
     9         kx 	    case DT_MOVESZ: name = "MOVESZ"; break;
     9         kx 	    case DT_FEATURE: name = "FEATURE"; break;
     9         kx 	    case DT_POSFLAG_1: name = "POSFLAG_1"; break;
     9         kx 	    case DT_SYMINSZ: name = "SYMINSZ"; break;
     9         kx 	    case DT_SYMINENT: name = "SYMINENT"; break;
     9         kx 	    case DT_CONFIG: name = "CONFIG"; stringp = true; break;
     9         kx 	    case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = true; break;
     9         kx 	    case DT_AUDIT: name = "AUDIT"; stringp = true; break;
     9         kx 	    case DT_PLTPAD: name = "PLTPAD"; break;
     9         kx 	    case DT_MOVETAB: name = "MOVETAB"; break;
     9         kx 	    case DT_SYMINFO: name = "SYMINFO"; break;
     9         kx 	    case DT_RELACOUNT: name = "RELACOUNT"; break;
     9         kx 	    case DT_RELCOUNT: name = "RELCOUNT"; break;
     9         kx 	    case DT_FLAGS_1: name = "FLAGS_1"; break;
     9         kx 	    case DT_VERSYM: name = "VERSYM"; break;
     9         kx 	    case DT_VERDEF: name = "VERDEF"; break;
     9         kx 	    case DT_VERDEFNUM: name = "VERDEFNUM"; break;
     9         kx 	    case DT_VERNEED: name = "VERNEED"; break;
     9         kx 	    case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
     9         kx 	    case DT_AUXILIARY: name = "AUXILIARY"; stringp = true; break;
     9         kx 	    case DT_USED: name = "USED"; break;
     9         kx 	    case DT_FILTER: name = "FILTER"; stringp = true; break;
     9         kx 	    case DT_GNU_HASH: name = "GNU_HASH"; break;
     9         kx 	    }
     9         kx 
     9         kx 	  fprintf (f, "  %-20s ", name);
     9         kx 	  if (! stringp)
     9         kx 	    {
     9         kx 	      fprintf (f, "0x");
     9         kx 	      bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      const char *string;
     9         kx 	      unsigned int tagv = dyn.d_un.d_val;
     9         kx 
     9         kx 	      string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
     9         kx 	      if (string == NULL)
     9         kx 		goto error_return;
     9         kx 	      fprintf (f, "%s", string);
     9         kx 	    }
     9         kx 	  fprintf (f, "\n");
     9         kx 	}
     9         kx 
     9         kx       free (dynbuf);
     9         kx       dynbuf = NULL;
     9         kx     }
     9         kx 
     9         kx   if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
     9         kx       || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
     9         kx     {
     9         kx       if (! _bfd_elf_slurp_version_tables (abfd, false))
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   if (elf_dynverdef (abfd) != 0)
     9         kx     {
     9         kx       Elf_Internal_Verdef *t;
     9         kx 
     9         kx       fprintf (f, _("\nVersion definitions:\n"));
     9         kx       for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
     9         kx 	{
     9         kx 	  fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
     9         kx 		   t->vd_flags, t->vd_hash,
     9         kx 		   t->vd_nodename ? t->vd_nodename : "<corrupt>");
     9         kx 	  if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
     9         kx 	    {
     9         kx 	      Elf_Internal_Verdaux *a;
     9         kx 
     9         kx 	      fprintf (f, "\t");
     9         kx 	      for (a = t->vd_auxptr->vda_nextptr;
     9         kx 		   a != NULL;
     9         kx 		   a = a->vda_nextptr)
     9         kx 		fprintf (f, "%s ",
     9         kx 			 a->vda_nodename ? a->vda_nodename : "<corrupt>");
     9         kx 	      fprintf (f, "\n");
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   if (elf_dynverref (abfd) != 0)
     9         kx     {
     9         kx       Elf_Internal_Verneed *t;
     9         kx 
     9         kx       fprintf (f, _("\nVersion References:\n"));
     9         kx       for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
     9         kx 	{
     9         kx 	  Elf_Internal_Vernaux *a;
     9         kx 
     9         kx 	  fprintf (f, _("  required from %s:\n"),
     9         kx 		   t->vn_filename ? t->vn_filename : "<corrupt>");
     9         kx 	  for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
     9         kx 	    fprintf (f, "    0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
     9         kx 		     a->vna_flags, a->vna_other,
     9         kx 		     a->vna_nodename ? a->vna_nodename : "<corrupt>");
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx 
     9         kx  error_return:
     9         kx   free (dynbuf);
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx /* Get version name.  If BASE_P is TRUE, return "Base" for VER_FLG_BASE
     9         kx    and return symbol version for symbol version itself.   */
     9         kx 
     9         kx const char *
     9         kx _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
     9         kx 				    bool base_p,
     9         kx 				    bool *hidden)
     9         kx {
     9         kx   const char *version_string = NULL;
     9         kx   if (elf_dynversym (abfd) != 0
     9         kx       && (elf_dynverdef (abfd) != 0 || elf_dynverref (abfd) != 0))
     9         kx     {
     9         kx       unsigned int vernum = ((elf_symbol_type *) symbol)->version;
     9         kx 
     9         kx       *hidden = (vernum & VERSYM_HIDDEN) != 0;
     9         kx       vernum &= VERSYM_VERSION;
     9         kx 
     9         kx       if (vernum == 0)
     9         kx 	version_string = "";
     9         kx       else if (vernum == 1
     9         kx 	       && (vernum > elf_tdata (abfd)->cverdefs
     9         kx 		   || (elf_tdata (abfd)->verdef[0].vd_flags
     9         kx 		       == VER_FLG_BASE)))
     9         kx 	version_string = base_p ? "Base" : "";
     9         kx       else if (vernum <= elf_tdata (abfd)->cverdefs)
     9         kx 	{
     9         kx 	  const char *nodename
     9         kx 	    = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
     9         kx 	  version_string = "";
     9         kx 	  if (base_p
     9         kx 	      || nodename == NULL
     9         kx 	      || symbol->name == NULL
     9         kx 	      || strcmp (symbol->name, nodename) != 0)
     9         kx 	    version_string = nodename;
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  Elf_Internal_Verneed *t;
     9         kx 
     9         kx 	  version_string = _("<corrupt>");
     9         kx 	  for (t = elf_tdata (abfd)->verref;
     9         kx 	       t != NULL;
     9         kx 	       t = t->vn_nextref)
     9         kx 	    {
     9         kx 	      Elf_Internal_Vernaux *a;
     9         kx 
     9         kx 	      for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
     9         kx 		{
     9         kx 		  if (a->vna_other == vernum)
     9         kx 		    {
     9         kx 		      *hidden = true;
     9         kx 		      version_string = a->vna_nodename;
     9         kx 		      break;
     9         kx 		    }
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx   return version_string;
     9         kx }
     9         kx 
     9         kx /* Display ELF-specific fields of a symbol.  */
     9         kx 
     9         kx void
     9         kx bfd_elf_print_symbol (bfd *abfd,
     9         kx 		      void *filep,
     9         kx 		      asymbol *symbol,
     9         kx 		      bfd_print_symbol_type how)
     9         kx {
     9         kx   FILE *file = (FILE *) filep;
     9         kx   switch (how)
     9         kx     {
     9         kx     case bfd_print_symbol_name:
     9         kx       fprintf (file, "%s", symbol->name);
     9         kx       break;
     9         kx     case bfd_print_symbol_more:
     9         kx       fprintf (file, "elf ");
     9         kx       bfd_fprintf_vma (abfd, file, symbol->value);
     9         kx       fprintf (file, " %x", symbol->flags);
     9         kx       break;
     9         kx     case bfd_print_symbol_all:
     9         kx       {
     9         kx 	const char *section_name;
     9         kx 	const char *name = NULL;
     9         kx 	const struct elf_backend_data *bed;
     9         kx 	unsigned char st_other;
     9         kx 	bfd_vma val;
     9         kx 	const char *version_string;
     9         kx 	bool hidden;
     9         kx 
     9         kx 	section_name = symbol->section ? symbol->section->name : "(*none*)";
     9         kx 
     9         kx 	bed = get_elf_backend_data (abfd);
     9         kx 	if (bed->elf_backend_print_symbol_all)
     9         kx 	  name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);
     9         kx 
     9         kx 	if (name == NULL)
     9         kx 	  {
     9         kx 	    name = symbol->name;
     9         kx 	    bfd_print_symbol_vandf (abfd, file, symbol);
     9         kx 	  }
     9         kx 
     9         kx 	fprintf (file, " %s\t", section_name);
     9         kx 	/* Print the "other" value for a symbol.  For common symbols,
     9         kx 	   we've already printed the size; now print the alignment.
     9         kx 	   For other symbols, we have no specified alignment, and
     9         kx 	   we've printed the address; now print the size.  */
     9         kx 	if (symbol->section && bfd_is_com_section (symbol->section))
     9         kx 	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
     9         kx 	else
     9         kx 	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
     9         kx 	bfd_fprintf_vma (abfd, file, val);
     9         kx 
     9         kx 	/* If we have version information, print it.  */
     9         kx 	version_string = _bfd_elf_get_symbol_version_string (abfd,
     9         kx 							     symbol,
     9         kx 							     true,
     9         kx 							     &hidden);
     9         kx 	if (version_string)
     9         kx 	  {
     9         kx 	    if (!hidden)
     9         kx 	      fprintf (file, "  %-11s", version_string);
     9         kx 	    else
     9         kx 	      {
     9         kx 		int i;
     9         kx 
     9         kx 		fprintf (file, " (%s)", version_string);
     9         kx 		for (i = 10 - strlen (version_string); i > 0; --i)
     9         kx 		  putc (' ', file);
     9         kx 	      }
     9         kx 	  }
     9         kx 
     9         kx 	/* If the st_other field is not zero, print it.  */
     9         kx 	st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
     9         kx 
     9         kx 	switch (st_other)
     9         kx 	  {
     9         kx 	  case 0: break;
     9         kx 	  case STV_INTERNAL:  fprintf (file, " .internal");  break;
     9         kx 	  case STV_HIDDEN:    fprintf (file, " .hidden");    break;
     9         kx 	  case STV_PROTECTED: fprintf (file, " .protected"); break;
     9         kx 	  default:
     9         kx 	    /* Some other non-defined flags are also present, so print
     9         kx 	       everything hex.  */
     9         kx 	    fprintf (file, " 0x%02x", (unsigned int) st_other);
     9         kx 	  }
     9         kx 
     9         kx 	fprintf (file, " %s", name);
     9         kx       }
     9         kx       break;
     9         kx     }
     9         kx }
     9         kx 
     9         kx /* ELF .o/exec file reading */
     9         kx 
     9         kx /* Create a new bfd section from an ELF section header.  */
     9         kx 
     9         kx bool
     9         kx bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
     9         kx {
     9         kx   Elf_Internal_Shdr *hdr;
     9         kx   Elf_Internal_Ehdr *ehdr;
     9         kx   const struct elf_backend_data *bed;
     9         kx   const char *name;
     9         kx   bool ret = true;
     9         kx 
     9         kx   if (shindex >= elf_numsections (abfd))
     9         kx     return false;
     9         kx 
     9         kx   /* PR17512: A corrupt ELF binary might contain a loop of sections via
     9         kx      sh_link or sh_info.  Detect this here, by refusing to load a
     9         kx      section that we are already in the process of loading.  */
     9         kx   if (elf_tdata (abfd)->being_created[shindex])
     9         kx     {
     9         kx       _bfd_error_handler
     9         kx 	(_("%pB: warning: loop in section dependencies detected"), abfd);
     9         kx       return false;
     9         kx     }
     9         kx   elf_tdata (abfd)->being_created[shindex] = true;
     9         kx 
     9         kx   hdr = elf_elfsections (abfd)[shindex];
     9         kx   ehdr = elf_elfheader (abfd);
     9         kx   name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
     9         kx 					  hdr->sh_name);
     9         kx   if (name == NULL)
     9         kx     goto fail;
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   switch (hdr->sh_type)
     9         kx     {
     9         kx     case SHT_NULL:
     9         kx       /* Inactive section. Throw it away.  */
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_PROGBITS:		/* Normal section with contents.  */
     9         kx     case SHT_NOBITS:		/* .bss section.  */
     9         kx     case SHT_HASH:		/* .hash section.  */
     9         kx     case SHT_NOTE:		/* .note section.  */
     9         kx     case SHT_INIT_ARRAY:	/* .init_array section.  */
     9         kx     case SHT_FINI_ARRAY:	/* .fini_array section.  */
     9         kx     case SHT_PREINIT_ARRAY:	/* .preinit_array section.  */
     9         kx     case SHT_GNU_LIBLIST:	/* .gnu.liblist section.  */
     9         kx     case SHT_GNU_HASH:		/* .gnu.hash section.  */
     9         kx       ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_DYNAMIC:	/* Dynamic linking information.  */
     9         kx       if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     9         kx 	goto fail;
     9         kx 
     9         kx       if (hdr->sh_link > elf_numsections (abfd))
     9         kx 	{
     9         kx 	  /* PR 10478: Accept Solaris binaries with a sh_link field
     9         kx 	     set to SHN_BEFORE (LORESERVE) or SHN_AFTER (LORESERVE+1).  */
     9         kx 	  switch (bfd_get_arch (abfd))
     9         kx 	    {
     9         kx 	    case bfd_arch_i386:
     9         kx 	    case bfd_arch_sparc:
     9         kx 	      if (hdr->sh_link == (SHN_LORESERVE & 0xffff)
     9         kx 		  || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff))
     9         kx 		break;
     9         kx 	      /* Otherwise fall through.  */
     9         kx 	    default:
     9         kx 	      goto fail;
     9         kx 	    }
     9         kx 	}
     9         kx       else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
     9         kx 	goto fail;
     9         kx       else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
     9         kx 	{
     9         kx 	  Elf_Internal_Shdr *dynsymhdr;
     9         kx 
     9         kx 	  /* The shared libraries distributed with hpux11 have a bogus
     9         kx 	     sh_link field for the ".dynamic" section.  Find the
     9         kx 	     string table for the ".dynsym" section instead.  */
     9         kx 	  if (elf_dynsymtab (abfd) != 0)
     9         kx 	    {
     9         kx 	      dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
     9         kx 	      hdr->sh_link = dynsymhdr->sh_link;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      unsigned int i, num_sec;
     9         kx 
     9         kx 	      num_sec = elf_numsections (abfd);
     9         kx 	      for (i = 1; i < num_sec; i++)
     9         kx 		{
     9         kx 		  dynsymhdr = elf_elfsections (abfd)[i];
     9         kx 		  if (dynsymhdr->sh_type == SHT_DYNSYM)
     9         kx 		    {
     9         kx 		      hdr->sh_link = dynsymhdr->sh_link;
     9         kx 		      break;
     9         kx 		    }
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_SYMTAB:		/* A symbol table.  */
     9         kx       if (elf_onesymtab (abfd) == shindex)
     9         kx 	goto success;
     9         kx 
     9         kx       if (hdr->sh_entsize != bed->s->sizeof_sym)
     9         kx 	goto fail;
     9         kx 
     9         kx       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
     9         kx 	{
     9         kx 	  if (hdr->sh_size != 0)
     9         kx 	    goto fail;
     9         kx 	  /* Some assemblers erroneously set sh_info to one with a
     9         kx 	     zero sh_size.  ld sees this as a global symbol count
     9         kx 	     of (unsigned) -1.  Fix it here.  */
     9         kx 	  hdr->sh_info = 0;
     9         kx 	  goto success;
     9         kx 	}
     9         kx 
     9         kx       /* PR 18854: A binary might contain more than one symbol table.
     9         kx 	 Unusual, but possible.  Warn, but continue.  */
     9         kx       if (elf_onesymtab (abfd) != 0)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    /* xgettext:c-format */
     9         kx 	    (_("%pB: warning: multiple symbol tables detected"
     9         kx 	       " - ignoring the table in section %u"),
     9         kx 	     abfd, shindex);
     9         kx 	  goto success;
     9         kx 	}
     9         kx       elf_onesymtab (abfd) = shindex;
     9         kx       elf_symtab_hdr (abfd) = *hdr;
     9         kx       elf_elfsections (abfd)[shindex] = hdr = & elf_symtab_hdr (abfd);
     9         kx       abfd->flags |= HAS_SYMS;
     9         kx 
     9         kx       /* Sometimes a shared object will map in the symbol table.  If
     9         kx 	 SHF_ALLOC is set, and this is a shared object, then we also
     9         kx 	 treat this section as a BFD section.  We can not base the
     9         kx 	 decision purely on SHF_ALLOC, because that flag is sometimes
     9         kx 	 set in a relocatable object file, which would confuse the
     9         kx 	 linker.  */
     9         kx       if ((hdr->sh_flags & SHF_ALLOC) != 0
     9         kx 	  && (abfd->flags & DYNAMIC) != 0
     9         kx 	  && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
     9         kx 						shindex))
     9         kx 	goto fail;
     9         kx 
     9         kx       /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
     9         kx 	 can't read symbols without that section loaded as well.  It
     9         kx 	 is most likely specified by the next section header.  */
     9         kx       {
     9         kx 	elf_section_list * entry;
     9         kx 	unsigned int i, num_sec;
     9         kx 
     9         kx 	for (entry = elf_symtab_shndx_list (abfd); entry; entry = entry->next)
     9         kx 	  if (entry->hdr.sh_link == shindex)
     9         kx 	    goto success;
     9         kx 
     9         kx 	num_sec = elf_numsections (abfd);
     9         kx 	for (i = shindex + 1; i < num_sec; i++)
     9         kx 	  {
     9         kx 	    Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
     9         kx 
     9         kx 	    if (hdr2->sh_type == SHT_SYMTAB_SHNDX
     9         kx 		&& hdr2->sh_link == shindex)
     9         kx 	      break;
     9         kx 	  }
     9         kx 
     9         kx 	if (i == num_sec)
     9         kx 	  for (i = 1; i < shindex; i++)
     9         kx 	    {
     9         kx 	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
     9         kx 
     9         kx 	      if (hdr2->sh_type == SHT_SYMTAB_SHNDX
     9         kx 		  && hdr2->sh_link == shindex)
     9         kx 		break;
     9         kx 	    }
     9         kx 
     9         kx 	if (i != shindex)
     9         kx 	  ret = bfd_section_from_shdr (abfd, i);
     9         kx 	/* else FIXME: we have failed to find the symbol table.
     9         kx 	   Should we issue an error?  */
     9         kx 	goto success;
     9         kx       }
     9         kx 
     9         kx     case SHT_DYNSYM:		/* A dynamic symbol table.  */
     9         kx       if (elf_dynsymtab (abfd) == shindex)
     9         kx 	goto success;
     9         kx 
     9         kx       if (hdr->sh_entsize != bed->s->sizeof_sym)
     9         kx 	goto fail;
     9         kx 
     9         kx       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
     9         kx 	{
     9         kx 	  if (hdr->sh_size != 0)
     9         kx 	    goto fail;
     9         kx 
     9         kx 	  /* Some linkers erroneously set sh_info to one with a
     9         kx 	     zero sh_size.  ld sees this as a global symbol count
     9         kx 	     of (unsigned) -1.  Fix it here.  */
     9         kx 	  hdr->sh_info = 0;
     9         kx 	  goto success;
     9         kx 	}
     9         kx 
     9         kx       /* PR 18854: A binary might contain more than one dynamic symbol table.
     9         kx 	 Unusual, but possible.  Warn, but continue.  */
     9         kx       if (elf_dynsymtab (abfd) != 0)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    /* xgettext:c-format */
     9         kx 	    (_("%pB: warning: multiple dynamic symbol tables detected"
     9         kx 	       " - ignoring the table in section %u"),
     9         kx 	     abfd, shindex);
     9         kx 	  goto success;
     9         kx 	}
     9         kx       elf_dynsymtab (abfd) = shindex;
     9         kx       elf_tdata (abfd)->dynsymtab_hdr = *hdr;
     9         kx       elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
     9         kx       abfd->flags |= HAS_SYMS;
     9         kx 
     9         kx       /* Besides being a symbol table, we also treat this as a regular
     9         kx 	 section, so that objcopy can handle it.  */
     9         kx       ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections.  */
     9         kx       {
     9         kx 	elf_section_list * entry;
     9         kx 
     9         kx 	for (entry = elf_symtab_shndx_list (abfd); entry; entry = entry->next)
     9         kx 	  if (entry->ndx == shindex)
     9         kx 	    goto success;
     9         kx 
     9         kx 	entry = bfd_alloc (abfd, sizeof (*entry));
     9         kx 	if (entry == NULL)
     9         kx 	  goto fail;
     9         kx 	entry->ndx = shindex;
     9         kx 	entry->hdr = * hdr;
     9         kx 	entry->next = elf_symtab_shndx_list (abfd);
     9         kx 	elf_symtab_shndx_list (abfd) = entry;
     9         kx 	elf_elfsections (abfd)[shindex] = & entry->hdr;
     9         kx 	goto success;
     9         kx       }
     9         kx 
     9         kx     case SHT_STRTAB:		/* A string table.  */
     9         kx       if (hdr->bfd_section != NULL)
     9         kx 	goto success;
     9         kx 
     9         kx       if (ehdr->e_shstrndx == shindex)
     9         kx 	{
     9         kx 	  elf_tdata (abfd)->shstrtab_hdr = *hdr;
     9         kx 	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
     9         kx 	  goto success;
     9         kx 	}
     9         kx 
     9         kx       if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
     9         kx 	{
     9         kx 	symtab_strtab:
     9         kx 	  elf_tdata (abfd)->strtab_hdr = *hdr;
     9         kx 	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
     9         kx 	  goto success;
     9         kx 	}
     9         kx 
     9         kx       if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
     9         kx 	{
     9         kx 	dynsymtab_strtab:
     9         kx 	  elf_tdata (abfd)->dynstrtab_hdr = *hdr;
     9         kx 	  hdr = &elf_tdata (abfd)->dynstrtab_hdr;
     9         kx 	  elf_elfsections (abfd)[shindex] = hdr;
     9         kx 	  /* We also treat this as a regular section, so that objcopy
     9         kx 	     can handle it.  */
     9         kx 	  ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
     9         kx 						 shindex);
     9         kx 	  goto success;
     9         kx 	}
     9         kx 
     9         kx       /* If the string table isn't one of the above, then treat it as a
     9         kx 	 regular section.  We need to scan all the headers to be sure,
     9         kx 	 just in case this strtab section appeared before the above.  */
     9         kx       if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
     9         kx 	{
     9         kx 	  unsigned int i, num_sec;
     9         kx 
     9         kx 	  num_sec = elf_numsections (abfd);
     9         kx 	  for (i = 1; i < num_sec; i++)
     9         kx 	    {
     9         kx 	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
     9         kx 	      if (hdr2->sh_link == shindex)
     9         kx 		{
     9         kx 		  /* Prevent endless recursion on broken objects.  */
     9         kx 		  if (i == shindex)
     9         kx 		    goto fail;
     9         kx 		  if (! bfd_section_from_shdr (abfd, i))
     9         kx 		    goto fail;
     9         kx 		  if (elf_onesymtab (abfd) == i)
     9         kx 		    goto symtab_strtab;
     9         kx 		  if (elf_dynsymtab (abfd) == i)
     9         kx 		    goto dynsymtab_strtab;
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx       ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_REL:
     9         kx     case SHT_RELA:
     9         kx     case SHT_RELR:
     9         kx       /* *These* do a lot of work -- but build no sections!  */
     9         kx       {
     9         kx 	asection *target_sect;
     9         kx 	Elf_Internal_Shdr *hdr2, **p_hdr;
     9         kx 	unsigned int num_sec = elf_numsections (abfd);
     9         kx 	struct bfd_elf_section_data *esdt;
     9         kx 	bfd_size_type size;
     9         kx 
     9         kx 	if (hdr->sh_type == SHT_REL)
     9         kx 	  size = bed->s->sizeof_rel;
     9         kx 	else if (hdr->sh_type == SHT_RELA)
     9         kx 	  size = bed->s->sizeof_rela;
     9         kx 	else
     9         kx 	  size = bed->s->arch_size / 8;
     9         kx 	if (hdr->sh_entsize != size)
     9         kx 	  goto fail;
     9         kx 
     9         kx 	/* Check for a bogus link to avoid crashing.  */
     9         kx 	if (hdr->sh_link >= num_sec)
     9         kx 	  {
     9         kx 	    _bfd_error_handler
     9         kx 	      /* xgettext:c-format */
     9         kx 	      (_("%pB: invalid link %u for reloc section %s (index %u)"),
     9         kx 	       abfd, hdr->sh_link, name, shindex);
     9         kx 	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx 	    goto success;
     9         kx 	  }
     9         kx 
     9         kx 	/* Get the symbol table.  */
     9         kx 	if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
     9         kx 	     || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
     9         kx 	    && ! bfd_section_from_shdr (abfd, hdr->sh_link))
     9         kx 	  goto fail;
     9         kx 
     9         kx 	/* If this is an alloc section in an executable or shared
     9         kx 	   library, or the reloc section does not use the main symbol
     9         kx 	   table we don't treat it as a reloc section.  BFD can't
     9         kx 	   adequately represent such a section, so at least for now,
     9         kx 	   we don't try.  We just present it as a normal section.  We
     9         kx 	   also can't use it as a reloc section if it points to the
     9         kx 	   null section, an invalid section, another reloc section, or
     9         kx 	   its sh_link points to the null section.  */
     9         kx 	if (((abfd->flags & (DYNAMIC | EXEC_P)) != 0
     9         kx 	     && (hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx 	    || hdr->sh_type == SHT_RELR
     9         kx 	    || hdr->sh_link == SHN_UNDEF
     9         kx 	    || hdr->sh_link != elf_onesymtab (abfd)
     9         kx 	    || hdr->sh_info == SHN_UNDEF
     9         kx 	    || hdr->sh_info >= num_sec
     9         kx 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
     9         kx 	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
     9         kx 	  {
     9         kx 	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx 	    goto success;
     9         kx 	  }
     9         kx 
     9         kx 	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
     9         kx 	  goto fail;
     9         kx 
     9         kx 	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
     9         kx 	if (target_sect == NULL)
     9         kx 	  goto fail;
     9         kx 
     9         kx 	esdt = elf_section_data (target_sect);
     9         kx 	if (hdr->sh_type == SHT_RELA)
     9         kx 	  p_hdr = &esdt->rela.hdr;
     9         kx 	else
     9         kx 	  p_hdr = &esdt->rel.hdr;
     9         kx 
     9         kx 	/* PR 17512: file: 0b4f81b7.
     9         kx 	   Also see PR 24456, for a file which deliberately has two reloc
     9         kx 	   sections.  */
     9         kx 	if (*p_hdr != NULL)
     9         kx 	  {
     9         kx 	    if (!bed->init_secondary_reloc_section (abfd, hdr, name, shindex))
     9         kx 	      {
     9         kx 		_bfd_error_handler
     9         kx 		  /* xgettext:c-format */
     9         kx 		  (_("%pB: warning: secondary relocation section '%s' "
     9         kx 		     "for section %pA found - ignoring"),
     9         kx 		   abfd, name, target_sect);
     9         kx 	      }
     9         kx 	    else
     9         kx 	      esdt->has_secondary_relocs = true;
     9         kx 	    goto success;
     9         kx 	  }
     9         kx 
     9         kx 	hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
     9         kx 	if (hdr2 == NULL)
     9         kx 	  goto fail;
     9         kx 	*hdr2 = *hdr;
     9         kx 	*p_hdr = hdr2;
     9         kx 	elf_elfsections (abfd)[shindex] = hdr2;
     9         kx 	target_sect->reloc_count += (NUM_SHDR_ENTRIES (hdr)
     9         kx 				     * bed->s->int_rels_per_ext_rel);
     9         kx 	target_sect->flags |= SEC_RELOC;
     9         kx 	target_sect->relocation = NULL;
     9         kx 	target_sect->rel_filepos = hdr->sh_offset;
     9         kx 	/* In the section to which the relocations apply, mark whether
     9         kx 	   its relocations are of the REL or RELA variety.  */
     9         kx 	if (hdr->sh_size != 0)
     9         kx 	  {
     9         kx 	    if (hdr->sh_type == SHT_RELA)
     9         kx 	      target_sect->use_rela_p = 1;
     9         kx 	  }
     9         kx 	abfd->flags |= HAS_RELOC;
     9         kx 	goto success;
     9         kx       }
     9         kx 
     9         kx     case SHT_GNU_verdef:
     9         kx       if (hdr->sh_info != 0)
     9         kx 	elf_dynverdef (abfd) = shindex;
     9         kx       elf_tdata (abfd)->dynverdef_hdr = *hdr;
     9         kx       ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_GNU_versym:
     9         kx       if (hdr->sh_entsize != sizeof (Elf_External_Versym))
     9         kx 	goto fail;
     9         kx 
     9         kx       elf_dynversym (abfd) = shindex;
     9         kx       elf_tdata (abfd)->dynversym_hdr = *hdr;
     9         kx       ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_GNU_verneed:
     9         kx       if (hdr->sh_info != 0)
     9         kx 	elf_dynverref (abfd) = shindex;
     9         kx       elf_tdata (abfd)->dynverref_hdr = *hdr;
     9         kx       ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_SHLIB:
     9         kx       goto success;
     9         kx 
     9         kx     case SHT_GROUP:
     9         kx       if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE))
     9         kx 	goto fail;
     9         kx 
     9         kx       if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     9         kx 	goto fail;
     9         kx 
     9         kx       goto success;
     9         kx 
     9         kx     default:
     9         kx       /* Possibly an attributes section.  */
     9         kx       if (hdr->sh_type == SHT_GNU_ATTRIBUTES
     9         kx 	  || hdr->sh_type == bed->obj_attrs_section_type)
     9         kx 	{
     9         kx 	  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     9         kx 	    goto fail;
     9         kx 	  _bfd_elf_parse_attributes (abfd, hdr);
     9         kx 	  goto success;
     9         kx 	}
     9         kx 
     9         kx       /* Check for any processor-specific section types.  */
     9         kx       if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
     9         kx 	goto success;
     9         kx 
     9         kx       if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
     9         kx 	{
     9         kx 	  if ((hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx 	    /* FIXME: How to properly handle allocated section reserved
     9         kx 	       for applications?  */
     9         kx 	    _bfd_error_handler
     9         kx 	      /* xgettext:c-format */
     9         kx 	      (_("%pB: unknown type [%#x] section `%s'"),
     9         kx 	       abfd, hdr->sh_type, name);
     9         kx 	  else
     9         kx 	    {
     9         kx 	      /* Allow sections reserved for applications.  */
     9         kx 	      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx 	      goto success;
     9         kx 	    }
     9         kx 	}
     9         kx       else if (hdr->sh_type >= SHT_LOPROC
     9         kx 	       && hdr->sh_type <= SHT_HIPROC)
     9         kx 	/* FIXME: We should handle this section.  */
     9         kx 	_bfd_error_handler
     9         kx 	  /* xgettext:c-format */
     9         kx 	  (_("%pB: unknown type [%#x] section `%s'"),
     9         kx 	   abfd, hdr->sh_type, name);
     9         kx       else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
     9         kx 	{
     9         kx 	  /* Unrecognised OS-specific sections.  */
     9         kx 	  if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0)
     9         kx 	    /* SHF_OS_NONCONFORMING indicates that special knowledge is
     9         kx 	       required to correctly process the section and the file should
     9         kx 	       be rejected with an error message.  */
     9         kx 	    _bfd_error_handler
     9         kx 	      /* xgettext:c-format */
     9         kx 	      (_("%pB: unknown type [%#x] section `%s'"),
     9         kx 	       abfd, hdr->sh_type, name);
     9         kx 	  else
     9         kx 	    {
     9         kx 	      /* Otherwise it should be processed.  */
     9         kx 	      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx 	      goto success;
     9         kx 	    }
     9         kx 	}
     9         kx       else
     9         kx 	/* FIXME: We should handle this section.  */
     9         kx 	_bfd_error_handler
     9         kx 	  /* xgettext:c-format */
     9         kx 	  (_("%pB: unknown type [%#x] section `%s'"),
     9         kx 	   abfd, hdr->sh_type, name);
     9         kx 
     9         kx       goto fail;
     9         kx     }
     9         kx 
     9         kx  fail:
     9         kx   ret = false;
     9         kx  success:
     9         kx   elf_tdata (abfd)->being_created[shindex] = false;
     9         kx   return ret;
     9         kx }
     9         kx 
     9         kx /* Return the local symbol specified by ABFD, R_SYMNDX.  */
     9         kx 
     9         kx Elf_Internal_Sym *
     9         kx bfd_sym_from_r_symndx (struct sym_cache *cache,
     9         kx 		       bfd *abfd,
     9         kx 		       unsigned long r_symndx)
     9         kx {
     9         kx   unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
     9         kx 
     9         kx   if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
     9         kx     {
     9         kx       Elf_Internal_Shdr *symtab_hdr;
     9         kx       unsigned char esym[sizeof (Elf64_External_Sym)];
     9         kx       Elf_External_Sym_Shndx eshndx;
     9         kx 
     9         kx       symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
     9         kx       if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
     9         kx 				&cache->sym[ent], esym, &eshndx) == NULL)
     9         kx 	return NULL;
     9         kx 
     9         kx       if (cache->abfd != abfd)
     9         kx 	{
     9         kx 	  memset (cache->indx, -1, sizeof (cache->indx));
     9         kx 	  cache->abfd = abfd;
     9         kx 	}
     9         kx       cache->indx[ent] = r_symndx;
     9         kx     }
     9         kx 
     9         kx   return &cache->sym[ent];
     9         kx }
     9         kx 
     9         kx /* Given an ELF section number, retrieve the corresponding BFD
     9         kx    section.  */
     9         kx 
     9         kx asection *
     9         kx bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index)
     9         kx {
     9         kx   if (sec_index >= elf_numsections (abfd))
     9         kx     return NULL;
     9         kx   return elf_elfsections (abfd)[sec_index]->bfd_section;
     9         kx }
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_b[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
     9         kx   { NULL,		    0,	0, 0,		 0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_c[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".ctf"),	0, SHT_PROGBITS,    0 },
     9         kx   { NULL,			0, 0, 0,	    0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_d[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".data"),		-2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".data1"),	 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
     9         kx   /* There are more DWARF sections than these, but they needn't be added here
     9         kx      unless you have to cope with broken compilers that don't emit section
     9         kx      attributes or you want to help the user writing assembler.  */
     9         kx   { STRING_COMMA_LEN (".debug"),	 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".debug_line"),	 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".debug_info"),	 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".debug_abbrev"),	 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".dynamic"),	 0, SHT_DYNAMIC,  SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".dynstr"),	 0, SHT_STRTAB,	  SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".dynsym"),	 0, SHT_DYNSYM,	  SHF_ALLOC },
     9         kx   { NULL,		       0,	 0, 0,		  0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_f[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".fini"),	       0, SHT_PROGBITS,	  SHF_ALLOC + SHF_EXECINSTR },
     9         kx   { STRING_COMMA_LEN (".fini_array"), -2, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
     9         kx   { NULL,			   0 , 0, 0,		  0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_g[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".gnu.linkonce.n"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".gnu.linkonce.p"), -2, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".gnu.lto_"),	  -1, SHT_PROGBITS,    SHF_EXCLUDE },
     9         kx   { STRING_COMMA_LEN (".got"),		   0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".gnu.version"),	   0, SHT_GNU_versym,  0 },
     9         kx   { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
     9         kx   { STRING_COMMA_LEN (".gnu.version_r"),   0, SHT_GNU_verneed, 0 },
     9         kx   { STRING_COMMA_LEN (".gnu.liblist"),	   0, SHT_GNU_LIBLIST, SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".gnu.conflict"),	   0, SHT_RELA,	       SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".gnu.hash"),	   0, SHT_GNU_HASH,    SHF_ALLOC },
     9         kx   { NULL,			 0,	   0, 0,	       0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_h[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".hash"), 0, SHT_HASH,	 SHF_ALLOC },
     9         kx   { NULL,		     0, 0, 0,		 0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_i[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".init"),	       0, SHT_PROGBITS,	  SHF_ALLOC + SHF_EXECINSTR },
     9         kx   { STRING_COMMA_LEN (".init_array"), -2, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".interp"),      0, SHT_PROGBITS,	  0 },
     9         kx   { NULL,		       0,      0, 0,		  0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_l[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
     9         kx   { NULL,		     0, 0, 0,		 0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_n[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".noinit"),	 -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".note"),		 -1, SHT_NOTE,	   0 },
     9         kx   { NULL,		     0,		  0, 0,		   0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_p[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".persistent.bss"), 0, SHT_NOBITS,	SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".persistent"),	 -2, SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".preinit_array"), -2, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
     9         kx   { STRING_COMMA_LEN (".plt"),		  0, SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR },
     9         kx   { NULL,		    0,		  0, 0,			0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_r[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".relr.dyn"), 0, SHT_RELR, SHF_ALLOC },
     9         kx   { STRING_COMMA_LEN (".rela"),	  -1, SHT_RELA,	    0 },
     9         kx   { STRING_COMMA_LEN (".rel"),	  -1, SHT_REL,	    0 },
     9         kx   { NULL,		    0,	   0, 0,	    0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_s[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
     9         kx   { STRING_COMMA_LEN (".strtab"),   0, SHT_STRTAB, 0 },
     9         kx   { STRING_COMMA_LEN (".symtab"),   0, SHT_SYMTAB, 0 },
     9         kx   /* See struct bfd_elf_special_section declaration for the semantics of
     9         kx      this special case where .prefix_length != strlen (.prefix).  */
     9         kx   { ".stabstr",			5,  3, SHT_STRTAB, 0 },
     9         kx   { NULL,			0,  0, 0,	   0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_t[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".text"),	 -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
     9         kx   { STRING_COMMA_LEN (".tbss"),	 -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
     9         kx   { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
     9         kx   { NULL,		      0,  0, 0,		   0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section special_sections_z[] =
     9         kx {
     9         kx   { STRING_COMMA_LEN (".zdebug_line"),	  0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".zdebug_info"),	  0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".zdebug_abbrev"),  0, SHT_PROGBITS, 0 },
     9         kx   { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
     9         kx   { NULL,		      0,  0, 0,		   0 }
     9         kx };
     9         kx 
     9         kx static const struct bfd_elf_special_section * const special_sections[] =
     9         kx {
     9         kx   special_sections_b,		/* 'b' */
     9         kx   special_sections_c,		/* 'c' */
     9         kx   special_sections_d,		/* 'd' */
     9         kx   NULL,				/* 'e' */
     9         kx   special_sections_f,		/* 'f' */
     9         kx   special_sections_g,		/* 'g' */
     9         kx   special_sections_h,		/* 'h' */
     9         kx   special_sections_i,		/* 'i' */
     9         kx   NULL,				/* 'j' */
     9         kx   NULL,				/* 'k' */
     9         kx   special_sections_l,		/* 'l' */
     9         kx   NULL,				/* 'm' */
     9         kx   special_sections_n,		/* 'n' */
     9         kx   NULL,				/* 'o' */
     9         kx   special_sections_p,		/* 'p' */
     9         kx   NULL,				/* 'q' */
     9         kx   special_sections_r,		/* 'r' */
     9         kx   special_sections_s,		/* 's' */
     9         kx   special_sections_t,		/* 't' */
     9         kx   NULL,				/* 'u' */
     9         kx   NULL,				/* 'v' */
     9         kx   NULL,				/* 'w' */
     9         kx   NULL,				/* 'x' */
     9         kx   NULL,				/* 'y' */
     9         kx   special_sections_z		/* 'z' */
     9         kx };
     9         kx 
     9         kx const struct bfd_elf_special_section *
     9         kx _bfd_elf_get_special_section (const char *name,
     9         kx 			      const struct bfd_elf_special_section *spec,
     9         kx 			      unsigned int rela)
     9         kx {
     9         kx   int i;
     9         kx   int len;
     9         kx 
     9         kx   len = strlen (name);
     9         kx 
     9         kx   for (i = 0; spec[i].prefix != NULL; i++)
     9         kx     {
     9         kx       int suffix_len;
     9         kx       int prefix_len = spec[i].prefix_length;
     9         kx 
     9         kx       if (len < prefix_len)
     9         kx 	continue;
     9         kx       if (memcmp (name, spec[i].prefix, prefix_len) != 0)
     9         kx 	continue;
     9         kx 
     9         kx       suffix_len = spec[i].suffix_length;
     9         kx       if (suffix_len <= 0)
     9         kx 	{
     9         kx 	  if (name[prefix_len] != 0)
     9         kx 	    {
     9         kx 	      if (suffix_len == 0)
     9         kx 		continue;
     9         kx 	      if (name[prefix_len] != '.'
     9         kx 		  && (suffix_len == -2
     9         kx 		      || (rela && spec[i].type == SHT_REL)))
     9         kx 		continue;
     9         kx 	    }
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  if (len < prefix_len + suffix_len)
     9         kx 	    continue;
     9         kx 	  if (memcmp (name + len - suffix_len,
     9         kx 		      spec[i].prefix + prefix_len,
     9         kx 		      suffix_len) != 0)
     9         kx 	    continue;
     9         kx 	}
     9         kx       return &spec[i];
     9         kx     }
     9         kx 
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx const struct bfd_elf_special_section *
     9         kx _bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
     9         kx {
     9         kx   int i;
     9         kx   const struct bfd_elf_special_section *spec;
     9         kx   const struct elf_backend_data *bed;
     9         kx 
     9         kx   /* See if this is one of the special sections.  */
     9         kx   if (sec->name == NULL)
     9         kx     return NULL;
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   spec = bed->special_sections;
     9         kx   if (spec)
     9         kx     {
     9         kx       spec = _bfd_elf_get_special_section (sec->name,
     9         kx 					   bed->special_sections,
     9         kx 					   sec->use_rela_p);
     9         kx       if (spec != NULL)
     9         kx 	return spec;
     9         kx     }
     9         kx 
     9         kx   if (sec->name[0] != '.')
     9         kx     return NULL;
     9         kx 
     9         kx   i = sec->name[1] - 'b';
     9         kx   if (i < 0 || i > 'z' - 'b')
     9         kx     return NULL;
     9         kx 
     9         kx   spec = special_sections[i];
     9         kx 
     9         kx   if (spec == NULL)
     9         kx     return NULL;
     9         kx 
     9         kx   return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
     9         kx {
     9         kx   struct bfd_elf_section_data *sdata;
     9         kx   const struct elf_backend_data *bed;
     9         kx   const struct bfd_elf_special_section *ssect;
     9         kx 
     9         kx   sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
     9         kx   if (sdata == NULL)
     9         kx     {
     9         kx       sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd,
     9         kx 							  sizeof (*sdata));
     9         kx       if (sdata == NULL)
     9         kx 	return false;
     9         kx       sec->used_by_bfd = sdata;
     9         kx     }
     9         kx 
     9         kx   /* Indicate whether or not this section should use RELA relocations.  */
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   sec->use_rela_p = bed->default_use_rela_p;
     9         kx 
     9         kx   /* Set up ELF section type and flags for newly created sections, if
     9         kx      there is an ABI mandated section.  */
     9         kx   ssect = (*bed->get_sec_type_attr) (abfd, sec);
     9         kx   if (ssect != NULL)
     9         kx     {
     9         kx       elf_section_type (sec) = ssect->type;
     9         kx       elf_section_flags (sec) = ssect->attr;
     9         kx     }
     9         kx 
     9         kx   return _bfd_generic_new_section_hook (abfd, sec);
     9         kx }
     9         kx 
     9         kx /* Create a new bfd section from an ELF program header.
     9         kx 
     9         kx    Since program segments have no names, we generate a synthetic name
     9         kx    of the form segment<NUM>, where NUM is generally the index in the
     9         kx    program header table.  For segments that are split (see below) we
     9         kx    generate the names segment<NUM>a and segment<NUM>b.
     9         kx 
     9         kx    Note that some program segments may have a file size that is different than
     9         kx    (less than) the memory size.  All this means is that at execution the
     9         kx    system must allocate the amount of memory specified by the memory size,
     9         kx    but only initialize it with the first "file size" bytes read from the
     9         kx    file.  This would occur for example, with program segments consisting
     9         kx    of combined data+bss.
     9         kx 
     9         kx    To handle the above situation, this routine generates TWO bfd sections
     9         kx    for the single program segment.  The first has the length specified by
     9         kx    the file size of the segment, and the second has the length specified
     9         kx    by the difference between the two sizes.  In effect, the segment is split
     9         kx    into its initialized and uninitialized parts.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_make_section_from_phdr (bfd *abfd,
     9         kx 				 Elf_Internal_Phdr *hdr,
     9         kx 				 int hdr_index,
     9         kx 				 const char *type_name)
     9         kx {
     9         kx   asection *newsect;
     9         kx   char *name;
     9         kx   char namebuf[64];
     9         kx   size_t len;
     9         kx   int split;
     9         kx   unsigned int opb = bfd_octets_per_byte (abfd, NULL);
     9         kx 
     9         kx   split = ((hdr->p_memsz > 0)
     9         kx 	    && (hdr->p_filesz > 0)
     9         kx 	    && (hdr->p_memsz > hdr->p_filesz));
     9         kx 
     9         kx   if (hdr->p_filesz > 0)
     9         kx     {
     9         kx       sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : "");
     9         kx       len = strlen (namebuf) + 1;
     9         kx       name = (char *) bfd_alloc (abfd, len);
     9         kx       if (!name)
     9         kx 	return false;
     9         kx       memcpy (name, namebuf, len);
     9         kx       newsect = bfd_make_section (abfd, name);
     9         kx       if (newsect == NULL)
     9         kx 	return false;
     9         kx       newsect->vma = hdr->p_vaddr / opb;
     9         kx       newsect->lma = hdr->p_paddr / opb;
     9         kx       newsect->size = hdr->p_filesz;
     9         kx       newsect->filepos = hdr->p_offset;
     9         kx       newsect->flags |= SEC_HAS_CONTENTS;
     9         kx       newsect->alignment_power = bfd_log2 (hdr->p_align);
     9         kx       if (hdr->p_type == PT_LOAD)
     9         kx 	{
     9         kx 	  newsect->flags |= SEC_ALLOC;
     9         kx 	  newsect->flags |= SEC_LOAD;
     9         kx 	  if (hdr->p_flags & PF_X)
     9         kx 	    {
     9         kx 	      /* FIXME: all we known is that it has execute PERMISSION,
     9         kx 		 may be data.  */
     9         kx 	      newsect->flags |= SEC_CODE;
     9         kx 	    }
     9         kx 	}
     9         kx       if (!(hdr->p_flags & PF_W))
     9         kx 	{
     9         kx 	  newsect->flags |= SEC_READONLY;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   if (hdr->p_memsz > hdr->p_filesz)
     9         kx     {
     9         kx       bfd_vma align;
     9         kx 
     9         kx       sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : "");
     9         kx       len = strlen (namebuf) + 1;
     9         kx       name = (char *) bfd_alloc (abfd, len);
     9         kx       if (!name)
     9         kx 	return false;
     9         kx       memcpy (name, namebuf, len);
     9         kx       newsect = bfd_make_section (abfd, name);
     9         kx       if (newsect == NULL)
     9         kx 	return false;
     9         kx       newsect->vma = (hdr->p_vaddr + hdr->p_filesz) / opb;
     9         kx       newsect->lma = (hdr->p_paddr + hdr->p_filesz) / opb;
     9         kx       newsect->size = hdr->p_memsz - hdr->p_filesz;
     9         kx       newsect->filepos = hdr->p_offset + hdr->p_filesz;
     9         kx       align = newsect->vma & -newsect->vma;
     9         kx       if (align == 0 || align > hdr->p_align)
     9         kx 	align = hdr->p_align;
     9         kx       newsect->alignment_power = bfd_log2 (align);
     9         kx       if (hdr->p_type == PT_LOAD)
     9         kx 	{
     9         kx 	  newsect->flags |= SEC_ALLOC;
     9         kx 	  if (hdr->p_flags & PF_X)
     9         kx 	    newsect->flags |= SEC_CODE;
     9         kx 	}
     9         kx       if (!(hdr->p_flags & PF_W))
     9         kx 	newsect->flags |= SEC_READONLY;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx _bfd_elf_core_find_build_id (bfd *templ, bfd_vma offset)
     9         kx {
     9         kx   /* The return value is ignored.  Build-ids are considered optional.  */
     9         kx   if (templ->xvec->flavour == bfd_target_elf_flavour)
     9         kx     return (*get_elf_backend_data (templ)->elf_backend_core_find_build_id)
     9         kx       (templ, offset);
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx bool
     9         kx bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
     9         kx {
     9         kx   const struct elf_backend_data *bed;
     9         kx 
     9         kx   switch (hdr->p_type)
     9         kx     {
     9         kx     case PT_NULL:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null");
     9         kx 
     9         kx     case PT_LOAD:
     9         kx       if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load"))
     9         kx 	return false;
     9         kx       if (bfd_get_format (abfd) == bfd_core && abfd->build_id == NULL)
     9         kx 	_bfd_elf_core_find_build_id (abfd, hdr->p_offset);
     9         kx       return true;
     9         kx 
     9         kx     case PT_DYNAMIC:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic");
     9         kx 
     9         kx     case PT_INTERP:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp");
     9         kx 
     9         kx     case PT_NOTE:
     9         kx       if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
     9         kx 	return false;
     9         kx       if (! elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz,
     9         kx 			    hdr->p_align))
     9         kx 	return false;
     9         kx       return true;
     9         kx 
     9         kx     case PT_SHLIB:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib");
     9         kx 
     9         kx     case PT_PHDR:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr");
     9         kx 
     9         kx     case PT_GNU_EH_FRAME:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
     9         kx 					      "eh_frame_hdr");
     9         kx 
     9         kx     case PT_GNU_STACK:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack");
     9         kx 
     9         kx     case PT_GNU_RELRO:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro");
     9         kx 
     9         kx     case PT_GNU_SFRAME:
     9         kx       return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
     9         kx 					      "sframe");
     9         kx 
     9         kx     default:
     9         kx       /* Check for any processor-specific program segment types.  */
     9         kx       bed = get_elf_backend_data (abfd);
     9         kx       return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc");
     9         kx     }
     9         kx }
     9         kx 
     9         kx /* Return the REL_HDR for SEC, assuming there is only a single one, either
     9         kx    REL or RELA.  */
     9         kx 
     9         kx Elf_Internal_Shdr *
     9         kx _bfd_elf_single_rel_hdr (asection *sec)
     9         kx {
     9         kx   if (elf_section_data (sec)->rel.hdr)
     9         kx     {
     9         kx       BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
     9         kx       return elf_section_data (sec)->rel.hdr;
     9         kx     }
     9         kx   else
     9         kx     return elf_section_data (sec)->rela.hdr;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx _bfd_elf_set_reloc_sh_name (bfd *abfd,
     9         kx 			    Elf_Internal_Shdr *rel_hdr,
     9         kx 			    const char *sec_name,
     9         kx 			    bool use_rela_p)
     9         kx {
     9         kx   char *name = (char *) bfd_alloc (abfd,
     9         kx 				   sizeof ".rela" + strlen (sec_name));
     9         kx   if (name == NULL)
     9         kx     return false;
     9         kx 
     9         kx   sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", sec_name);
     9         kx   rel_hdr->sh_name =
     9         kx     (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
     9         kx 					false);
     9         kx   if (rel_hdr->sh_name == (unsigned int) -1)
     9         kx     return false;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Allocate and initialize a section-header for a new reloc section,
     9         kx    containing relocations against ASECT.  It is stored in RELDATA.  If
     9         kx    USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
     9         kx    relocations.  */
     9         kx 
     9         kx static bool
     9         kx _bfd_elf_init_reloc_shdr (bfd *abfd,
     9         kx 			  struct bfd_elf_section_reloc_data *reldata,
     9         kx 			  const char *sec_name,
     9         kx 			  bool use_rela_p,
     9         kx 			  bool delay_st_name_p)
     9         kx {
     9         kx   Elf_Internal_Shdr *rel_hdr;
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   BFD_ASSERT (reldata->hdr == NULL);
     9         kx   rel_hdr = bfd_zalloc (abfd, sizeof (*rel_hdr));
     9         kx   reldata->hdr = rel_hdr;
     9         kx 
     9         kx   if (delay_st_name_p)
     9         kx     rel_hdr->sh_name = (unsigned int) -1;
     9         kx   else if (!_bfd_elf_set_reloc_sh_name (abfd, rel_hdr, sec_name,
     9         kx 					use_rela_p))
     9         kx     return false;
     9         kx   rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
     9         kx   rel_hdr->sh_entsize = (use_rela_p
     9         kx 			 ? bed->s->sizeof_rela
     9         kx 			 : bed->s->sizeof_rel);
     9         kx   rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
     9         kx   rel_hdr->sh_flags = 0;
     9         kx   rel_hdr->sh_addr = 0;
     9         kx   rel_hdr->sh_size = 0;
     9         kx   rel_hdr->sh_offset = 0;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Return the default section type based on the passed in section flags.  */
     9         kx 
     9         kx int
     9         kx bfd_elf_get_default_section_type (flagword flags)
     9         kx {
     9         kx   if ((flags & (SEC_ALLOC | SEC_IS_COMMON)) != 0
     9         kx       && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
     9         kx     return SHT_NOBITS;
     9         kx   return SHT_PROGBITS;
     9         kx }
     9         kx 
     9         kx struct fake_section_arg
     9         kx {
     9         kx   struct bfd_link_info *link_info;
     9         kx   bool failed;
     9         kx };
     9         kx 
     9         kx /* Set up an ELF internal section header for a section.  */
     9         kx 
     9         kx static void
     9         kx elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
     9         kx {
     9         kx   struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   struct bfd_elf_section_data *esd = elf_section_data (asect);
     9         kx   Elf_Internal_Shdr *this_hdr;
     9         kx   unsigned int sh_type;
     9         kx   const char *name = asect->name;
     9         kx   bool delay_st_name_p = false;
     9         kx   bfd_vma mask;
     9         kx 
     9         kx   if (arg->failed)
     9         kx     {
     9         kx       /* We already failed; just get out of the bfd_map_over_sections
     9         kx 	 loop.  */
     9         kx       return;
     9         kx     }
     9         kx 
     9         kx   this_hdr = &esd->this_hdr;
     9         kx 
     9         kx   /* ld: compress DWARF debug sections with names: .debug_*.  */
     9         kx   if (arg->link_info
     9         kx       && (abfd->flags & BFD_COMPRESS) != 0
     9         kx       && (asect->flags & SEC_DEBUGGING) != 0
     9         kx       && name[1] == 'd'
     9         kx       && name[6] == '_')
     9         kx     {
     9         kx       /* If this section will be compressed, delay adding section
     9         kx 	 name to section name section after it is compressed in
     9         kx 	 _bfd_elf_assign_file_positions_for_non_load.  */
     9         kx       delay_st_name_p = true;
     9         kx     }
     9         kx 
     9         kx   if (delay_st_name_p)
     9         kx     this_hdr->sh_name = (unsigned int) -1;
     9         kx   else
     9         kx     {
     9         kx       this_hdr->sh_name
     9         kx 	= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
     9         kx 					      name, false);
     9         kx       if (this_hdr->sh_name == (unsigned int) -1)
     9         kx 	{
     9         kx 	  arg->failed = true;
     9         kx 	  return;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Don't clear sh_flags. Assembler may set additional bits.  */
     9         kx 
     9         kx   if ((asect->flags & SEC_ALLOC) != 0
     9         kx       || asect->user_set_vma)
     9         kx     this_hdr->sh_addr = asect->vma * bfd_octets_per_byte (abfd, asect);
     9         kx   else
     9         kx     this_hdr->sh_addr = 0;
     9         kx 
     9         kx   this_hdr->sh_offset = 0;
     9         kx   this_hdr->sh_size = asect->size;
     9         kx   this_hdr->sh_link = 0;
     9         kx   /* PR 17512: file: 0eb809fe, 8b0535ee.  */
     9         kx   if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
     9         kx     {
     9         kx       _bfd_error_handler
     9         kx 	/* xgettext:c-format */
     9         kx 	(_("%pB: error: alignment power %d of section `%pA' is too big"),
     9         kx 	 abfd, asect->alignment_power, asect);
     9         kx       arg->failed = true;
     9         kx       return;
     9         kx     }
     9         kx   /* Set sh_addralign to the highest power of two given by alignment
     9         kx      consistent with the section VMA.  Linker scripts can force VMA.  */
     9         kx   mask = ((bfd_vma) 1 << asect->alignment_power) | this_hdr->sh_addr;
     9         kx   this_hdr->sh_addralign = mask & -mask;
     9         kx   /* The sh_entsize and sh_info fields may have been set already by
     9         kx      copy_private_section_data.  */
     9         kx 
     9         kx   this_hdr->bfd_section = asect;
     9         kx   this_hdr->contents = NULL;
     9         kx 
     9         kx   /* If the section type is unspecified, we set it based on
     9         kx      asect->flags.  */
     9         kx   if (asect->type != 0)
     9         kx     sh_type = asect->type;
     9         kx   else if ((asect->flags & SEC_GROUP) != 0)
     9         kx     sh_type = SHT_GROUP;
     9         kx   else
     9         kx     sh_type = bfd_elf_get_default_section_type (asect->flags);
     9         kx 
     9         kx   if (this_hdr->sh_type == SHT_NULL)
     9         kx     this_hdr->sh_type = sh_type;
     9         kx   else if (this_hdr->sh_type == SHT_NOBITS
     9         kx 	   && sh_type == SHT_PROGBITS
     9         kx 	   && (asect->flags & SEC_ALLOC) != 0)
     9         kx     {
     9         kx       /* Warn if we are changing a NOBITS section to PROGBITS, but
     9         kx 	 allow the link to proceed.  This can happen when users link
     9         kx 	 non-bss input sections to bss output sections, or emit data
     9         kx 	 to a bss output section via a linker script.  */
     9         kx       _bfd_error_handler
     9         kx 	(_("warning: section `%pA' type changed to PROGBITS"), asect);
     9         kx       this_hdr->sh_type = sh_type;
     9         kx     }
     9         kx 
     9         kx   switch (this_hdr->sh_type)
     9         kx     {
     9         kx     default:
     9         kx       break;
     9         kx 
     9         kx     case SHT_STRTAB:
     9         kx     case SHT_NOTE:
     9         kx     case SHT_NOBITS:
     9         kx     case SHT_PROGBITS:
     9         kx       break;
     9         kx 
     9         kx     case SHT_INIT_ARRAY:
     9         kx     case SHT_FINI_ARRAY:
     9         kx     case SHT_PREINIT_ARRAY:
     9         kx       this_hdr->sh_entsize = bed->s->arch_size / 8;
     9         kx       break;
     9         kx 
     9         kx     case SHT_HASH:
     9         kx       this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
     9         kx       break;
     9         kx 
     9         kx     case SHT_DYNSYM:
     9         kx       this_hdr->sh_entsize = bed->s->sizeof_sym;
     9         kx       break;
     9         kx 
     9         kx     case SHT_DYNAMIC:
     9         kx       this_hdr->sh_entsize = bed->s->sizeof_dyn;
     9         kx       break;
     9         kx 
     9         kx     case SHT_RELA:
     9         kx       if (get_elf_backend_data (abfd)->may_use_rela_p)
     9         kx 	this_hdr->sh_entsize = bed->s->sizeof_rela;
     9         kx       break;
     9         kx 
     9         kx      case SHT_REL:
     9         kx       if (get_elf_backend_data (abfd)->may_use_rel_p)
     9         kx 	this_hdr->sh_entsize = bed->s->sizeof_rel;
     9         kx       break;
     9         kx 
     9         kx      case SHT_GNU_versym:
     9         kx       this_hdr->sh_entsize = sizeof (Elf_External_Versym);
     9         kx       break;
     9         kx 
     9         kx      case SHT_GNU_verdef:
     9         kx       this_hdr->sh_entsize = 0;
     9         kx       /* objcopy or strip will copy over sh_info, but may not set
     9         kx 	 cverdefs.  The linker will set cverdefs, but sh_info will be
     9         kx 	 zero.  */
     9         kx       if (this_hdr->sh_info == 0)
     9         kx 	this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
     9         kx       else
     9         kx 	BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
     9         kx 		    || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
     9         kx       break;
     9         kx 
     9         kx     case SHT_GNU_verneed:
     9         kx       this_hdr->sh_entsize = 0;
     9         kx       /* objcopy or strip will copy over sh_info, but may not set
     9         kx 	 cverrefs.  The linker will set cverrefs, but sh_info will be
     9         kx 	 zero.  */
     9         kx       if (this_hdr->sh_info == 0)
     9         kx 	this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
     9         kx       else
     9         kx 	BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
     9         kx 		    || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
     9         kx       break;
     9         kx 
     9         kx     case SHT_GROUP:
     9         kx       this_hdr->sh_entsize = GRP_ENTRY_SIZE;
     9         kx       break;
     9         kx 
     9         kx     case SHT_GNU_HASH:
     9         kx       this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
     9         kx       break;
     9         kx     }
     9         kx 
     9         kx   if ((asect->flags & SEC_ALLOC) != 0)
     9         kx     this_hdr->sh_flags |= SHF_ALLOC;
     9         kx   if ((asect->flags & SEC_READONLY) == 0)
     9         kx     this_hdr->sh_flags |= SHF_WRITE;
     9         kx   if ((asect->flags & SEC_CODE) != 0)
     9         kx     this_hdr->sh_flags |= SHF_EXECINSTR;
     9         kx   if ((asect->flags & SEC_MERGE) != 0)
     9         kx     {
     9         kx       this_hdr->sh_flags |= SHF_MERGE;
     9         kx       this_hdr->sh_entsize = asect->entsize;
     9         kx     }
     9         kx   if ((asect->flags & SEC_STRINGS) != 0)
     9         kx     this_hdr->sh_flags |= SHF_STRINGS;
     9         kx   if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
     9         kx     this_hdr->sh_flags |= SHF_GROUP;
     9         kx   if ((asect->flags & SEC_THREAD_LOCAL) != 0)
     9         kx     {
     9         kx       this_hdr->sh_flags |= SHF_TLS;
     9         kx       if (asect->size == 0
     9         kx 	  && (asect->flags & SEC_HAS_CONTENTS) == 0)
     9         kx 	{
     9         kx 	  struct bfd_link_order *o = asect->map_tail.link_order;
     9         kx 
     9         kx 	  this_hdr->sh_size = 0;
     9         kx 	  if (o != NULL)
     9         kx 	    {
     9         kx 	      this_hdr->sh_size = o->offset + o->size;
     9         kx 	      if (this_hdr->sh_size != 0)
     9         kx 		this_hdr->sh_type = SHT_NOBITS;
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx   if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
     9         kx     this_hdr->sh_flags |= SHF_EXCLUDE;
     9         kx 
     9         kx   /* If the section has relocs, set up a section header for the
     9         kx      SHT_REL[A] section.  If two relocation sections are required for
     9         kx      this section, it is up to the processor-specific back-end to
     9         kx      create the other.  */
     9         kx   if ((asect->flags & SEC_RELOC) != 0)
     9         kx     {
     9         kx       /* When doing a relocatable link, create both REL and RELA sections if
     9         kx 	 needed.  */
     9         kx       if (arg->link_info
     9         kx 	  /* Do the normal setup if we wouldn't create any sections here.  */
     9         kx 	  && esd->rel.count + esd->rela.count > 0
     9         kx 	  && (bfd_link_relocatable (arg->link_info)
     9         kx 	      || arg->link_info->emitrelocations))
     9         kx 	{
     9         kx 	  if (esd->rel.count && esd->rel.hdr == NULL
     9         kx 	      && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name,
     9         kx 					    false, delay_st_name_p))
     9         kx 	    {
     9         kx 	      arg->failed = true;
     9         kx 	      return;
     9         kx 	    }
     9         kx 	  if (esd->rela.count && esd->rela.hdr == NULL
     9         kx 	      && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name,
     9         kx 					    true, delay_st_name_p))
     9         kx 	    {
     9         kx 	      arg->failed = true;
     9         kx 	      return;
     9         kx 	    }
     9         kx 	}
     9         kx       else if (!_bfd_elf_init_reloc_shdr (abfd,
     9         kx 					  (asect->use_rela_p
     9         kx 					   ? &esd->rela : &esd->rel),
     9         kx 					  name,
     9         kx 					  asect->use_rela_p,
     9         kx 					  delay_st_name_p))
     9         kx 	{
     9         kx 	  arg->failed = true;
     9         kx 	  return;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Check for processor-specific section types.  */
     9         kx   sh_type = this_hdr->sh_type;
     9         kx   if (bed->elf_backend_fake_sections
     9         kx       && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
     9         kx     {
     9         kx       arg->failed = true;
     9         kx       return;
     9         kx     }
     9         kx 
     9         kx   if (sh_type == SHT_NOBITS && asect->size != 0)
     9         kx     {
     9         kx       /* Don't change the header type from NOBITS if we are being
     9         kx 	 called for objcopy --only-keep-debug.  */
     9         kx       this_hdr->sh_type = sh_type;
     9         kx     }
     9         kx }
     9         kx 
     9         kx /* Fill in the contents of a SHT_GROUP section.  Called from
     9         kx    _bfd_elf_compute_section_file_positions for gas, objcopy, and
     9         kx    when ELF targets use the generic linker, ld.  Called for ld -r
     9         kx    from bfd_elf_final_link.  */
     9         kx 
     9         kx void
     9         kx bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
     9         kx {
     9         kx   bool *failedptr = (bool *) failedptrarg;
     9         kx   asection *elt, *first;
     9         kx   unsigned char *loc;
     9         kx   bool gas;
     9         kx 
     9         kx   /* Ignore linker created group section.  See elfNN_ia64_object_p in
     9         kx      elfxx-ia64.c.  */
     9         kx   if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP
     9         kx       || sec->size == 0
     9         kx       || *failedptr)
     9         kx     return;
     9         kx 
     9         kx   if (elf_section_data (sec)->this_hdr.sh_info == 0)
     9         kx     {
     9         kx       unsigned long symindx = 0;
     9         kx 
     9         kx       /* elf_group_id will have been set up by objcopy and the
     9         kx 	 generic linker.  */
     9         kx       if (elf_group_id (sec) != NULL)
     9         kx 	symindx = elf_group_id (sec)->udata.i;
     9         kx 
     9         kx       if (symindx == 0)
     9         kx 	{
     9         kx 	  /* If called from the assembler, swap_out_syms will have set up
     9         kx 	     elf_section_syms.
     9         kx 	     PR 25699: A corrupt input file could contain bogus group info.  */
     9         kx 	  if (sec->index >= elf_num_section_syms (abfd)
     9         kx 	      || elf_section_syms (abfd)[sec->index] == NULL)
     9         kx 	    {
     9         kx 	      *failedptr = true;
     9         kx 	      return;
     9         kx 	    }
     9         kx 	  symindx = elf_section_syms (abfd)[sec->index]->udata.i;
     9         kx 	}
     9         kx       elf_section_data (sec)->this_hdr.sh_info = symindx;
     9         kx     }
     9         kx   else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
     9         kx     {
     9         kx       /* The ELF backend linker sets sh_info to -2 when the group
     9         kx 	 signature symbol is global, and thus the index can't be
     9         kx 	 set until all local symbols are output.  */
     9         kx       asection *igroup;
     9         kx       struct bfd_elf_section_data *sec_data;
     9         kx       unsigned long symndx;
     9         kx       unsigned long extsymoff;
     9         kx       struct elf_link_hash_entry *h;
     9         kx 
     9         kx       /* The point of this little dance to the first SHF_GROUP section
     9         kx 	 then back to the SHT_GROUP section is that this gets us to
     9         kx 	 the SHT_GROUP in the input object.  */
     9         kx       igroup = elf_sec_group (elf_next_in_group (sec));
     9         kx       sec_data = elf_section_data (igroup);
     9         kx       symndx = sec_data->this_hdr.sh_info;
     9         kx       extsymoff = 0;
     9         kx       if (!elf_bad_symtab (igroup->owner))
     9         kx 	{
     9         kx 	  Elf_Internal_Shdr *symtab_hdr;
     9         kx 
     9         kx 	  symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
     9         kx 	  extsymoff = symtab_hdr->sh_info;
     9         kx 	}
     9         kx       h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
     9         kx       while (h->root.type == bfd_link_hash_indirect
     9         kx 	     || h->root.type == bfd_link_hash_warning)
     9         kx 	h = (struct elf_link_hash_entry *) h->root.u.i.link;
     9         kx 
     9         kx       elf_section_data (sec)->this_hdr.sh_info = h->indx;
     9         kx     }
     9         kx 
     9         kx   /* The contents won't be allocated for "ld -r" or objcopy.  */
     9         kx   gas = true;
     9         kx   if (sec->contents == NULL)
     9         kx     {
     9         kx       gas = false;
     9         kx       sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);
     9         kx 
     9         kx       /* Arrange for the section to be written out.  */
     9         kx       elf_section_data (sec)->this_hdr.contents = sec->contents;
     9         kx       if (sec->contents == NULL)
     9         kx 	{
     9         kx 	  *failedptr = true;
     9         kx 	  return;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   loc = sec->contents + sec->size;
     9         kx 
     9         kx   /* Get the pointer to the first section in the group that gas
     9         kx      squirreled away here.  objcopy arranges for this to be set to the
     9         kx      start of the input section group.  */
     9         kx   first = elt = elf_next_in_group (sec);
     9         kx 
     9         kx   /* First element is a flag word.  Rest of section is elf section
     9         kx      indices for all the sections of the group.  Write them backwards
     9         kx      just to keep the group in the same order as given in .section
     9         kx      directives, not that it matters.  */
     9         kx   while (elt != NULL)
     9         kx     {
     9         kx       asection *s;
     9         kx 
     9         kx       s = elt;
     9         kx       if (!gas)
     9         kx 	s = s->output_section;
     9         kx       if (s != NULL
     9         kx 	  && !bfd_is_abs_section (s))
     9         kx 	{
     9         kx 	  struct bfd_elf_section_data *elf_sec = elf_section_data (s);
     9         kx 	  struct bfd_elf_section_data *input_elf_sec = elf_section_data (elt);
     9         kx 
     9         kx 	  if (elf_sec->rel.hdr != NULL
     9         kx 	      && (gas
     9         kx 		  || (input_elf_sec->rel.hdr != NULL
     9         kx 		      && input_elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0))
     9         kx 	    {
     9         kx 	      elf_sec->rel.hdr->sh_flags |= SHF_GROUP;
     9         kx 	      loc -= 4;
     9         kx 	      if (loc == sec->contents)
     9         kx 		break;
     9         kx 	      H_PUT_32 (abfd, elf_sec->rel.idx, loc);
     9         kx 	    }
     9         kx 	  if (elf_sec->rela.hdr != NULL
     9         kx 	      && (gas
     9         kx 		  || (input_elf_sec->rela.hdr != NULL
     9         kx 		      && input_elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0))
     9         kx 	    {
     9         kx 	      elf_sec->rela.hdr->sh_flags |= SHF_GROUP;
     9         kx 	      loc -= 4;
     9         kx 	      if (loc == sec->contents)
     9         kx 		break;
     9         kx 	      H_PUT_32 (abfd, elf_sec->rela.idx, loc);
     9         kx 	    }
     9         kx 	  loc -= 4;
     9         kx 	  if (loc == sec->contents)
     9         kx 	    break;
     9         kx 	  H_PUT_32 (abfd, elf_sec->this_idx, loc);
     9         kx 	}
     9         kx       elt = elf_next_in_group (elt);
     9         kx       if (elt == first)
     9         kx 	break;
     9         kx     }
     9         kx 
     9         kx   /* We should always get here with loc == sec->contents + 4, but it is
     9         kx      possible to craft bogus SHT_GROUP sections that will cause segfaults
     9         kx      in objcopy without checking loc here and in the loop above.  */
     9         kx   if (loc == sec->contents)
     9         kx     BFD_ASSERT (0);
     9         kx   else
     9         kx     {
     9         kx       loc -= 4;
     9         kx       if (loc != sec->contents)
     9         kx 	{
     9         kx 	  BFD_ASSERT (0);
     9         kx 	  memset (sec->contents + 4, 0, loc - sec->contents);
     9         kx 	  loc = sec->contents;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
     9         kx }
     9         kx 
     9         kx /* Given NAME, the name of a relocation section stripped of its
     9         kx    .rel/.rela prefix, return the section in ABFD to which the
     9         kx    relocations apply.  */
     9         kx 
     9         kx asection *
     9         kx _bfd_elf_plt_get_reloc_section (bfd *abfd, const char *name)
     9         kx {
     9         kx   /* If a target needs .got.plt section, relocations in rela.plt/rel.plt
     9         kx      section likely apply to .got.plt or .got section.  */
     9         kx   if (get_elf_backend_data (abfd)->want_got_plt
     9         kx       && strcmp (name, ".plt") == 0)
     9         kx     {
     9         kx       asection *sec;
     9         kx 
     9         kx       name = ".got.plt";
     9         kx       sec = bfd_get_section_by_name (abfd, name);
     9         kx       if (sec != NULL)
     9         kx 	return sec;
     9         kx       name = ".got";
     9         kx     }
     9         kx 
     9         kx   return bfd_get_section_by_name (abfd, name);
     9         kx }
     9         kx 
     9         kx /* Return the section to which RELOC_SEC applies.  */
     9         kx 
     9         kx static asection *
     9         kx elf_get_reloc_section (asection *reloc_sec)
     9         kx {
     9         kx   const char *name;
     9         kx   unsigned int type;
     9         kx   bfd *abfd;
     9         kx   const struct elf_backend_data *bed;
     9         kx 
     9         kx   type = elf_section_data (reloc_sec)->this_hdr.sh_type;
     9         kx   if (type != SHT_REL && type != SHT_RELA)
     9         kx     return NULL;
     9         kx 
     9         kx   /* We look up the section the relocs apply to by name.  */
     9         kx   name = reloc_sec->name;
     9         kx   if (!startswith (name, ".rel"))
     9         kx     return NULL;
     9         kx   name += 4;
     9         kx   if (type == SHT_RELA && *name++ != 'a')
     9         kx     return NULL;
     9         kx 
     9         kx   abfd = reloc_sec->owner;
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   return bed->get_reloc_section (abfd, name);
     9         kx }
     9         kx 
     9         kx /* Assign all ELF section numbers.  The dummy first section is handled here
     9         kx    too.  The link/info pointers for the standard section types are filled
     9         kx    in here too, while we're at it.  LINK_INFO will be 0 when arriving
     9         kx    here for gas, objcopy, and when using the generic ELF linker.  */
     9         kx 
     9         kx static bool
     9         kx assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
     9         kx {
     9         kx   struct elf_obj_tdata *t = elf_tdata (abfd);
     9         kx   asection *sec;
     9         kx   unsigned int section_number;
     9         kx   Elf_Internal_Shdr **i_shdrp;
     9         kx   struct bfd_elf_section_data *d;
     9         kx   bool need_symtab;
     9         kx   size_t amt;
     9         kx 
     9         kx   section_number = 1;
     9         kx 
     9         kx   _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
     9         kx 
     9         kx   /* SHT_GROUP sections are in relocatable files only.  */
     9         kx   if (link_info == NULL || !link_info->resolve_section_groups)
     9         kx     {
     9         kx       size_t reloc_count = 0;
     9         kx 
     9         kx       /* Put SHT_GROUP sections first.  */
     9         kx       for (sec = abfd->sections; sec != NULL; sec = sec->next)
     9         kx 	{
     9         kx 	  d = elf_section_data (sec);
     9         kx 
     9         kx 	  if (d->this_hdr.sh_type == SHT_GROUP)
     9         kx 	    {
     9         kx 	      if (sec->flags & SEC_LINKER_CREATED)
     9         kx 		{
     9         kx 		  /* Remove the linker created SHT_GROUP sections.  */
     9         kx 		  bfd_section_list_remove (abfd, sec);
     9         kx 		  abfd->section_count--;
     9         kx 		}
     9         kx 	      else
     9         kx 		d->this_idx = section_number++;
     9         kx 	    }
     9         kx 
     9         kx 	  /* Count relocations.  */
     9         kx 	  reloc_count += sec->reloc_count;
     9         kx 	}
     9         kx 
     9         kx       /* Set/clear HAS_RELOC depending on whether there are relocations.  */
     9         kx       if (reloc_count == 0)
     9         kx 	abfd->flags &= ~HAS_RELOC;
     9         kx       else
     9         kx 	abfd->flags |= HAS_RELOC;
     9         kx     }
     9         kx 
     9         kx   for (sec = abfd->sections; sec; sec = sec->next)
     9         kx     {
     9         kx       d = elf_section_data (sec);
     9         kx 
     9         kx       if (d->this_hdr.sh_type != SHT_GROUP)
     9         kx 	d->this_idx = section_number++;
     9         kx       if (d->this_hdr.sh_name != (unsigned int) -1)
     9         kx 	_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
     9         kx       if (d->rel.hdr)
     9         kx 	{
     9         kx 	  d->rel.idx = section_number++;
     9         kx 	  if (d->rel.hdr->sh_name != (unsigned int) -1)
     9         kx 	    _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
     9         kx 	}
     9         kx       else
     9         kx 	d->rel.idx = 0;
     9         kx 
     9         kx       if (d->rela.hdr)
     9         kx 	{
     9         kx 	  d->rela.idx = section_number++;
     9         kx 	  if (d->rela.hdr->sh_name != (unsigned int) -1)
     9         kx 	    _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
     9         kx 	}
     9         kx       else
     9         kx 	d->rela.idx = 0;
     9         kx     }
     9         kx 
     9         kx   need_symtab = (bfd_get_symcount (abfd) > 0
     9         kx 		 || (link_info == NULL
     9         kx 		     && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
     9         kx 			 == HAS_RELOC)));
     9         kx   if (need_symtab)
     9         kx     {
     9         kx       elf_onesymtab (abfd) = section_number++;
     9         kx       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
     9         kx       if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
     9         kx 	{
     9         kx 	  elf_section_list *entry;
     9         kx 
     9         kx 	  BFD_ASSERT (elf_symtab_shndx_list (abfd) == NULL);
     9         kx 
     9         kx 	  entry = bfd_zalloc (abfd, sizeof (*entry));
     9         kx 	  entry->ndx = section_number++;
     9         kx 	  elf_symtab_shndx_list (abfd) = entry;
     9         kx 	  entry->hdr.sh_name
     9         kx 	    = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
     9         kx 						  ".symtab_shndx", false);
     9         kx 	  if (entry->hdr.sh_name == (unsigned int) -1)
     9         kx 	    return false;
     9         kx 	}
     9         kx       elf_strtab_sec (abfd) = section_number++;
     9         kx       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
     9         kx     }
     9         kx 
     9         kx   elf_shstrtab_sec (abfd) = section_number++;
     9         kx   _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
     9         kx   elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
     9         kx 
     9         kx   if (section_number >= SHN_LORESERVE)
     9         kx     {
     9         kx       /* xgettext:c-format */
     9         kx       _bfd_error_handler (_("%pB: too many sections: %u"),
     9         kx 			  abfd, section_number);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   elf_numsections (abfd) = section_number;
     9         kx   elf_elfheader (abfd)->e_shnum = section_number;
     9         kx 
     9         kx   /* Set up the list of section header pointers, in agreement with the
     9         kx      indices.  */
     9         kx   amt = section_number * sizeof (Elf_Internal_Shdr *);
     9         kx   i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
     9         kx   if (i_shdrp == NULL)
     9         kx     return false;
     9         kx 
     9         kx   i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd,
     9         kx 						 sizeof (Elf_Internal_Shdr));
     9         kx   if (i_shdrp[0] == NULL)
     9         kx     {
     9         kx       bfd_release (abfd, i_shdrp);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   elf_elfsections (abfd) = i_shdrp;
     9         kx 
     9         kx   i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr;
     9         kx   if (need_symtab)
     9         kx     {
     9         kx       i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
     9         kx       if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
     9         kx 	{
     9         kx 	  elf_section_list * entry = elf_symtab_shndx_list (abfd);
     9         kx 	  BFD_ASSERT (entry != NULL);
     9         kx 	  i_shdrp[entry->ndx] = & entry->hdr;
     9         kx 	  entry->hdr.sh_link = elf_onesymtab (abfd);
     9         kx 	}
     9         kx       i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
     9         kx       t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
     9         kx     }
     9         kx 
     9         kx   for (sec = abfd->sections; sec; sec = sec->next)
     9         kx     {
     9         kx       asection *s;
     9         kx 
     9         kx       d = elf_section_data (sec);
     9         kx 
     9         kx       i_shdrp[d->this_idx] = &d->this_hdr;
     9         kx       if (d->rel.idx != 0)
     9         kx 	i_shdrp[d->rel.idx] = d->rel.hdr;
     9         kx       if (d->rela.idx != 0)
     9         kx 	i_shdrp[d->rela.idx] = d->rela.hdr;
     9         kx 
     9         kx       /* Fill in the sh_link and sh_info fields while we're at it.  */
     9         kx 
     9         kx       /* sh_link of a reloc section is the section index of the symbol
     9         kx 	 table.  sh_info is the section index of the section to which
     9         kx 	 the relocation entries apply.  */
     9         kx       if (d->rel.idx != 0)
     9         kx 	{
     9         kx 	  d->rel.hdr->sh_link = elf_onesymtab (abfd);
     9         kx 	  d->rel.hdr->sh_info = d->this_idx;
     9         kx 	  d->rel.hdr->sh_flags |= SHF_INFO_LINK;
     9         kx 	}
     9         kx       if (d->rela.idx != 0)
     9         kx 	{
     9         kx 	  d->rela.hdr->sh_link = elf_onesymtab (abfd);
     9         kx 	  d->rela.hdr->sh_info = d->this_idx;
     9         kx 	  d->rela.hdr->sh_flags |= SHF_INFO_LINK;
     9         kx 	}
     9         kx 
     9         kx       /* We need to set up sh_link for SHF_LINK_ORDER.  */
     9         kx       if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
     9         kx 	{
     9         kx 	  s = elf_linked_to_section (sec);
     9         kx 	  /* We can now have a NULL linked section pointer.
     9         kx 	     This happens when the sh_link field is 0, which is done
     9         kx 	     when a linked to section is discarded but the linking
     9         kx 	     section has been retained for some reason.  */
     9         kx 	  if (s)
     9         kx 	    {
     9         kx 	      /* Check discarded linkonce section.  */
     9         kx 	      if (discarded_section (s))
     9         kx 		{
     9         kx 		  asection *kept;
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB: sh_link of section `%pA' points to"
     9         kx 		       " discarded section `%pA' of `%pB'"),
     9         kx 		     abfd, d->this_hdr.bfd_section, s, s->owner);
     9         kx 		  /* Point to the kept section if it has the same
     9         kx 		     size as the discarded one.  */
     9         kx 		  kept = _bfd_elf_check_kept_section (s, link_info);
     9         kx 		  if (kept == NULL)
     9         kx 		    {
     9         kx 		      bfd_set_error (bfd_error_bad_value);
     9         kx 		      return false;
     9         kx 		    }
     9         kx 		  s = kept;
     9         kx 		}
     9         kx 	      /* Handle objcopy. */
     9         kx 	      else if (s->output_section == NULL)
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB: sh_link of section `%pA' points to"
     9         kx 		       " removed section `%pA' of `%pB'"),
     9         kx 		     abfd, d->this_hdr.bfd_section, s, s->owner);
     9         kx 		  bfd_set_error (bfd_error_bad_value);
     9         kx 		  return false;
     9         kx 		}
     9         kx 	      s = s->output_section;
     9         kx 	      d->this_hdr.sh_link = elf_section_data (s)->this_idx;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       switch (d->this_hdr.sh_type)
     9         kx 	{
     9         kx 	case SHT_REL:
     9         kx 	case SHT_RELA:
     9         kx 	  /* A reloc section which we are treating as a normal BFD
     9         kx 	     section.  sh_link is the section index of the symbol
     9         kx 	     table.  sh_info is the section index of the section to
     9         kx 	     which the relocation entries apply.  We assume that an
     9         kx 	     allocated reloc section uses the dynamic symbol table
     9         kx 	     if there is one.  Otherwise we guess the normal symbol
     9         kx 	     table.  FIXME: How can we be sure?  */
     9         kx 	  if (d->this_hdr.sh_link == 0 && (sec->flags & SEC_ALLOC) != 0)
     9         kx 	    {
     9         kx 	      s = bfd_get_section_by_name (abfd, ".dynsym");
     9         kx 	      if (s != NULL)
     9         kx 		d->this_hdr.sh_link = elf_section_data (s)->this_idx;
     9         kx 	    }
     9         kx 	  if (d->this_hdr.sh_link == 0)
     9         kx 	    d->this_hdr.sh_link = elf_onesymtab (abfd);
     9         kx 
     9         kx 	  s = elf_get_reloc_section (sec);
     9         kx 	  if (s != NULL)
     9         kx 	    {
     9         kx 	      d->this_hdr.sh_info = elf_section_data (s)->this_idx;
     9         kx 	      d->this_hdr.sh_flags |= SHF_INFO_LINK;
     9         kx 	    }
     9         kx 	  break;
     9         kx 
     9         kx 	case SHT_STRTAB:
     9         kx 	  /* We assume that a section named .stab*str is a stabs
     9         kx 	     string section.  We look for a section with the same name
     9         kx 	     but without the trailing ``str'', and set its sh_link
     9         kx 	     field to point to this section.  */
     9         kx 	  if (startswith (sec->name, ".stab")
     9         kx 	      && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
     9         kx 	    {
     9         kx 	      size_t len;
     9         kx 	      char *alc;
     9         kx 
     9         kx 	      len = strlen (sec->name);
     9         kx 	      alc = (char *) bfd_malloc (len - 2);
     9         kx 	      if (alc == NULL)
     9         kx 		return false;
     9         kx 	      memcpy (alc, sec->name, len - 3);
     9         kx 	      alc[len - 3] = '\0';
     9         kx 	      s = bfd_get_section_by_name (abfd, alc);
     9         kx 	      free (alc);
     9         kx 	      if (s != NULL)
     9         kx 		{
     9         kx 		  elf_section_data (s)->this_hdr.sh_link = d->this_idx;
     9         kx 
     9         kx 		  /* This is a .stab section.  */
     9         kx 		  elf_section_data (s)->this_hdr.sh_entsize = 12;
     9         kx 		}
     9         kx 	    }
     9         kx 	  break;
     9         kx 
     9         kx 	case SHT_DYNAMIC:
     9         kx 	case SHT_DYNSYM:
     9         kx 	case SHT_GNU_verneed:
     9         kx 	case SHT_GNU_verdef:
     9         kx 	  /* sh_link is the section header index of the string table
     9         kx 	     used for the dynamic entries, or the symbol table, or the
     9         kx 	     version strings.  */
     9         kx 	  s = bfd_get_section_by_name (abfd, ".dynstr");
     9         kx 	  if (s != NULL)
     9         kx 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
     9         kx 	  break;
     9         kx 
     9         kx 	case SHT_GNU_LIBLIST:
     9         kx 	  /* sh_link is the section header index of the prelink library
     9         kx 	     list used for the dynamic entries, or the symbol table, or
     9         kx 	     the version strings.  */
     9         kx 	  s = bfd_get_section_by_name (abfd, ((sec->flags & SEC_ALLOC)
     9         kx 					      ? ".dynstr" : ".gnu.libstr"));
     9         kx 	  if (s != NULL)
     9         kx 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
     9         kx 	  break;
     9         kx 
     9         kx 	case SHT_HASH:
     9         kx 	case SHT_GNU_HASH:
     9         kx 	case SHT_GNU_versym:
     9         kx 	  /* sh_link is the section header index of the symbol table
     9         kx 	     this hash table or version table is for.  */
     9         kx 	  s = bfd_get_section_by_name (abfd, ".dynsym");
     9         kx 	  if (s != NULL)
     9         kx 	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
     9         kx 	  break;
     9         kx 
     9         kx 	case SHT_GROUP:
     9         kx 	  d->this_hdr.sh_link = elf_onesymtab (abfd);
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Delay setting sh_name to _bfd_elf_write_object_contents so that
     9         kx      _bfd_elf_assign_file_positions_for_non_load can convert DWARF
     9         kx      debug section name from .debug_* to .zdebug_* if needed.  */
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx sym_is_global (bfd *abfd, asymbol *sym)
     9         kx {
     9         kx   /* If the backend has a special mapping, use it.  */
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   if (bed->elf_backend_sym_is_global)
     9         kx     return (*bed->elf_backend_sym_is_global) (abfd, sym);
     9         kx 
     9         kx   return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
     9         kx 	  || bfd_is_und_section (bfd_asymbol_section (sym))
     9         kx 	  || bfd_is_com_section (bfd_asymbol_section (sym)));
     9         kx }
     9         kx 
     9         kx /* Filter global symbols of ABFD to include in the import library.  All
     9         kx    SYMCOUNT symbols of ABFD can be examined from their pointers in
     9         kx    SYMS.  Pointers of symbols to keep should be stored contiguously at
     9         kx    the beginning of that array.
     9         kx 
     9         kx    Returns the number of symbols to keep.  */
     9         kx 
     9         kx unsigned int
     9         kx _bfd_elf_filter_global_symbols (bfd *abfd, struct bfd_link_info *info,
     9         kx 				asymbol **syms, long symcount)
     9         kx {
     9         kx   long src_count, dst_count = 0;
     9         kx 
     9         kx   for (src_count = 0; src_count < symcount; src_count++)
     9         kx     {
     9         kx       asymbol *sym = syms[src_count];
     9         kx       char *name = (char *) bfd_asymbol_name (sym);
     9         kx       struct bfd_link_hash_entry *h;
     9         kx 
     9         kx       if (!sym_is_global (abfd, sym))
     9         kx 	continue;
     9         kx 
     9         kx       h = bfd_link_hash_lookup (info->hash, name, false, false, false);
     9         kx       if (h == NULL)
     9         kx 	continue;
     9         kx       if (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak)
     9         kx 	continue;
     9         kx       if (h->linker_def || h->ldscript_def)
     9         kx 	continue;
     9         kx 
     9         kx       syms[dst_count++] = sym;
     9         kx     }
     9         kx 
     9         kx   syms[dst_count] = NULL;
     9         kx 
     9         kx   return dst_count;
     9         kx }
     9         kx 
     9         kx /* Don't output section symbols for sections that are not going to be
     9         kx    output, that are duplicates or there is no BFD section.  */
     9         kx 
     9         kx static bool
     9         kx ignore_section_sym (bfd *abfd, asymbol *sym)
     9         kx {
     9         kx   elf_symbol_type *type_ptr;
     9         kx 
     9         kx   if (sym == NULL)
     9         kx     return false;
     9         kx 
     9         kx   if ((sym->flags & BSF_SECTION_SYM) == 0)
     9         kx     return false;
     9         kx 
     9         kx   /* Ignore the section symbol if it isn't used.  */
     9         kx   if ((sym->flags & BSF_SECTION_SYM_USED) == 0)
     9         kx     return true;
     9         kx 
     9         kx   if (sym->section == NULL)
     9         kx     return true;
     9         kx 
     9         kx   type_ptr = elf_symbol_from (sym);
     9         kx   return ((type_ptr != NULL
     9         kx 	   && type_ptr->internal_elf_sym.st_shndx != 0
     9         kx 	   && bfd_is_abs_section (sym->section))
     9         kx 	  || !(sym->section->owner == abfd
     9         kx 	       || (sym->section->output_section != NULL
     9         kx 		   && sym->section->output_section->owner == abfd
     9         kx 		   && sym->section->output_offset == 0)
     9         kx 	       || bfd_is_abs_section (sym->section)));
     9         kx }
     9         kx 
     9         kx /* Map symbol from it's internal number to the external number, moving
     9         kx    all local symbols to be at the head of the list.  */
     9         kx 
     9         kx static bool
     9         kx elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
     9         kx {
     9         kx   unsigned int symcount = bfd_get_symcount (abfd);
     9         kx   asymbol **syms = bfd_get_outsymbols (abfd);
     9         kx   asymbol **sect_syms;
     9         kx   unsigned int num_locals = 0;
     9         kx   unsigned int num_globals = 0;
     9         kx   unsigned int num_locals2 = 0;
     9         kx   unsigned int num_globals2 = 0;
     9         kx   unsigned int max_index = 0;
     9         kx   unsigned int idx;
     9         kx   asection *asect;
     9         kx   asymbol **new_syms;
     9         kx   size_t amt;
     9         kx 
     9         kx #ifdef DEBUG
     9         kx   fprintf (stderr, "elf_map_symbols\n");
     9         kx   fflush (stderr);
     9         kx #endif
     9         kx 
     9         kx   for (asect = abfd->sections; asect; asect = asect->next)
     9         kx     {
     9         kx       if (max_index < asect->index)
     9         kx 	max_index = asect->index;
     9         kx     }
     9         kx 
     9         kx   max_index++;
     9         kx   amt = max_index * sizeof (asymbol *);
     9         kx   sect_syms = (asymbol **) bfd_zalloc (abfd, amt);
     9         kx   if (sect_syms == NULL)
     9         kx     return false;
     9         kx   elf_section_syms (abfd) = sect_syms;
     9         kx   elf_num_section_syms (abfd) = max_index;
     9         kx 
     9         kx   /* Init sect_syms entries for any section symbols we have already
     9         kx      decided to output.  */
     9         kx   for (idx = 0; idx < symcount; idx++)
     9         kx     {
     9         kx       asymbol *sym = syms[idx];
     9         kx 
     9         kx       if ((sym->flags & BSF_SECTION_SYM) != 0
     9         kx 	  && sym->value == 0
     9         kx 	  && !ignore_section_sym (abfd, sym)
     9         kx 	  && !bfd_is_abs_section (sym->section))
     9         kx 	{
     9         kx 	  asection *sec = sym->section;
     9         kx 
     9         kx 	  if (sec->owner != abfd)
     9         kx 	    sec = sec->output_section;
     9         kx 
     9         kx 	  sect_syms[sec->index] = syms[idx];
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Classify all of the symbols.  */
     9         kx   for (idx = 0; idx < symcount; idx++)
     9         kx     {
     9         kx       if (sym_is_global (abfd, syms[idx]))
     9         kx 	num_globals++;
     9         kx       else if (!ignore_section_sym (abfd, syms[idx]))
     9         kx 	num_locals++;
     9         kx     }
     9         kx 
     9         kx   /* We will be adding a section symbol for each normal BFD section.  Most
     9         kx      sections will already have a section symbol in outsymbols, but
     9         kx      eg. SHT_GROUP sections will not, and we need the section symbol mapped
     9         kx      at least in that case.  */
     9         kx   for (asect = abfd->sections; asect; asect = asect->next)
     9         kx     {
     9         kx       asymbol *sym = asect->symbol;
     9         kx       /* Don't include ignored section symbols.  */
     9         kx       if (!ignore_section_sym (abfd, sym)
     9         kx 	  && sect_syms[asect->index] == NULL)
     9         kx 	{
     9         kx 	  if (!sym_is_global (abfd, asect->symbol))
     9         kx 	    num_locals++;
     9         kx 	  else
     9         kx 	    num_globals++;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Now sort the symbols so the local symbols are first.  */
     9         kx   amt = (num_locals + num_globals) * sizeof (asymbol *);
     9         kx   new_syms = (asymbol **) bfd_alloc (abfd, amt);
     9         kx   if (new_syms == NULL)
     9         kx     return false;
     9         kx 
     9         kx   for (idx = 0; idx < symcount; idx++)
     9         kx     {
     9         kx       asymbol *sym = syms[idx];
     9         kx       unsigned int i;
     9         kx 
     9         kx       if (sym_is_global (abfd, sym))
     9         kx 	i = num_locals + num_globals2++;
     9         kx       /* Don't include ignored section symbols.  */
     9         kx       else if (!ignore_section_sym (abfd, sym))
     9         kx 	i = num_locals2++;
     9         kx       else
     9         kx 	continue;
     9         kx       new_syms[i] = sym;
     9         kx       sym->udata.i = i + 1;
     9         kx     }
     9         kx   for (asect = abfd->sections; asect; asect = asect->next)
     9         kx     {
     9         kx       asymbol *sym = asect->symbol;
     9         kx       if (!ignore_section_sym (abfd, sym)
     9         kx 	  && sect_syms[asect->index] == NULL)
     9         kx 	{
     9         kx 	  unsigned int i;
     9         kx 
     9         kx 	  sect_syms[asect->index] = sym;
     9         kx 	  if (!sym_is_global (abfd, sym))
     9         kx 	    i = num_locals2++;
     9         kx 	  else
     9         kx 	    i = num_locals + num_globals2++;
     9         kx 	  new_syms[i] = sym;
     9         kx 	  sym->udata.i = i + 1;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
     9         kx 
     9         kx   *pnum_locals = num_locals;
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Align to the maximum file alignment that could be required for any
     9         kx    ELF data structure.  */
     9         kx 
     9         kx static inline file_ptr
     9         kx align_file_position (file_ptr off, int align)
     9         kx {
     9         kx   return (off + align - 1) & ~(align - 1);
     9         kx }
     9         kx 
     9         kx /* Assign a file position to a section, optionally aligning to the
     9         kx    required section alignment.  */
     9         kx 
     9         kx file_ptr
     9         kx _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
     9         kx 					   file_ptr offset,
     9         kx 					   bool align)
     9         kx {
     9         kx   if (align && i_shdrp->sh_addralign > 1)
     9         kx     offset = BFD_ALIGN (offset, i_shdrp->sh_addralign & -i_shdrp->sh_addralign);
     9         kx   i_shdrp->sh_offset = offset;
     9         kx   if (i_shdrp->bfd_section != NULL)
     9         kx     i_shdrp->bfd_section->filepos = offset;
     9         kx   if (i_shdrp->sh_type != SHT_NOBITS)
     9         kx     offset += i_shdrp->sh_size;
     9         kx   return offset;
     9         kx }
     9         kx 
     9         kx /* Compute the file positions we are going to put the sections at, and
     9         kx    otherwise prepare to begin writing out the ELF file.  If LINK_INFO
     9         kx    is not NULL, this is being called by the ELF backend linker.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_compute_section_file_positions (bfd *abfd,
     9         kx 					 struct bfd_link_info *link_info)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   struct fake_section_arg fsargs;
     9         kx   bool failed;
     9         kx   struct elf_strtab_hash *strtab = NULL;
     9         kx   Elf_Internal_Shdr *shstrtab_hdr;
     9         kx   bool need_symtab;
     9         kx 
     9         kx   if (abfd->output_has_begun)
     9         kx     return true;
     9         kx 
     9         kx   /* Do any elf backend specific processing first.  */
     9         kx   if (bed->elf_backend_begin_write_processing)
     9         kx     (*bed->elf_backend_begin_write_processing) (abfd, link_info);
     9         kx 
     9         kx   if (!(*bed->elf_backend_init_file_header) (abfd, link_info))
     9         kx     return false;
     9         kx 
     9         kx   fsargs.failed = false;
     9         kx   fsargs.link_info = link_info;
     9         kx   bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
     9         kx   if (fsargs.failed)
     9         kx     return false;
     9         kx 
     9         kx   if (!assign_section_numbers (abfd, link_info))
     9         kx     return false;
     9         kx 
     9         kx   /* The backend linker builds symbol table information itself.  */
     9         kx   need_symtab = (link_info == NULL
     9         kx 		 && (bfd_get_symcount (abfd) > 0
     9         kx 		     || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
     9         kx 			 == HAS_RELOC)));
     9         kx   if (need_symtab)
     9         kx     {
     9         kx       /* Non-zero if doing a relocatable link.  */
     9         kx       int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));
     9         kx 
     9         kx       if (! swap_out_syms (abfd, &strtab, relocatable_p, link_info))
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   failed = false;
     9         kx   if (link_info == NULL)
     9         kx     {
     9         kx       bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
     9         kx       if (failed)
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
     9         kx   /* sh_name was set in init_file_header.  */
     9         kx   shstrtab_hdr->sh_type = SHT_STRTAB;
     9         kx   shstrtab_hdr->sh_flags = bed->elf_strtab_flags;
     9         kx   shstrtab_hdr->sh_addr = 0;
     9         kx   /* sh_size is set in _bfd_elf_assign_file_positions_for_non_load.  */
     9         kx   shstrtab_hdr->sh_entsize = 0;
     9         kx   shstrtab_hdr->sh_link = 0;
     9         kx   shstrtab_hdr->sh_info = 0;
     9         kx   /* sh_offset is set in _bfd_elf_assign_file_positions_for_non_load.  */
     9         kx   shstrtab_hdr->sh_addralign = 1;
     9         kx 
     9         kx   if (!assign_file_positions_except_relocs (abfd, link_info))
     9         kx     return false;
     9         kx 
     9         kx   if (need_symtab)
     9         kx     {
     9         kx       file_ptr off;
     9         kx       Elf_Internal_Shdr *hdr;
     9         kx 
     9         kx       off = elf_next_file_pos (abfd);
     9         kx 
     9         kx       hdr = & elf_symtab_hdr (abfd);
     9         kx       off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
     9         kx 
     9         kx       if (elf_symtab_shndx_list (abfd) != NULL)
     9         kx 	{
     9         kx 	  hdr = & elf_symtab_shndx_list (abfd)->hdr;
     9         kx 	  if (hdr->sh_size != 0)
     9         kx 	    off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
     9         kx 	  /* FIXME: What about other symtab_shndx sections in the list ?  */
     9         kx 	}
     9         kx 
     9         kx       hdr = &elf_tdata (abfd)->strtab_hdr;
     9         kx       off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
     9         kx 
     9         kx       elf_next_file_pos (abfd) = off;
     9         kx 
     9         kx       /* Now that we know where the .strtab section goes, write it
     9         kx 	 out.  */
     9         kx       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
     9         kx 	  || ! _bfd_elf_strtab_emit (abfd, strtab))
     9         kx 	return false;
     9         kx       _bfd_elf_strtab_free (strtab);
     9         kx     }
     9         kx 
     9         kx   abfd->output_has_begun = true;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Retrieve .eh_frame_hdr.  Prior to size_dynamic_sections the
     9         kx    function effectively returns whether --eh-frame-hdr is given on the
     9         kx    command line.  After size_dynamic_sections the result reflects
     9         kx    whether .eh_frame_hdr will actually be output (sizing isn't done
     9         kx    until ldemul_after_allocation).  */
     9         kx 
     9         kx static asection *
     9         kx elf_eh_frame_hdr (const struct bfd_link_info *info)
     9         kx {
     9         kx   if (info != NULL && is_elf_hash_table (info->hash))
     9         kx     return elf_hash_table (info)->eh_info.hdr_sec;
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx /* Make an initial estimate of the size of the program header.  If we
     9         kx    get the number wrong here, we'll redo section placement.  */
     9         kx 
     9         kx static bfd_size_type
     9         kx get_program_header_size (bfd *abfd, struct bfd_link_info *info)
     9         kx {
     9         kx   size_t segs;
     9         kx   asection *s;
     9         kx   const struct elf_backend_data *bed;
     9         kx 
     9         kx   /* Assume we will need exactly two PT_LOAD segments: one for text
     9         kx      and one for data.  */
     9         kx   segs = 2;
     9         kx 
     9         kx   s = bfd_get_section_by_name (abfd, ".interp");
     9         kx   if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size != 0)
     9         kx     {
     9         kx       /* If we have a loadable interpreter section, we need a
     9         kx 	 PT_INTERP segment.  In this case, assume we also need a
     9         kx 	 PT_PHDR segment, although that may not be true for all
     9         kx 	 targets.  */
     9         kx       segs += 2;
     9         kx     }
     9         kx 
     9         kx   if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
     9         kx     {
     9         kx       /* We need a PT_DYNAMIC segment.  */
     9         kx       ++segs;
     9         kx     }
     9         kx 
     9         kx   if (info != NULL && info->relro)
     9         kx     {
     9         kx       /* We need a PT_GNU_RELRO segment.  */
     9         kx       ++segs;
     9         kx     }
     9         kx 
     9         kx   if (elf_eh_frame_hdr (info))
     9         kx     {
     9         kx       /* We need a PT_GNU_EH_FRAME segment.  */
     9         kx       ++segs;
     9         kx     }
     9         kx 
     9         kx   if (elf_stack_flags (abfd))
     9         kx     {
     9         kx       /* We need a PT_GNU_STACK segment.  */
     9         kx       ++segs;
     9         kx     }
     9         kx 
     9         kx   if (elf_sframe (abfd))
     9         kx     {
     9         kx       /* We need a PT_GNU_SFRAME segment.  */
     9         kx       ++segs;
     9         kx     }
     9         kx 
     9         kx   s = bfd_get_section_by_name (abfd,
     9         kx 			       NOTE_GNU_PROPERTY_SECTION_NAME);
     9         kx   if (s != NULL && s->size != 0)
     9         kx     {
     9         kx       /* We need a PT_GNU_PROPERTY segment.  */
     9         kx       ++segs;
     9         kx     }
     9         kx 
     9         kx   for (s = abfd->sections; s != NULL; s = s->next)
     9         kx     {
     9         kx       if ((s->flags & SEC_LOAD) != 0
     9         kx 	  && elf_section_type (s) == SHT_NOTE)
     9         kx 	{
     9         kx 	  unsigned int alignment_power;
     9         kx 	  /* We need a PT_NOTE segment.  */
     9         kx 	  ++segs;
     9         kx 	  /* Try to create just one PT_NOTE segment for all adjacent
     9         kx 	     loadable SHT_NOTE sections.  gABI requires that within a
     9         kx 	     PT_NOTE segment (and also inside of each SHT_NOTE section)
     9         kx 	     each note should have the same alignment.  So we check
     9         kx 	     whether the sections are correctly aligned.  */
     9         kx 	  alignment_power = s->alignment_power;
     9         kx 	  while (s->next != NULL
     9         kx 		 && s->next->alignment_power == alignment_power
     9         kx 		 && (s->next->flags & SEC_LOAD) != 0
     9         kx 		 && elf_section_type (s->next) == SHT_NOTE)
     9         kx 	    s = s->next;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   for (s = abfd->sections; s != NULL; s = s->next)
     9         kx     {
     9         kx       if (s->flags & SEC_THREAD_LOCAL)
     9         kx 	{
     9         kx 	  /* We need a PT_TLS segment.  */
     9         kx 	  ++segs;
     9         kx 	  break;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   if ((abfd->flags & D_PAGED) != 0
     9         kx       && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
     9         kx     {
     9         kx       /* Add a PT_GNU_MBIND segment for each mbind section.  */
     9         kx       bfd_vma commonpagesize;
     9         kx       unsigned int page_align_power;
     9         kx 
     9         kx       if (info != NULL)
     9         kx 	commonpagesize = info->commonpagesize;
     9         kx       else
     9         kx 	commonpagesize = bed->commonpagesize;
     9         kx       page_align_power = bfd_log2 (commonpagesize);
     9         kx       for (s = abfd->sections; s != NULL; s = s->next)
     9         kx 	if (elf_section_flags (s) & SHF_GNU_MBIND)
     9         kx 	  {
     9         kx 	    if (elf_section_data (s)->this_hdr.sh_info > PT_GNU_MBIND_NUM)
     9         kx 	      {
     9         kx 		_bfd_error_handler
     9         kx 		  /* xgettext:c-format */
     9         kx 		  (_("%pB: GNU_MBIND section `%pA' has invalid "
     9         kx 		     "sh_info field: %d"),
     9         kx 		   abfd, s, elf_section_data (s)->this_hdr.sh_info);
     9         kx 		continue;
     9         kx 	      }
     9         kx 	    /* Align mbind section to page size.  */
     9         kx 	    if (s->alignment_power < page_align_power)
     9         kx 	      s->alignment_power = page_align_power;
     9         kx 	    segs ++;
     9         kx 	  }
     9         kx     }
     9         kx 
     9         kx   /* Let the backend count up any program headers it might need.  */
     9         kx   if (bed->elf_backend_additional_program_headers)
     9         kx     {
     9         kx       int a;
     9         kx 
     9         kx       a = (*bed->elf_backend_additional_program_headers) (abfd, info);
     9         kx       if (a == -1)
     9         kx 	abort ();
     9         kx       segs += a;
     9         kx     }
     9         kx 
     9         kx   return segs * bed->s->sizeof_phdr;
     9         kx }
     9         kx 
     9         kx /* Find the segment that contains the output_section of section.  */
     9         kx 
     9         kx Elf_Internal_Phdr *
     9         kx _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
     9         kx {
     9         kx   struct elf_segment_map *m;
     9         kx   Elf_Internal_Phdr *p;
     9         kx 
     9         kx   for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr;
     9         kx        m != NULL;
     9         kx        m = m->next, p++)
     9         kx     {
     9         kx       int i;
     9         kx 
     9         kx       for (i = m->count - 1; i >= 0; i--)
     9         kx 	if (m->sections[i] == section)
     9         kx 	  return p;
     9         kx     }
     9         kx 
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx /* Create a mapping from a set of sections to a program segment.  */
     9         kx 
     9         kx static struct elf_segment_map *
     9         kx make_mapping (bfd *abfd,
     9         kx 	      asection **sections,
     9         kx 	      unsigned int from,
     9         kx 	      unsigned int to,
     9         kx 	      bool phdr)
     9         kx {
     9         kx   struct elf_segment_map *m;
     9         kx   unsigned int i;
     9         kx   asection **hdrpp;
     9         kx   size_t amt;
     9         kx 
     9         kx   amt = sizeof (struct elf_segment_map) - sizeof (asection *);
     9         kx   amt += (to - from) * sizeof (asection *);
     9         kx   m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx   if (m == NULL)
     9         kx     return NULL;
     9         kx   m->next = NULL;
     9         kx   m->p_type = PT_LOAD;
     9         kx   for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
     9         kx     m->sections[i - from] = *hdrpp;
     9         kx   m->count = to - from;
     9         kx 
     9         kx   if (from == 0 && phdr)
     9         kx     {
     9         kx       /* Include the headers in the first PT_LOAD segment.  */
     9         kx       m->includes_filehdr = 1;
     9         kx       m->includes_phdrs = 1;
     9         kx     }
     9         kx 
     9         kx   return m;
     9         kx }
     9         kx 
     9         kx /* Create the PT_DYNAMIC segment, which includes DYNSEC.  Returns NULL
     9         kx    on failure.  */
     9         kx 
     9         kx struct elf_segment_map *
     9         kx _bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
     9         kx {
     9         kx   struct elf_segment_map *m;
     9         kx 
     9         kx   m = (struct elf_segment_map *) bfd_zalloc (abfd,
     9         kx 					     sizeof (struct elf_segment_map));
     9         kx   if (m == NULL)
     9         kx     return NULL;
     9         kx   m->next = NULL;
     9         kx   m->p_type = PT_DYNAMIC;
     9         kx   m->count = 1;
     9         kx   m->sections[0] = dynsec;
     9         kx 
     9         kx   return m;
     9         kx }
     9         kx 
     9         kx /* Possibly add or remove segments from the segment map.  */
     9         kx 
     9         kx static bool
     9         kx elf_modify_segment_map (bfd *abfd,
     9         kx 			struct bfd_link_info *info,
     9         kx 			bool remove_empty_load)
     9         kx {
     9         kx   struct elf_segment_map **m;
     9         kx   const struct elf_backend_data *bed;
     9         kx 
     9         kx   /* The placement algorithm assumes that non allocated sections are
     9         kx      not in PT_LOAD segments.  We ensure this here by removing such
     9         kx      sections from the segment map.  We also remove excluded
     9         kx      sections.  Finally, any PT_LOAD segment without sections is
     9         kx      removed.  */
     9         kx   m = &elf_seg_map (abfd);
     9         kx   while (*m)
     9         kx     {
     9         kx       unsigned int i, new_count;
     9         kx 
     9         kx       for (new_count = 0, i = 0; i < (*m)->count; i++)
     9         kx 	{
     9         kx 	  if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
     9         kx 	      && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
     9         kx 		  || (*m)->p_type != PT_LOAD))
     9         kx 	    {
     9         kx 	      (*m)->sections[new_count] = (*m)->sections[i];
     9         kx 	      new_count++;
     9         kx 	    }
     9         kx 	}
     9         kx       (*m)->count = new_count;
     9         kx 
     9         kx       if (remove_empty_load
     9         kx 	  && (*m)->p_type == PT_LOAD
     9         kx 	  && (*m)->count == 0
     9         kx 	  && !(*m)->includes_phdrs)
     9         kx 	*m = (*m)->next;
     9         kx       else
     9         kx 	m = &(*m)->next;
     9         kx     }
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   if (bed->elf_backend_modify_segment_map != NULL)
     9         kx     {
     9         kx       if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx #define IS_TBSS(s) \
     9         kx   ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL)
     9         kx 
     9         kx /* Set up a mapping from BFD sections to program segments.  Update
     9         kx    NEED_LAYOUT if the section layout is changed.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_map_sections_to_segments (bfd *abfd,
     9         kx 				   struct bfd_link_info *info,
     9         kx 				   bool *need_layout)
     9         kx {
     9         kx   unsigned int count;
     9         kx   struct elf_segment_map *m;
     9         kx   asection **sections = NULL;
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   bool no_user_phdrs;
     9         kx 
     9         kx   no_user_phdrs = elf_seg_map (abfd) == NULL;
     9         kx 
     9         kx   if (info != NULL)
     9         kx     {
     9         kx       info->user_phdrs = !no_user_phdrs;
     9         kx 
     9         kx       /* Size the relative relocations if DT_RELR is enabled.  */
     9         kx       if (info->enable_dt_relr
     9         kx 	  && need_layout != NULL
     9         kx 	  && bed->size_relative_relocs
     9         kx 	  && !bed->size_relative_relocs (info, need_layout))
     9         kx 	info->callbacks->einfo
     9         kx 	  (_("%F%P: failed to size relative relocations\n"));
     9         kx     }
     9         kx 
     9         kx   if (no_user_phdrs && bfd_count_sections (abfd) != 0)
     9         kx     {
     9         kx       asection *s;
     9         kx       unsigned int i;
     9         kx       struct elf_segment_map *mfirst;
     9         kx       struct elf_segment_map **pm;
     9         kx       asection *last_hdr;
     9         kx       bfd_vma last_size;
     9         kx       unsigned int hdr_index;
     9         kx       bfd_vma maxpagesize;
     9         kx       asection **hdrpp;
     9         kx       bool phdr_in_segment;
     9         kx       bool writable;
     9         kx       bool executable;
     9         kx       unsigned int tls_count = 0;
     9         kx       asection *first_tls = NULL;
     9         kx       asection *first_mbind = NULL;
     9         kx       asection *dynsec, *eh_frame_hdr;
     9         kx       asection *sframe;
     9         kx       size_t amt;
     9         kx       bfd_vma addr_mask, wrap_to = 0;  /* Bytes.  */
     9         kx       bfd_size_type phdr_size;  /* Octets/bytes.  */
     9         kx       unsigned int opb = bfd_octets_per_byte (abfd, NULL);
     9         kx 
     9         kx       /* Select the allocated sections, and sort them.  */
     9         kx 
     9         kx       amt = bfd_count_sections (abfd) * sizeof (asection *);
     9         kx       sections = (asection **) bfd_malloc (amt);
     9         kx       if (sections == NULL)
     9         kx 	goto error_return;
     9         kx 
     9         kx       /* Calculate top address, avoiding undefined behaviour of shift
     9         kx 	 left operator when shift count is equal to size of type
     9         kx 	 being shifted.  */
     9         kx       addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1;
     9         kx       addr_mask = (addr_mask << 1) + 1;
     9         kx 
     9         kx       i = 0;
     9         kx       for (s = abfd->sections; s != NULL; s = s->next)
     9         kx 	{
     9         kx 	  if ((s->flags & SEC_ALLOC) != 0)
     9         kx 	    {
     9         kx 	      /* target_index is unused until bfd_elf_final_link
     9         kx 		 starts output of section symbols.  Use it to make
     9         kx 		 qsort stable.  */
     9         kx 	      s->target_index = i;
     9         kx 	      sections[i] = s;
     9         kx 	      ++i;
     9         kx 	      /* A wrapping section potentially clashes with header.  */
     9         kx 	      if (((s->lma + s->size / opb) & addr_mask) < (s->lma & addr_mask))
     9         kx 		wrap_to = (s->lma + s->size / opb) & addr_mask;
     9         kx 	    }
     9         kx 	}
     9         kx       BFD_ASSERT (i <= bfd_count_sections (abfd));
     9         kx       count = i;
     9         kx 
     9         kx       qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);
     9         kx 
     9         kx       phdr_size = elf_program_header_size (abfd);
     9         kx       if (phdr_size == (bfd_size_type) -1)
     9         kx 	phdr_size = get_program_header_size (abfd, info);
     9         kx       phdr_size += bed->s->sizeof_ehdr;
     9         kx       /* phdr_size is compared to LMA values which are in bytes.  */
     9         kx       phdr_size /= opb;
     9         kx       if (info != NULL)
     9         kx 	maxpagesize = info->maxpagesize;
     9         kx       else
     9         kx 	maxpagesize = bed->maxpagesize;
     9         kx       if (maxpagesize == 0)
     9         kx 	maxpagesize = 1;
     9         kx       phdr_in_segment = info != NULL && info->load_phdrs;
     9         kx       if (count != 0
     9         kx 	  && (((sections[0]->lma & addr_mask) & (maxpagesize - 1))
     9         kx 	      >= (phdr_size & (maxpagesize - 1))))
     9         kx 	/* For compatibility with old scripts that may not be using
     9         kx 	   SIZEOF_HEADERS, add headers when it looks like space has
     9         kx 	   been left for them.  */
     9         kx 	phdr_in_segment = true;
     9         kx 
     9         kx       /* Build the mapping.  */
     9         kx       mfirst = NULL;
     9         kx       pm = &mfirst;
     9         kx 
     9         kx       /* If we have a .interp section, then create a PT_PHDR segment for
     9         kx 	 the program headers and a PT_INTERP segment for the .interp
     9         kx 	 section.  */
     9         kx       s = bfd_get_section_by_name (abfd, ".interp");
     9         kx       if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size != 0)
     9         kx 	{
     9         kx 	  amt = sizeof (struct elf_segment_map);
     9         kx 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_PHDR;
     9         kx 	  m->p_flags = PF_R;
     9         kx 	  m->p_flags_valid = 1;
     9         kx 	  m->includes_phdrs = 1;
     9         kx 	  phdr_in_segment = true;
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 
     9         kx 	  amt = sizeof (struct elf_segment_map);
     9         kx 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_INTERP;
     9         kx 	  m->count = 1;
     9         kx 	  m->sections[0] = s;
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       /* Look through the sections.  We put sections in the same program
     9         kx 	 segment when the start of the second section can be placed within
     9         kx 	 a few bytes of the end of the first section.  */
     9         kx       last_hdr = NULL;
     9         kx       last_size = 0;
     9         kx       hdr_index = 0;
     9         kx       writable = false;
     9         kx       executable = false;
     9         kx       dynsec = bfd_get_section_by_name (abfd, ".dynamic");
     9         kx       if (dynsec != NULL
     9         kx 	  && (dynsec->flags & SEC_LOAD) == 0)
     9         kx 	dynsec = NULL;
     9         kx 
     9         kx       if ((abfd->flags & D_PAGED) == 0)
     9         kx 	phdr_in_segment = false;
     9         kx 
     9         kx       /* Deal with -Ttext or something similar such that the first section
     9         kx 	 is not adjacent to the program headers.  This is an
     9         kx 	 approximation, since at this point we don't know exactly how many
     9         kx 	 program headers we will need.  */
     9         kx       if (phdr_in_segment && count > 0)
     9         kx 	{
     9         kx 	  bfd_vma phdr_lma;  /* Bytes.  */
     9         kx 	  bool separate_phdr = false;
     9         kx 
     9         kx 	  phdr_lma = (sections[0]->lma - phdr_size) & addr_mask & -maxpagesize;
     9         kx 	  if (info != NULL
     9         kx 	      && info->separate_code
     9         kx 	      && (sections[0]->flags & SEC_CODE) != 0)
     9         kx 	    {
     9         kx 	      /* If data sections should be separate from code and
     9         kx 		 thus not executable, and the first section is
     9         kx 		 executable then put the file and program headers in
     9         kx 		 their own PT_LOAD.  */
     9         kx 	      separate_phdr = true;
     9         kx 	      if ((((phdr_lma + phdr_size - 1) & addr_mask & -maxpagesize)
     9         kx 		   == (sections[0]->lma & addr_mask & -maxpagesize)))
     9         kx 		{
     9         kx 		  /* The file and program headers are currently on the
     9         kx 		     same page as the first section.  Put them on the
     9         kx 		     previous page if we can.  */
     9         kx 		  if (phdr_lma >= maxpagesize)
     9         kx 		    phdr_lma -= maxpagesize;
     9         kx 		  else
     9         kx 		    separate_phdr = false;
     9         kx 		}
     9         kx 	    }
     9         kx 	  if ((sections[0]->lma & addr_mask) < phdr_lma
     9         kx 	      || (sections[0]->lma & addr_mask) < phdr_size)
     9         kx 	    /* If file and program headers would be placed at the end
     9         kx 	       of memory then it's probably better to omit them.  */
     9         kx 	    phdr_in_segment = false;
     9         kx 	  else if (phdr_lma < wrap_to)
     9         kx 	    /* If a section wraps around to where we'll be placing
     9         kx 	       file and program headers, then the headers will be
     9         kx 	       overwritten.  */
     9         kx 	    phdr_in_segment = false;
     9         kx 	  else if (separate_phdr)
     9         kx 	    {
     9         kx 	      m = make_mapping (abfd, sections, 0, 0, phdr_in_segment);
     9         kx 	      if (m == NULL)
     9         kx 		goto error_return;
     9         kx 	      m->p_paddr = phdr_lma * opb;
     9         kx 	      m->p_vaddr_offset
     9         kx 		= (sections[0]->vma - phdr_size) & addr_mask & -maxpagesize;
     9         kx 	      m->p_paddr_valid = 1;
     9         kx 	      *pm = m;
     9         kx 	      pm = &m->next;
     9         kx 	      phdr_in_segment = false;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
     9         kx 	{
     9         kx 	  asection *hdr;
     9         kx 	  bool new_segment;
     9         kx 
     9         kx 	  hdr = *hdrpp;
     9         kx 
     9         kx 	  /* See if this section and the last one will fit in the same
     9         kx 	     segment.  */
     9         kx 
     9         kx 	  if (last_hdr == NULL)
     9         kx 	    {
     9         kx 	      /* If we don't have a segment yet, then we don't need a new
     9         kx 		 one (we build the last one after this loop).  */
     9         kx 	      new_segment = false;
     9         kx 	    }
     9         kx 	  else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
     9         kx 	    {
     9         kx 	      /* If this section has a different relation between the
     9         kx 		 virtual address and the load address, then we need a new
     9         kx 		 segment.  */
     9         kx 	      new_segment = true;
     9         kx 	    }
     9         kx 	  else if (hdr->lma < last_hdr->lma + last_size
     9         kx 		   || last_hdr->lma + last_size < last_hdr->lma)
     9         kx 	    {
     9         kx 	      /* If this section has a load address that makes it overlap
     9         kx 		 the previous section, then we need a new segment.  */
     9         kx 	      new_segment = true;
     9         kx 	    }
     9         kx 	  else if ((abfd->flags & D_PAGED) != 0
     9         kx 		   && (((last_hdr->lma + last_size - 1) & -maxpagesize)
     9         kx 		       == (hdr->lma & -maxpagesize)))
     9         kx 	    {
     9         kx 	      /* If we are demand paged then we can't map two disk
     9         kx 		 pages onto the same memory page.  */
     9         kx 	      new_segment = false;
     9         kx 	    }
     9         kx 	  /* In the next test we have to be careful when last_hdr->lma is close
     9         kx 	     to the end of the address space.  If the aligned address wraps
     9         kx 	     around to the start of the address space, then there are no more
     9         kx 	     pages left in memory and it is OK to assume that the current
     9         kx 	     section can be included in the current segment.  */
     9         kx 	  else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
     9         kx 		    + maxpagesize > last_hdr->lma)
     9         kx 		   && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
     9         kx 		       + maxpagesize <= hdr->lma))
     9         kx 	    {
     9         kx 	      /* If putting this section in this segment would force us to
     9         kx 		 skip a page in the segment, then we need a new segment.  */
     9         kx 	      new_segment = true;
     9         kx 	    }
     9         kx 	  else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
     9         kx 		   && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
     9         kx 	    {
     9         kx 	      /* We don't want to put a loaded section after a
     9         kx 		 nonloaded (ie. bss style) section in the same segment
     9         kx 		 as that will force the non-loaded section to be loaded.
     9         kx 		 Consider .tbss sections as loaded for this purpose.  */
     9         kx 	      new_segment = true;
     9         kx 	    }
     9         kx 	  else if ((abfd->flags & D_PAGED) == 0)
     9         kx 	    {
     9         kx 	      /* If the file is not demand paged, which means that we
     9         kx 		 don't require the sections to be correctly aligned in the
     9         kx 		 file, then there is no other reason for a new segment.  */
     9         kx 	      new_segment = false;
     9         kx 	    }
     9         kx 	  else if (info != NULL
     9         kx 		   && info->separate_code
     9         kx 		   && executable != ((hdr->flags & SEC_CODE) != 0))
     9         kx 	    {
     9         kx 	      new_segment = true;
     9         kx 	    }
     9         kx 	  else if (! writable
     9         kx 		   && (hdr->flags & SEC_READONLY) == 0)
     9         kx 	    {
     9         kx 	      /* We don't want to put a writable section in a read only
     9         kx 		 segment.  */
     9         kx 	      new_segment = true;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      /* Otherwise, we can use the same segment.  */
     9         kx 	      new_segment = false;
     9         kx 	    }
     9         kx 
     9         kx 	  /* Allow interested parties a chance to override our decision.  */
     9         kx 	  if (last_hdr != NULL
     9         kx 	      && info != NULL
     9         kx 	      && info->callbacks->override_segment_assignment != NULL)
     9         kx 	    new_segment
     9         kx 	      = info->callbacks->override_segment_assignment (info, abfd, hdr,
     9         kx 							      last_hdr,
     9         kx 							      new_segment);
     9         kx 
     9         kx 	  if (! new_segment)
     9         kx 	    {
     9         kx 	      if ((hdr->flags & SEC_READONLY) == 0)
     9         kx 		writable = true;
     9         kx 	      if ((hdr->flags & SEC_CODE) != 0)
     9         kx 		executable = true;
     9         kx 	      last_hdr = hdr;
     9         kx 	      /* .tbss sections effectively have zero size.  */
     9         kx 	      last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  /* We need a new program segment.  We must create a new program
     9         kx 	     header holding all the sections from hdr_index until hdr.  */
     9         kx 
     9         kx 	  m = make_mapping (abfd, sections, hdr_index, i, phdr_in_segment);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 
     9         kx 	  if ((hdr->flags & SEC_READONLY) == 0)
     9         kx 	    writable = true;
     9         kx 	  else
     9         kx 	    writable = false;
     9         kx 
     9         kx 	  if ((hdr->flags & SEC_CODE) == 0)
     9         kx 	    executable = false;
     9         kx 	  else
     9         kx 	    executable = true;
     9         kx 
     9         kx 	  last_hdr = hdr;
     9         kx 	  /* .tbss sections effectively have zero size.  */
     9         kx 	  last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
     9         kx 	  hdr_index = i;
     9         kx 	  phdr_in_segment = false;
     9         kx 	}
     9         kx 
     9         kx       /* Create a final PT_LOAD program segment, but not if it's just
     9         kx 	 for .tbss.  */
     9         kx       if (last_hdr != NULL
     9         kx 	  && (i - hdr_index != 1
     9         kx 	      || !IS_TBSS (last_hdr)))
     9         kx 	{
     9         kx 	  m = make_mapping (abfd, sections, hdr_index, i, phdr_in_segment);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       /* If there is a .dynamic section, throw in a PT_DYNAMIC segment.  */
     9         kx       if (dynsec != NULL)
     9         kx 	{
     9         kx 	  m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       /* For each batch of consecutive loadable SHT_NOTE  sections,
     9         kx 	 add a PT_NOTE segment.  We don't use bfd_get_section_by_name,
     9         kx 	 because if we link together nonloadable .note sections and
     9         kx 	 loadable .note sections, we will generate two .note sections
     9         kx 	 in the output file.  */
     9         kx       for (s = abfd->sections; s != NULL; s = s->next)
     9         kx 	{
     9         kx 	  if ((s->flags & SEC_LOAD) != 0
     9         kx 	      && elf_section_type (s) == SHT_NOTE)
     9         kx 	    {
     9         kx 	      asection *s2;
     9         kx 	      unsigned int alignment_power = s->alignment_power;
     9         kx 
     9         kx 	      count = 1;
     9         kx 	      for (s2 = s; s2->next != NULL; s2 = s2->next)
     9         kx 		{
     9         kx 		  if (s2->next->alignment_power == alignment_power
     9         kx 		      && (s2->next->flags & SEC_LOAD) != 0
     9         kx 		      && elf_section_type (s2->next) == SHT_NOTE
     9         kx 		      && align_power (s2->lma + s2->size / opb,
     9         kx 				      alignment_power)
     9         kx 		      == s2->next->lma)
     9         kx 		    count++;
     9         kx 		  else
     9         kx 		    break;
     9         kx 		}
     9         kx 	      amt = sizeof (struct elf_segment_map) - sizeof (asection *);
     9         kx 	      amt += count * sizeof (asection *);
     9         kx 	      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	      if (m == NULL)
     9         kx 		goto error_return;
     9         kx 	      m->next = NULL;
     9         kx 	      m->p_type = PT_NOTE;
     9         kx 	      m->count = count;
     9         kx 	      while (count > 1)
     9         kx 		{
     9         kx 		  m->sections[m->count - count--] = s;
     9         kx 		  BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
     9         kx 		  s = s->next;
     9         kx 		}
     9         kx 	      m->sections[m->count - 1] = s;
     9         kx 	      BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
     9         kx 	      *pm = m;
     9         kx 	      pm = &m->next;
     9         kx 	    }
     9         kx 	  if (s->flags & SEC_THREAD_LOCAL)
     9         kx 	    {
     9         kx 	      if (! tls_count)
     9         kx 		first_tls = s;
     9         kx 	      tls_count++;
     9         kx 	    }
     9         kx 	  if (first_mbind == NULL
     9         kx 	      && (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
     9         kx 	    first_mbind = s;
     9         kx 	}
     9         kx 
     9         kx       /* If there are any SHF_TLS output sections, add PT_TLS segment.  */
     9         kx       if (tls_count > 0)
     9         kx 	{
     9         kx 	  amt = sizeof (struct elf_segment_map) - sizeof (asection *);
     9         kx 	  amt += tls_count * sizeof (asection *);
     9         kx 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_TLS;
     9         kx 	  m->count = tls_count;
     9         kx 	  /* Mandated PF_R.  */
     9         kx 	  m->p_flags = PF_R;
     9         kx 	  m->p_flags_valid = 1;
     9         kx 	  s = first_tls;
     9         kx 	  for (i = 0; i < tls_count; ++i)
     9         kx 	    {
     9         kx 	      if ((s->flags & SEC_THREAD_LOCAL) == 0)
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    (_("%pB: TLS sections are not adjacent:"), abfd);
     9         kx 		  s = first_tls;
     9         kx 		  i = 0;
     9         kx 		  while (i < tls_count)
     9         kx 		    {
     9         kx 		      if ((s->flags & SEC_THREAD_LOCAL) != 0)
     9         kx 			{
     9         kx 			  _bfd_error_handler (_("	    TLS: %pA"), s);
     9         kx 			  i++;
     9         kx 			}
     9         kx 		      else
     9         kx 			_bfd_error_handler (_("	non-TLS: %pA"), s);
     9         kx 		      s = s->next;
     9         kx 		    }
     9         kx 		  bfd_set_error (bfd_error_bad_value);
     9         kx 		  goto error_return;
     9         kx 		}
     9         kx 	      m->sections[i] = s;
     9         kx 	      s = s->next;
     9         kx 	    }
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       if (first_mbind
     9         kx 	  && (abfd->flags & D_PAGED) != 0
     9         kx 	  && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
     9         kx 	for (s = first_mbind; s != NULL; s = s->next)
     9         kx 	  if ((elf_section_flags (s) & SHF_GNU_MBIND) != 0
     9         kx 	      && elf_section_data (s)->this_hdr.sh_info <= PT_GNU_MBIND_NUM)
     9         kx 	    {
     9         kx 	      /* Mandated PF_R.  */
     9         kx 	      unsigned long p_flags = PF_R;
     9         kx 	      if ((s->flags & SEC_READONLY) == 0)
     9         kx 		p_flags |= PF_W;
     9         kx 	      if ((s->flags & SEC_CODE) != 0)
     9         kx 		p_flags |= PF_X;
     9         kx 
     9         kx 	      amt = sizeof (struct elf_segment_map) + sizeof (asection *);
     9         kx 	      m = bfd_zalloc (abfd, amt);
     9         kx 	      if (m == NULL)
     9         kx 		goto error_return;
     9         kx 	      m->next = NULL;
     9         kx 	      m->p_type = (PT_GNU_MBIND_LO
     9         kx 			   + elf_section_data (s)->this_hdr.sh_info);
     9         kx 	      m->count = 1;
     9         kx 	      m->p_flags_valid = 1;
     9         kx 	      m->sections[0] = s;
     9         kx 	      m->p_flags = p_flags;
     9         kx 
     9         kx 	      *pm = m;
     9         kx 	      pm = &m->next;
     9         kx 	    }
     9         kx 
     9         kx       s = bfd_get_section_by_name (abfd,
     9         kx 				   NOTE_GNU_PROPERTY_SECTION_NAME);
     9         kx       if (s != NULL && s->size != 0)
     9         kx 	{
     9         kx 	  amt = sizeof (struct elf_segment_map) + sizeof (asection *);
     9         kx 	  m = bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_GNU_PROPERTY;
     9         kx 	  m->count = 1;
     9         kx 	  m->p_flags_valid = 1;
     9         kx 	  m->sections[0] = s;
     9         kx 	  m->p_flags = PF_R;
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
     9         kx 	 segment.  */
     9         kx       eh_frame_hdr = elf_eh_frame_hdr (info);
     9         kx       if (eh_frame_hdr != NULL
     9         kx 	  && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
     9         kx 	{
     9         kx 	  amt = sizeof (struct elf_segment_map);
     9         kx 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_GNU_EH_FRAME;
     9         kx 	  m->count = 1;
     9         kx 	  m->sections[0] = eh_frame_hdr->output_section;
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       /* If there is a .sframe section, throw in a PT_GNU_SFRAME
     9         kx 	 segment.  */
     9         kx       sframe = elf_sframe (abfd);
     9         kx       if (sframe != NULL
     9         kx 	  && (sframe->output_section->flags & SEC_LOAD) != 0
     9         kx 	  && sframe->size != 0)
     9         kx 	{
     9         kx 	  amt = sizeof (struct elf_segment_map);
     9         kx 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_GNU_SFRAME;
     9         kx 	  m->count = 1;
     9         kx 	  m->sections[0] = sframe->output_section;
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       if (elf_stack_flags (abfd))
     9         kx 	{
     9         kx 	  amt = sizeof (struct elf_segment_map);
     9         kx 	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	  if (m == NULL)
     9         kx 	    goto error_return;
     9         kx 	  m->next = NULL;
     9         kx 	  m->p_type = PT_GNU_STACK;
     9         kx 	  m->p_flags = elf_stack_flags (abfd);
     9         kx 	  m->p_align = bed->stack_align;
     9         kx 	  m->p_flags_valid = 1;
     9         kx 	  m->p_align_valid = m->p_align != 0;
     9         kx 	  if (info->stacksize > 0)
     9         kx 	    {
     9         kx 	      m->p_size = info->stacksize;
     9         kx 	      m->p_size_valid = 1;
     9         kx 	    }
     9         kx 
     9         kx 	  *pm = m;
     9         kx 	  pm = &m->next;
     9         kx 	}
     9         kx 
     9         kx       if (info != NULL && info->relro)
     9         kx 	{
     9         kx 	  for (m = mfirst; m != NULL; m = m->next)
     9         kx 	    {
     9         kx 	      if (m->p_type == PT_LOAD
     9         kx 		  && m->count != 0
     9         kx 		  && m->sections[0]->vma >= info->relro_start
     9         kx 		  && m->sections[0]->vma < info->relro_end)
     9         kx 		{
     9         kx 		  i = m->count;
     9         kx 		  while (--i != (unsigned) -1)
     9         kx 		    {
     9         kx 		      if (m->sections[i]->size > 0
     9         kx 			  && (m->sections[i]->flags & SEC_LOAD) != 0
     9         kx 			  && (m->sections[i]->flags & SEC_HAS_CONTENTS) != 0)
     9         kx 			break;
     9         kx 		    }
     9         kx 
     9         kx 		  if (i != (unsigned) -1)
     9         kx 		    break;
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
     9         kx 	  if (m != NULL)
     9         kx 	    {
     9         kx 	      amt = sizeof (struct elf_segment_map);
     9         kx 	      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
     9         kx 	      if (m == NULL)
     9         kx 		goto error_return;
     9         kx 	      m->next = NULL;
     9         kx 	      m->p_type = PT_GNU_RELRO;
     9         kx 	      *pm = m;
     9         kx 	      pm = &m->next;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       free (sections);
     9         kx       elf_seg_map (abfd) = mfirst;
     9         kx     }
     9         kx 
     9         kx   if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
     9         kx     return false;
     9         kx 
     9         kx   for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
     9         kx     ++count;
     9         kx   elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;
     9         kx 
     9         kx   return true;
     9         kx 
     9         kx  error_return:
     9         kx   free (sections);
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx /* Sort sections by address.  */
     9         kx 
     9         kx static int
     9         kx elf_sort_sections (const void *arg1, const void *arg2)
     9         kx {
     9         kx   const asection *sec1 = *(const asection **) arg1;
     9         kx   const asection *sec2 = *(const asection **) arg2;
     9         kx   bfd_size_type size1, size2;
     9         kx 
     9         kx   /* Sort by LMA first, since this is the address used to
     9         kx      place the section into a segment.  */
     9         kx   if (sec1->lma < sec2->lma)
     9         kx     return -1;
     9         kx   else if (sec1->lma > sec2->lma)
     9         kx     return 1;
     9         kx 
     9         kx   /* Then sort by VMA.  Normally the LMA and the VMA will be
     9         kx      the same, and this will do nothing.  */
     9         kx   if (sec1->vma < sec2->vma)
     9         kx     return -1;
     9         kx   else if (sec1->vma > sec2->vma)
     9         kx     return 1;
     9         kx 
     9         kx   /* Put !SEC_LOAD sections after SEC_LOAD ones.  */
     9         kx 
     9         kx #define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 \
     9         kx 		  && (x)->size != 0)
     9         kx 
     9         kx   if (TOEND (sec1))
     9         kx     {
     9         kx       if (!TOEND (sec2))
     9         kx 	return 1;
     9         kx     }
     9         kx   else if (TOEND (sec2))
     9         kx     return -1;
     9         kx 
     9         kx #undef TOEND
     9         kx 
     9         kx   /* Sort by size, to put zero sized sections
     9         kx      before others at the same address.  */
     9         kx 
     9         kx   size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
     9         kx   size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;
     9         kx 
     9         kx   if (size1 < size2)
     9         kx     return -1;
     9         kx   if (size1 > size2)
     9         kx     return 1;
     9         kx 
     9         kx   return sec1->target_index - sec2->target_index;
     9         kx }
     9         kx 
     9         kx /* This qsort comparison functions sorts PT_LOAD segments first and
     9         kx    by p_paddr, for assign_file_positions_for_load_sections.  */
     9         kx 
     9         kx static int
     9         kx elf_sort_segments (const void *arg1, const void *arg2)
     9         kx {
     9         kx   const struct elf_segment_map *m1 = *(const struct elf_segment_map **) arg1;
     9         kx   const struct elf_segment_map *m2 = *(const struct elf_segment_map **) arg2;
     9         kx 
     9         kx   if (m1->p_type != m2->p_type)
     9         kx     {
     9         kx       if (m1->p_type == PT_NULL)
     9         kx 	return 1;
     9         kx       if (m2->p_type == PT_NULL)
     9         kx 	return -1;
     9         kx       return m1->p_type < m2->p_type ? -1 : 1;
     9         kx     }
     9         kx   if (m1->includes_filehdr != m2->includes_filehdr)
     9         kx     return m1->includes_filehdr ? -1 : 1;
     9         kx   if (m1->no_sort_lma != m2->no_sort_lma)
     9         kx     return m1->no_sort_lma ? -1 : 1;
     9         kx   if (m1->p_type == PT_LOAD && !m1->no_sort_lma)
     9         kx     {
     9         kx       bfd_vma lma1, lma2;  /* Octets.  */
     9         kx       lma1 = 0;
     9         kx       if (m1->p_paddr_valid)
     9         kx 	lma1 = m1->p_paddr;
     9         kx       else if (m1->count != 0)
     9         kx 	{
     9         kx 	  unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner,
     9         kx 						  m1->sections[0]);
     9         kx 	  lma1 = (m1->sections[0]->lma + m1->p_vaddr_offset) * opb;
     9         kx 	}
     9         kx       lma2 = 0;
     9         kx       if (m2->p_paddr_valid)
     9         kx 	lma2 = m2->p_paddr;
     9         kx       else if (m2->count != 0)
     9         kx 	{
     9         kx 	  unsigned int opb = bfd_octets_per_byte (m2->sections[0]->owner,
     9         kx 						  m2->sections[0]);
     9         kx 	  lma2 = (m2->sections[0]->lma + m2->p_vaddr_offset) * opb;
     9         kx 	}
     9         kx       if (lma1 != lma2)
     9         kx 	return lma1 < lma2 ? -1 : 1;
     9         kx     }
     9         kx   if (m1->idx != m2->idx)
     9         kx     return m1->idx < m2->idx ? -1 : 1;
     9         kx   return 0;
     9         kx }
     9         kx 
     9         kx /* Ian Lance Taylor writes:
     9         kx 
     9         kx    We shouldn't be using % with a negative signed number.  That's just
     9         kx    not good.  We have to make sure either that the number is not
     9         kx    negative, or that the number has an unsigned type.  When the types
     9         kx    are all the same size they wind up as unsigned.  When file_ptr is a
     9         kx    larger signed type, the arithmetic winds up as signed long long,
     9         kx    which is wrong.
     9         kx 
     9         kx    What we're trying to say here is something like ``increase OFF by
     9         kx    the least amount that will cause it to be equal to the VMA modulo
     9         kx    the page size.''  */
     9         kx /* In other words, something like:
     9         kx 
     9         kx    vma_offset = m->sections[0]->vma % bed->maxpagesize;
     9         kx    off_offset = off % bed->maxpagesize;
     9         kx    if (vma_offset < off_offset)
     9         kx      adjustment = vma_offset + bed->maxpagesize - off_offset;
     9         kx    else
     9         kx      adjustment = vma_offset - off_offset;
     9         kx 
     9         kx    which can be collapsed into the expression below.  */
     9         kx 
     9         kx static file_ptr
     9         kx vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
     9         kx {
     9         kx   /* PR binutils/16199: Handle an alignment of zero.  */
     9         kx   if (maxpagesize == 0)
     9         kx     maxpagesize = 1;
     9         kx   return ((vma - off) % maxpagesize);
     9         kx }
     9         kx 
     9         kx static void
     9         kx print_segment_map (const struct elf_segment_map *m)
     9         kx {
     9         kx   unsigned int j;
     9         kx   const char *pt = get_segment_type (m->p_type);
     9         kx   char buf[32];
     9         kx 
     9         kx   if (pt == NULL)
     9         kx     {
     9         kx       if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC)
     9         kx 	sprintf (buf, "LOPROC+%7.7x",
     9         kx 		 (unsigned int) (m->p_type - PT_LOPROC));
     9         kx       else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS)
     9         kx 	sprintf (buf, "LOOS+%7.7x",
     9         kx 		 (unsigned int) (m->p_type - PT_LOOS));
     9         kx       else
     9         kx 	snprintf (buf, sizeof (buf), "%8.8x",
     9         kx 		  (unsigned int) m->p_type);
     9         kx       pt = buf;
     9         kx     }
     9         kx   fflush (stdout);
     9         kx   fprintf (stderr, "%s:", pt);
     9         kx   for (j = 0; j < m->count; j++)
     9         kx     fprintf (stderr, " %s", m->sections [j]->name);
     9         kx   putc ('\n',stderr);
     9         kx   fflush (stderr);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len)
     9         kx {
     9         kx   void *buf;
     9         kx   bool ret;
     9         kx 
     9         kx   if (bfd_seek (abfd, pos, SEEK_SET) != 0)
     9         kx     return false;
     9         kx   buf = bfd_zmalloc (len);
     9         kx   if (buf == NULL)
     9         kx     return false;
     9         kx   ret = bfd_bwrite (buf, len, abfd) == len;
     9         kx   free (buf);
     9         kx   return ret;
     9         kx }
     9         kx 
     9         kx /* Assign file positions to the sections based on the mapping from
     9         kx    sections to segments.  This function also sets up some fields in
     9         kx    the file header.  */
     9         kx 
     9         kx static bool
     9         kx assign_file_positions_for_load_sections (bfd *abfd,
     9         kx 					 struct bfd_link_info *link_info)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   struct elf_segment_map *m;
     9         kx   struct elf_segment_map *phdr_load_seg;
     9         kx   Elf_Internal_Phdr *phdrs;
     9         kx   Elf_Internal_Phdr *p;
     9         kx   file_ptr off;  /* Octets.  */
     9         kx   bfd_size_type maxpagesize;
     9         kx   unsigned int alloc, actual;
     9         kx   unsigned int i, j;
     9         kx   struct elf_segment_map **sorted_seg_map;
     9         kx   unsigned int opb = bfd_octets_per_byte (abfd, NULL);
     9         kx 
     9         kx   if (link_info == NULL
     9         kx       && !_bfd_elf_map_sections_to_segments (abfd, link_info, NULL))
     9         kx     return false;
     9         kx 
     9         kx   alloc = 0;
     9         kx   for (m = elf_seg_map (abfd); m != NULL; m = m->next)
     9         kx     m->idx = alloc++;
     9         kx 
     9         kx   if (alloc)
     9         kx     {
     9         kx       elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
     9         kx       elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       /* PR binutils/12467.  */
     9         kx       elf_elfheader (abfd)->e_phoff = 0;
     9         kx       elf_elfheader (abfd)->e_phentsize = 0;
     9         kx     }
     9         kx 
     9         kx   elf_elfheader (abfd)->e_phnum = alloc;
     9         kx 
     9         kx   if (elf_program_header_size (abfd) == (bfd_size_type) -1)
     9         kx     {
     9         kx       actual = alloc;
     9         kx       elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr;
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       actual = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
     9         kx       BFD_ASSERT (elf_program_header_size (abfd)
     9         kx 		  == actual * bed->s->sizeof_phdr);
     9         kx       BFD_ASSERT (actual >= alloc);
     9         kx     }
     9         kx 
     9         kx   if (alloc == 0)
     9         kx     {
     9         kx       elf_next_file_pos (abfd) = bed->s->sizeof_ehdr;
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   /* We're writing the size in elf_program_header_size (abfd),
     9         kx      see assign_file_positions_except_relocs, so make sure we have
     9         kx      that amount allocated, with trailing space cleared.
     9         kx      The variable alloc contains the computed need, while
     9         kx      elf_program_header_size (abfd) contains the size used for the
     9         kx      layout.
     9         kx      See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
     9         kx      where the layout is forced to according to a larger size in the
     9         kx      last iterations for the testcase ld-elf/header.  */
     9         kx   phdrs = bfd_zalloc (abfd, (actual * sizeof (*phdrs)
     9         kx 			     + alloc * sizeof (*sorted_seg_map)));
     9         kx   sorted_seg_map = (struct elf_segment_map **) (phdrs + actual);
     9         kx   elf_tdata (abfd)->phdr = phdrs;
     9         kx   if (phdrs == NULL)
     9         kx     return false;
     9         kx 
     9         kx   for (m = elf_seg_map (abfd), j = 0; m != NULL; m = m->next, j++)
     9         kx     {
     9         kx       sorted_seg_map[j] = m;
     9         kx       /* If elf_segment_map is not from map_sections_to_segments, the
     9         kx 	 sections may not be correctly ordered.  NOTE: sorting should
     9         kx 	 not be done to the PT_NOTE section of a corefile, which may
     9         kx 	 contain several pseudo-sections artificially created by bfd.
     9         kx 	 Sorting these pseudo-sections breaks things badly.  */
     9         kx       if (m->count > 1
     9         kx 	  && !(elf_elfheader (abfd)->e_type == ET_CORE
     9         kx 	       && m->p_type == PT_NOTE))
     9         kx 	{
     9         kx 	  for (i = 0; i < m->count; i++)
     9         kx 	    m->sections[i]->target_index = i;
     9         kx 	  qsort (m->sections, (size_t) m->count, sizeof (asection *),
     9         kx 		 elf_sort_sections);
     9         kx 	}
     9         kx     }
     9         kx   if (alloc > 1)
     9         kx     qsort (sorted_seg_map, alloc, sizeof (*sorted_seg_map),
     9         kx 	   elf_sort_segments);
     9         kx 
     9         kx   maxpagesize = 1;
     9         kx   if ((abfd->flags & D_PAGED) != 0)
     9         kx     {
     9         kx       if (link_info != NULL)
     9         kx 	maxpagesize = link_info->maxpagesize;
     9         kx       else
     9         kx 	maxpagesize = bed->maxpagesize;
     9         kx     }
     9         kx 
     9         kx   /* Sections must map to file offsets past the ELF file header.  */
     9         kx   off = bed->s->sizeof_ehdr;
     9         kx   /* And if one of the PT_LOAD headers doesn't include the program
     9         kx      headers then we'll be mapping program headers in the usual
     9         kx      position after the ELF file header.  */
     9         kx   phdr_load_seg = NULL;
     9         kx   for (j = 0; j < alloc; j++)
     9         kx     {
     9         kx       m = sorted_seg_map[j];
     9         kx       if (m->p_type != PT_LOAD)
     9         kx 	break;
     9         kx       if (m->includes_phdrs)
     9         kx 	{
     9         kx 	  phdr_load_seg = m;
     9         kx 	  break;
     9         kx 	}
     9         kx     }
     9         kx   if (phdr_load_seg == NULL)
     9         kx     off += actual * bed->s->sizeof_phdr;
     9         kx 
     9         kx   for (j = 0; j < alloc; j++)
     9         kx     {
     9         kx       asection **secpp;
     9         kx       bfd_vma off_adjust;  /* Octets.  */
     9         kx       bool no_contents;
     9         kx       bfd_size_type p_align;
     9         kx       bool p_align_p;
     9         kx 
     9         kx       /* An ELF segment (described by Elf_Internal_Phdr) may contain a
     9         kx 	 number of sections with contents contributing to both p_filesz
     9         kx 	 and p_memsz, followed by a number of sections with no contents
     9         kx 	 that just contribute to p_memsz.  In this loop, OFF tracks next
     9         kx 	 available file offset for PT_LOAD and PT_NOTE segments.  */
     9         kx       m = sorted_seg_map[j];
     9         kx       p = phdrs + m->idx;
     9         kx       p->p_type = m->p_type;
     9         kx       p->p_flags = m->p_flags;
     9         kx       p_align = bed->p_align;
     9         kx       p_align_p = false;
     9         kx 
     9         kx       if (m->count == 0)
     9         kx 	p->p_vaddr = m->p_vaddr_offset * opb;
     9         kx       else
     9         kx 	p->p_vaddr = (m->sections[0]->vma + m->p_vaddr_offset) * opb;
     9         kx 
     9         kx       if (m->p_paddr_valid)
     9         kx 	p->p_paddr = m->p_paddr;
     9         kx       else if (m->count == 0)
     9         kx 	p->p_paddr = 0;
     9         kx       else
     9         kx 	p->p_paddr = (m->sections[0]->lma + m->p_vaddr_offset) * opb;
     9         kx 
     9         kx       if (p->p_type == PT_LOAD
     9         kx 	  && (abfd->flags & D_PAGED) != 0)
     9         kx 	{
     9         kx 	  /* p_align in demand paged PT_LOAD segments effectively stores
     9         kx 	     the maximum page size.  When copying an executable with
     9         kx 	     objcopy, we set m->p_align from the input file.  Use this
     9         kx 	     value for maxpagesize rather than bed->maxpagesize, which
     9         kx 	     may be different.  Note that we use maxpagesize for PT_TLS
     9         kx 	     segment alignment later in this function, so we are relying
     9         kx 	     on at least one PT_LOAD segment appearing before a PT_TLS
     9         kx 	     segment.  */
     9         kx 	  if (m->p_align_valid)
     9         kx 	    maxpagesize = m->p_align;
     9         kx 	  else if (p_align != 0
     9         kx 		   && (link_info == NULL
     9         kx 		       || !link_info->maxpagesize_is_set))
     9         kx 	    /* Set p_align to the default p_align value while laying
     9         kx 	       out segments aligning to the maximum page size or the
     9         kx 	       largest section alignment.  The run-time loader can
     9         kx 	       align segments to the default p_align value or the
     9         kx 	       maximum page size, depending on system page size.  */
     9         kx 	    p_align_p = true;
     9         kx 
     9         kx 	  p->p_align = maxpagesize;
     9         kx 	}
     9         kx       else if (m->p_align_valid)
     9         kx 	p->p_align = m->p_align;
     9         kx       else if (m->count == 0)
     9         kx 	p->p_align = 1 << bed->s->log_file_align;
     9         kx 
     9         kx       if (m == phdr_load_seg)
     9         kx 	{
     9         kx 	  if (!m->includes_filehdr)
     9         kx 	    p->p_offset = off;
     9         kx 	  off += actual * bed->s->sizeof_phdr;
     9         kx 	}
     9         kx 
     9         kx       no_contents = false;
     9         kx       off_adjust = 0;
     9         kx       if (p->p_type == PT_LOAD
     9         kx 	  && m->count > 0)
     9         kx 	{
     9         kx 	  bfd_size_type align;  /* Bytes.  */
     9         kx 	  unsigned int align_power = 0;
     9         kx 
     9         kx 	  if (m->p_align_valid)
     9         kx 	    align = p->p_align;
     9         kx 	  else
     9         kx 	    {
     9         kx 	      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
     9         kx 		{
     9         kx 		  unsigned int secalign;
     9         kx 
     9         kx 		  secalign = bfd_section_alignment (*secpp);
     9         kx 		  if (secalign > align_power)
     9         kx 		    align_power = secalign;
     9         kx 		}
     9         kx 	      align = (bfd_size_type) 1 << align_power;
     9         kx 	      if (align < maxpagesize)
     9         kx 		{
     9         kx 		  /* If a section requires alignment higher than the
     9         kx 		     default p_align value, don't set p_align to the
     9         kx 		     default p_align value.  */
     9         kx 		  if (align > p_align)
     9         kx 		    p_align_p = false;
     9         kx 		  align = maxpagesize;
     9         kx 		}
     9         kx 	      else
     9         kx 		{
     9         kx 		  /* If a section requires alignment higher than the
     9         kx 		     maximum page size, set p_align to the section
     9         kx 		     alignment.  */
     9         kx 		  p_align_p = true;
     9         kx 		  p_align = align;
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  for (i = 0; i < m->count; i++)
     9         kx 	    if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
     9         kx 	      /* If we aren't making room for this section, then
     9         kx 		 it must be SHT_NOBITS regardless of what we've
     9         kx 		 set via struct bfd_elf_special_section.  */
     9         kx 	      elf_section_type (m->sections[i]) = SHT_NOBITS;
     9         kx 
     9         kx 	  /* Find out whether this segment contains any loadable
     9         kx 	     sections.  */
     9         kx 	  no_contents = true;
     9         kx 	  for (i = 0; i < m->count; i++)
     9         kx 	    if (elf_section_type (m->sections[i]) != SHT_NOBITS)
     9         kx 	      {
     9         kx 		no_contents = false;
     9         kx 		break;
     9         kx 	      }
     9         kx 
     9         kx 	  off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align * opb);
     9         kx 
     9         kx 	  /* Broken hardware and/or kernel require that files do not
     9         kx 	     map the same page with different permissions on some hppa
     9         kx 	     processors.  */
     9         kx 	  if (j != 0
     9         kx 	      && (abfd->flags & D_PAGED) != 0
     9         kx 	      && bed->no_page_alias
     9         kx 	      && (off & (maxpagesize - 1)) != 0
     9         kx 	      && ((off & -maxpagesize)
     9         kx 		  == ((off + off_adjust) & -maxpagesize)))
     9         kx 	    off_adjust += maxpagesize;
     9         kx 	  off += off_adjust;
     9         kx 	  if (no_contents)
     9         kx 	    {
     9         kx 	      /* We shouldn't need to align the segment on disk since
     9         kx 		 the segment doesn't need file space, but the gABI
     9         kx 		 arguably requires the alignment and glibc ld.so
     9         kx 		 checks it.  So to comply with the alignment
     9         kx 		 requirement but not waste file space, we adjust
     9         kx 		 p_offset for just this segment.  (OFF_ADJUST is
     9         kx 		 subtracted from OFF later.)  This may put p_offset
     9         kx 		 past the end of file, but that shouldn't matter.  */
     9         kx 	    }
     9         kx 	  else
     9         kx 	    off_adjust = 0;
     9         kx 	}
     9         kx       /* Make sure the .dynamic section is the first section in the
     9         kx 	 PT_DYNAMIC segment.  */
     9         kx       else if (p->p_type == PT_DYNAMIC
     9         kx 	       && m->count > 1
     9         kx 	       && strcmp (m->sections[0]->name, ".dynamic") != 0)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    (_("%pB: The first section in the PT_DYNAMIC segment"
     9         kx 	       " is not the .dynamic section"),
     9         kx 	     abfd);
     9         kx 	  bfd_set_error (bfd_error_bad_value);
     9         kx 	  return false;
     9         kx 	}
     9         kx       /* Set the note section type to SHT_NOTE.  */
     9         kx       else if (p->p_type == PT_NOTE)
     9         kx 	for (i = 0; i < m->count; i++)
     9         kx 	  elf_section_type (m->sections[i]) = SHT_NOTE;
     9         kx 
     9         kx       if (m->includes_filehdr)
     9         kx 	{
     9         kx 	  if (!m->p_flags_valid)
     9         kx 	    p->p_flags |= PF_R;
     9         kx 	  p->p_filesz = bed->s->sizeof_ehdr;
     9         kx 	  p->p_memsz = bed->s->sizeof_ehdr;
     9         kx 	  if (p->p_type == PT_LOAD)
     9         kx 	    {
     9         kx 	      if (m->count > 0)
     9         kx 		{
     9         kx 		  if (p->p_vaddr < (bfd_vma) off
     9         kx 		      || (!m->p_paddr_valid
     9         kx 			  && p->p_paddr < (bfd_vma) off))
     9         kx 		    {
     9         kx 		      _bfd_error_handler
     9         kx 			(_("%pB: not enough room for program headers,"
     9         kx 			   " try linking with -N"),
     9         kx 			 abfd);
     9         kx 		      bfd_set_error (bfd_error_bad_value);
     9         kx 		      return false;
     9         kx 		    }
     9         kx 		  p->p_vaddr -= off;
     9         kx 		  if (!m->p_paddr_valid)
     9         kx 		    p->p_paddr -= off;
     9         kx 		}
     9         kx 	    }
     9         kx 	  else if (sorted_seg_map[0]->includes_filehdr)
     9         kx 	    {
     9         kx 	      Elf_Internal_Phdr *filehdr = phdrs + sorted_seg_map[0]->idx;
     9         kx 	      p->p_vaddr = filehdr->p_vaddr;
     9         kx 	      if (!m->p_paddr_valid)
     9         kx 		p->p_paddr = filehdr->p_paddr;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (m->includes_phdrs)
     9         kx 	{
     9         kx 	  if (!m->p_flags_valid)
     9         kx 	    p->p_flags |= PF_R;
     9         kx 	  p->p_filesz += actual * bed->s->sizeof_phdr;
     9         kx 	  p->p_memsz += actual * bed->s->sizeof_phdr;
     9         kx 	  if (!m->includes_filehdr)
     9         kx 	    {
     9         kx 	      if (p->p_type == PT_LOAD)
     9         kx 		{
     9         kx 		  elf_elfheader (abfd)->e_phoff = p->p_offset;
     9         kx 		  if (m->count > 0)
     9         kx 		    {
     9         kx 		      p->p_vaddr -= off - p->p_offset;
     9         kx 		      if (!m->p_paddr_valid)
     9         kx 			p->p_paddr -= off - p->p_offset;
     9         kx 		    }
     9         kx 		}
     9         kx 	      else if (phdr_load_seg != NULL)
     9         kx 		{
     9         kx 		  Elf_Internal_Phdr *phdr = phdrs + phdr_load_seg->idx;
     9         kx 		  bfd_vma phdr_off = 0;  /* Octets.  */
     9         kx 		  if (phdr_load_seg->includes_filehdr)
     9         kx 		    phdr_off = bed->s->sizeof_ehdr;
     9         kx 		  p->p_vaddr = phdr->p_vaddr + phdr_off;
     9         kx 		  if (!m->p_paddr_valid)
     9         kx 		    p->p_paddr = phdr->p_paddr + phdr_off;
     9         kx 		  p->p_offset = phdr->p_offset + phdr_off;
     9         kx 		}
     9         kx 	      else
     9         kx 		p->p_offset = bed->s->sizeof_ehdr;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (p->p_type == PT_LOAD
     9         kx 	  || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
     9         kx 	{
     9         kx 	  if (!m->includes_filehdr && !m->includes_phdrs)
     9         kx 	    {
     9         kx 	      p->p_offset = off;
     9         kx 	      if (no_contents)
     9         kx 		{
     9         kx 		  /* Put meaningless p_offset for PT_LOAD segments
     9         kx 		     without file contents somewhere within the first
     9         kx 		     page, in an attempt to not point past EOF.  */
     9         kx 		  bfd_size_type align = maxpagesize;
     9         kx 		  if (align < p->p_align)
     9         kx 		    align = p->p_align;
     9         kx 		  if (align < 1)
     9         kx 		    align = 1;
     9         kx 		  p->p_offset = off % align;
     9         kx 		}
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      file_ptr adjust;  /* Octets.  */
     9         kx 
     9         kx 	      adjust = off - (p->p_offset + p->p_filesz);
     9         kx 	      if (!no_contents)
     9         kx 		p->p_filesz += adjust;
     9         kx 	      p->p_memsz += adjust;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       /* Set up p_filesz, p_memsz, p_align and p_flags from the section
     9         kx 	 maps.  Set filepos for sections in PT_LOAD segments, and in
     9         kx 	 core files, for sections in PT_NOTE segments.
     9         kx 	 assign_file_positions_for_non_load_sections will set filepos
     9         kx 	 for other sections and update p_filesz for other segments.  */
     9         kx       for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
     9         kx 	{
     9         kx 	  asection *sec;
     9         kx 	  bfd_size_type align;
     9         kx 	  Elf_Internal_Shdr *this_hdr;
     9         kx 
     9         kx 	  sec = *secpp;
     9         kx 	  this_hdr = &elf_section_data (sec)->this_hdr;
     9         kx 	  align = (bfd_size_type) 1 << bfd_section_alignment (sec);
     9         kx 
     9         kx 	  if ((p->p_type == PT_LOAD
     9         kx 	       || p->p_type == PT_TLS)
     9         kx 	      && (this_hdr->sh_type != SHT_NOBITS
     9         kx 		  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
     9         kx 		      && ((this_hdr->sh_flags & SHF_TLS) == 0
     9         kx 			  || p->p_type == PT_TLS))))
     9         kx 	    {
     9         kx 	      bfd_vma p_start = p->p_paddr;		/* Octets.  */
     9         kx 	      bfd_vma p_end = p_start + p->p_memsz;	/* Octets.  */
     9         kx 	      bfd_vma s_start = sec->lma * opb;		/* Octets.  */
     9         kx 	      bfd_vma adjust = s_start - p_end;		/* Octets.  */
     9         kx 
     9         kx 	      if (adjust != 0
     9         kx 		  && (s_start < p_end
     9         kx 		      || p_end < p_start))
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB: section %pA lma %#" PRIx64
     9         kx 		       " adjusted to %#" PRIx64),
     9         kx 		     abfd, sec, (uint64_t) s_start / opb,
     9         kx 		     (uint64_t) p_end / opb);
     9         kx 		  adjust = 0;
     9         kx 		  sec->lma = p_end / opb;
     9         kx 		}
     9         kx 	      p->p_memsz += adjust;
     9         kx 
     9         kx 	      if (p->p_type == PT_LOAD)
     9         kx 		{
     9         kx 		  if (this_hdr->sh_type != SHT_NOBITS)
     9         kx 		    {
     9         kx 		      off_adjust = 0;
     9         kx 		      if (p->p_filesz + adjust < p->p_memsz)
     9         kx 			{
     9         kx 			  /* We have a PROGBITS section following NOBITS ones.
     9         kx 			     Allocate file space for the NOBITS section(s) and
     9         kx 			     zero it.  */
     9         kx 			  adjust = p->p_memsz - p->p_filesz;
     9         kx 			  if (!write_zeros (abfd, off, adjust))
     9         kx 			    return false;
     9         kx 			}
     9         kx 		    }
     9         kx 		  /* We only adjust sh_offset in SHT_NOBITS sections
     9         kx 		     as would seem proper for their address when the
     9         kx 		     section is first in the segment.  sh_offset
     9         kx 		     doesn't really have any significance for
     9         kx 		     SHT_NOBITS anyway, apart from a notional position
     9         kx 		     relative to other sections.  Historically we
     9         kx 		     didn't bother with adjusting sh_offset and some
     9         kx 		     programs depend on it not being adjusted.  See
     9         kx 		     pr12921 and pr25662.  */
     9         kx 		  if (this_hdr->sh_type != SHT_NOBITS || i == 0)
     9         kx 		    {
     9         kx 		      off += adjust;
     9         kx 		      if (this_hdr->sh_type == SHT_NOBITS)
     9         kx 			off_adjust += adjust;
     9         kx 		    }
     9         kx 		}
     9         kx 	      if (this_hdr->sh_type != SHT_NOBITS)
     9         kx 		p->p_filesz += adjust;
     9         kx 	    }
     9         kx 
     9         kx 	  if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
     9         kx 	    {
     9         kx 	      /* The section at i == 0 is the one that actually contains
     9         kx 		 everything.  */
     9         kx 	      if (i == 0)
     9         kx 		{
     9         kx 		  this_hdr->sh_offset = sec->filepos = off;
     9         kx 		  off += this_hdr->sh_size;
     9         kx 		  p->p_filesz = this_hdr->sh_size;
     9         kx 		  p->p_memsz = 0;
     9         kx 		  p->p_align = 1;
     9         kx 		}
     9         kx 	      else
     9         kx 		{
     9         kx 		  /* The rest are fake sections that shouldn't be written.  */
     9         kx 		  sec->filepos = 0;
     9         kx 		  sec->size = 0;
     9         kx 		  sec->flags = 0;
     9         kx 		  continue;
     9         kx 		}
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      if (p->p_type == PT_LOAD)
     9         kx 		{
     9         kx 		  this_hdr->sh_offset = sec->filepos = off;
     9         kx 		  if (this_hdr->sh_type != SHT_NOBITS)
     9         kx 		    off += this_hdr->sh_size;
     9         kx 		}
     9         kx 	      else if (this_hdr->sh_type == SHT_NOBITS
     9         kx 		       && (this_hdr->sh_flags & SHF_TLS) != 0
     9         kx 		       && this_hdr->sh_offset == 0)
     9         kx 		{
     9         kx 		  /* This is a .tbss section that didn't get a PT_LOAD.
     9         kx 		     (See _bfd_elf_map_sections_to_segments "Create a
     9         kx 		     final PT_LOAD".)  Set sh_offset to the value it
     9         kx 		     would have if we had created a zero p_filesz and
     9         kx 		     p_memsz PT_LOAD header for the section.  This
     9         kx 		     also makes the PT_TLS header have the same
     9         kx 		     p_offset value.  */
     9         kx 		  bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
     9         kx 							  off, align);
     9         kx 		  this_hdr->sh_offset = sec->filepos = off + adjust;
     9         kx 		}
     9         kx 
     9         kx 	      if (this_hdr->sh_type != SHT_NOBITS)
     9         kx 		{
     9         kx 		  p->p_filesz += this_hdr->sh_size;
     9         kx 		  /* A load section without SHF_ALLOC is something like
     9         kx 		     a note section in a PT_NOTE segment.  These take
     9         kx 		     file space but are not loaded into memory.  */
     9         kx 		  if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx 		    p->p_memsz += this_hdr->sh_size;
     9         kx 		}
     9         kx 	      else if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx 		{
     9         kx 		  if (p->p_type == PT_TLS)
     9         kx 		    p->p_memsz += this_hdr->sh_size;
     9         kx 
     9         kx 		  /* .tbss is special.  It doesn't contribute to p_memsz of
     9         kx 		     normal segments.  */
     9         kx 		  else if ((this_hdr->sh_flags & SHF_TLS) == 0)
     9         kx 		    p->p_memsz += this_hdr->sh_size;
     9         kx 		}
     9         kx 
     9         kx 	      if (align > p->p_align
     9         kx 		  && !m->p_align_valid
     9         kx 		  && (p->p_type != PT_LOAD
     9         kx 		      || (abfd->flags & D_PAGED) == 0))
     9         kx 		p->p_align = align;
     9         kx 	    }
     9         kx 
     9         kx 	  if (!m->p_flags_valid)
     9         kx 	    {
     9         kx 	      p->p_flags |= PF_R;
     9         kx 	      if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
     9         kx 		p->p_flags |= PF_X;
     9         kx 	      if ((this_hdr->sh_flags & SHF_WRITE) != 0)
     9         kx 		p->p_flags |= PF_W;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       off -= off_adjust;
     9         kx 
     9         kx       /* PR ld/20815 - Check that the program header segment, if
     9         kx 	 present, will be loaded into memory.  */
     9         kx       if (p->p_type == PT_PHDR
     9         kx 	  && phdr_load_seg == NULL
     9         kx 	  && !(bed->elf_backend_allow_non_load_phdr != NULL
     9         kx 	       && bed->elf_backend_allow_non_load_phdr (abfd, phdrs, alloc)))
     9         kx 	{
     9         kx 	  /* The fix for this error is usually to edit the linker script being
     9         kx 	     used and set up the program headers manually.  Either that or
     9         kx 	     leave room for the headers at the start of the SECTIONS.  */
     9         kx 	  _bfd_error_handler (_("%pB: error: PHDR segment not covered"
     9         kx 				" by LOAD segment"),
     9         kx 			      abfd);
     9         kx 	  if (link_info == NULL)
     9         kx 	    return false;
     9         kx 	  /* Arrange for the linker to exit with an error, deleting
     9         kx 	     the output file unless --noinhibit-exec is given.  */
     9         kx 	  link_info->callbacks->info ("%X");
     9         kx 	}
     9         kx 
     9         kx       /* Check that all sections are in a PT_LOAD segment.
     9         kx 	 Don't check funky gdb generated core files.  */
     9         kx       if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core)
     9         kx 	{
     9         kx 	  bool check_vma = true;
     9         kx 
     9         kx 	  for (i = 1; i < m->count; i++)
     9         kx 	    if (m->sections[i]->vma == m->sections[i - 1]->vma
     9         kx 		&& ELF_SECTION_SIZE (&(elf_section_data (m->sections[i])
     9         kx 				       ->this_hdr), p) != 0
     9         kx 		&& ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1])
     9         kx 				       ->this_hdr), p) != 0)
     9         kx 	      {
     9         kx 		/* Looks like we have overlays packed into the segment.  */
     9         kx 		check_vma = false;
     9         kx 		break;
     9         kx 	      }
     9         kx 
     9         kx 	  for (i = 0; i < m->count; i++)
     9         kx 	    {
     9         kx 	      Elf_Internal_Shdr *this_hdr;
     9         kx 	      asection *sec;
     9         kx 
     9         kx 	      sec = m->sections[i];
     9         kx 	      this_hdr = &(elf_section_data(sec)->this_hdr);
     9         kx 	      if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
     9         kx 		  && !ELF_TBSS_SPECIAL (this_hdr, p))
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB: section `%pA' can't be allocated in segment %d"),
     9         kx 		     abfd, sec, j);
     9         kx 		  print_segment_map (m);
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  if (p_align_p)
     9         kx 	    p->p_align = p_align;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   elf_next_file_pos (abfd) = off;
     9         kx 
     9         kx   if (link_info != NULL
     9         kx       && phdr_load_seg != NULL
     9         kx       && phdr_load_seg->includes_filehdr)
     9         kx     {
     9         kx       /* There is a segment that contains both the file headers and the
     9         kx 	 program headers, so provide a symbol __ehdr_start pointing there.
     9         kx 	 A program can use this to examine itself robustly.  */
     9         kx 
     9         kx       struct elf_link_hash_entry *hash
     9         kx 	= elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
     9         kx 				false, false, true);
     9         kx       /* If the symbol was referenced and not defined, define it.  */
     9         kx       if (hash != NULL
     9         kx 	  && (hash->root.type == bfd_link_hash_new
     9         kx 	      || hash->root.type == bfd_link_hash_undefined
     9         kx 	      || hash->root.type == bfd_link_hash_undefweak
     9         kx 	      || hash->root.type == bfd_link_hash_common))
     9         kx 	{
     9         kx 	  asection *s = NULL;
     9         kx 	  bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr / opb;
     9         kx 
     9         kx 	  if (phdr_load_seg->count != 0)
     9         kx 	    /* The segment contains sections, so use the first one.  */
     9         kx 	    s = phdr_load_seg->sections[0];
     9         kx 	  else
     9         kx 	    /* Use the first (i.e. lowest-addressed) section in any segment.  */
     9         kx 	    for (m = elf_seg_map (abfd); m != NULL; m = m->next)
     9         kx 	      if (m->p_type == PT_LOAD && m->count != 0)
     9         kx 		{
     9         kx 		  s = m->sections[0];
     9         kx 		  break;
     9         kx 		}
     9         kx 
     9         kx 	  if (s != NULL)
     9         kx 	    {
     9         kx 	      hash->root.u.def.value = filehdr_vaddr - s->vma;
     9         kx 	      hash->root.u.def.section = s;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      hash->root.u.def.value = filehdr_vaddr;
     9         kx 	      hash->root.u.def.section = bfd_abs_section_ptr;
     9         kx 	    }
     9         kx 
     9         kx 	  hash->root.type = bfd_link_hash_defined;
     9         kx 	  hash->def_regular = 1;
     9         kx 	  hash->non_elf = 0;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Determine if a bfd is a debuginfo file.  Unfortunately there
     9         kx    is no defined method for detecting such files, so we have to
     9         kx    use heuristics instead.  */
     9         kx 
     9         kx bool
     9         kx is_debuginfo_file (bfd *abfd)
     9         kx {
     9         kx   if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
     9         kx     return false;
     9         kx 
     9         kx   Elf_Internal_Shdr **start_headers = elf_elfsections (abfd);
     9         kx   Elf_Internal_Shdr **end_headers = start_headers + elf_numsections (abfd);
     9         kx   Elf_Internal_Shdr **headerp;
     9         kx 
     9         kx   for (headerp = start_headers; headerp < end_headers; headerp ++)
     9         kx     {
     9         kx       Elf_Internal_Shdr *header = * headerp;
     9         kx 
     9         kx       /* Debuginfo files do not have any allocated SHT_PROGBITS sections.
     9         kx 	 The only allocated sections are SHT_NOBITS or SHT_NOTES.  */
     9         kx       if ((header->sh_flags & SHF_ALLOC) == SHF_ALLOC
     9         kx 	  && header->sh_type != SHT_NOBITS
     9         kx 	  && header->sh_type != SHT_NOTE)
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Assign file positions for other sections, except for compressed debug
     9         kx    and sections assigned in _bfd_elf_assign_file_positions_for_non_load.  */
     9         kx 
     9         kx static bool
     9         kx assign_file_positions_for_non_load_sections (bfd *abfd,
     9         kx 					     struct bfd_link_info *link_info)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   Elf_Internal_Shdr **i_shdrpp;
     9         kx   Elf_Internal_Shdr **hdrpp, **end_hdrpp;
     9         kx   Elf_Internal_Phdr *phdrs;
     9         kx   Elf_Internal_Phdr *p;
     9         kx   struct elf_segment_map *m;
     9         kx   file_ptr off;
     9         kx   unsigned int opb = bfd_octets_per_byte (abfd, NULL);
     9         kx   bfd_vma maxpagesize;
     9         kx 
     9         kx   if (link_info != NULL)
     9         kx     maxpagesize = link_info->maxpagesize;
     9         kx   else
     9         kx     maxpagesize = bed->maxpagesize;
     9         kx   i_shdrpp = elf_elfsections (abfd);
     9         kx   end_hdrpp = i_shdrpp + elf_numsections (abfd);
     9         kx   off = elf_next_file_pos (abfd);
     9         kx   for (hdrpp = i_shdrpp + 1; hdrpp < end_hdrpp; hdrpp++)
     9         kx     {
     9         kx       Elf_Internal_Shdr *hdr;
     9         kx       bfd_vma align;
     9         kx 
     9         kx       hdr = *hdrpp;
     9         kx       if (hdr->bfd_section != NULL
     9         kx 	  && (hdr->bfd_section->filepos != 0
     9         kx 	      || (hdr->sh_type == SHT_NOBITS
     9         kx 		  && hdr->contents == NULL)))
     9         kx 	BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
     9         kx       else if ((hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx 	{
     9         kx 	  if (hdr->sh_size != 0
     9         kx 	      /* PR 24717 - debuginfo files are known to be not strictly
     9         kx 		 compliant with the ELF standard.  In particular they often
     9         kx 		 have .note.gnu.property sections that are outside of any
     9         kx 		 loadable segment.  This is not a problem for such files,
     9         kx 		 so do not warn about them.  */
     9         kx 	      && ! is_debuginfo_file (abfd))
     9         kx 	    _bfd_error_handler
     9         kx 	      /* xgettext:c-format */
     9         kx 	      (_("%pB: warning: allocated section `%s' not in segment"),
     9         kx 	       abfd,
     9         kx 	       (hdr->bfd_section == NULL
     9         kx 		? "*unknown*"
     9         kx 		: hdr->bfd_section->name));
     9         kx 	  /* We don't need to page align empty sections.  */
     9         kx 	  if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
     9         kx 	    align = maxpagesize;
     9         kx 	  else
     9         kx 	    align = hdr->sh_addralign & -hdr->sh_addralign;
     9         kx 	  off += vma_page_aligned_bias (hdr->sh_addr, off, align);
     9         kx 	  off = _bfd_elf_assign_file_position_for_section (hdr, off,
     9         kx 							   false);
     9         kx 	}
     9         kx       else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
     9         kx 		&& hdr->bfd_section == NULL)
     9         kx 	       /* We don't know the offset of these sections yet:
     9         kx 		  their size has not been decided.  */
     9         kx 	       || (abfd->is_linker_output
     9         kx 		   && hdr->bfd_section != NULL
     9         kx 		   && (hdr->sh_name == -1u
     9         kx 		       || bfd_section_is_ctf (hdr->bfd_section)))
     9         kx 	       || hdr == i_shdrpp[elf_onesymtab (abfd)]
     9         kx 	       || (elf_symtab_shndx_list (abfd) != NULL
     9         kx 		   && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
     9         kx 	       || hdr == i_shdrpp[elf_strtab_sec (abfd)]
     9         kx 	       || hdr == i_shdrpp[elf_shstrtab_sec (abfd)])
     9         kx 	hdr->sh_offset = -1;
     9         kx       else
     9         kx 	off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
     9         kx     }
     9         kx   elf_next_file_pos (abfd) = off;
     9         kx 
     9         kx   /* Now that we have set the section file positions, we can set up
     9         kx      the file positions for the non PT_LOAD segments.  */
     9         kx   phdrs = elf_tdata (abfd)->phdr;
     9         kx   for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
     9         kx     {
     9         kx       if (p->p_type == PT_GNU_RELRO)
     9         kx 	{
     9         kx 	  bfd_vma start, end;  /* Bytes.  */
     9         kx 	  bool ok;
     9         kx 
     9         kx 	  if (link_info != NULL)
     9         kx 	    {
     9         kx 	      /* During linking the range of the RELRO segment is passed
     9         kx 		 in link_info.  Note that there may be padding between
     9         kx 		 relro_start and the first RELRO section.  */
     9         kx 	      start = link_info->relro_start;
     9         kx 	      end = link_info->relro_end;
     9         kx 	    }
     9         kx 	  else if (m->count != 0)
     9         kx 	    {
     9         kx 	      if (!m->p_size_valid)
     9         kx 		abort ();
     9         kx 	      start = m->sections[0]->vma;
     9         kx 	      end = start + m->p_size / opb;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      start = 0;
     9         kx 	      end = 0;
     9         kx 	    }
     9         kx 
     9         kx 	  ok = false;
     9         kx 	  if (start < end)
     9         kx 	    {
     9         kx 	      struct elf_segment_map *lm;
     9         kx 	      const Elf_Internal_Phdr *lp;
     9         kx 	      unsigned int i;
     9         kx 
     9         kx 	      /* Find a LOAD segment containing a section in the RELRO
     9         kx 		 segment.  */
     9         kx 	      for (lm = elf_seg_map (abfd), lp = phdrs;
     9         kx 		   lm != NULL;
     9         kx 		   lm = lm->next, lp++)
     9         kx 		{
     9         kx 		  if (lp->p_type == PT_LOAD
     9         kx 		      && lm->count != 0
     9         kx 		      && (lm->sections[lm->count - 1]->vma
     9         kx 			  + (!IS_TBSS (lm->sections[lm->count - 1])
     9         kx 			     ? lm->sections[lm->count - 1]->size / opb
     9         kx 			     : 0)) > start
     9         kx 		      && lm->sections[0]->vma < end)
     9         kx 		    break;
     9         kx 		}
     9         kx 
     9         kx 	      if (lm != NULL)
     9         kx 		{
     9         kx 		  /* Find the section starting the RELRO segment.  */
     9         kx 		  for (i = 0; i < lm->count; i++)
     9         kx 		    {
     9         kx 		      asection *s = lm->sections[i];
     9         kx 		      if (s->vma >= start
     9         kx 			  && s->vma < end
     9         kx 			  && s->size != 0)
     9         kx 			break;
     9         kx 		    }
     9         kx 
     9         kx 		  if (i < lm->count)
     9         kx 		    {
     9         kx 		      p->p_vaddr = lm->sections[i]->vma * opb;
     9         kx 		      p->p_paddr = lm->sections[i]->lma * opb;
     9         kx 		      p->p_offset = lm->sections[i]->filepos;
     9         kx 		      p->p_memsz = end * opb - p->p_vaddr;
     9         kx 		      p->p_filesz = p->p_memsz;
     9         kx 
     9         kx 		      /* The RELRO segment typically ends a few bytes
     9         kx 			 into .got.plt but other layouts are possible.
     9         kx 			 In cases where the end does not match any
     9         kx 			 loaded section (for instance is in file
     9         kx 			 padding), trim p_filesz back to correspond to
     9         kx 			 the end of loaded section contents.  */
     9         kx 		      if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr)
     9         kx 			p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr;
     9         kx 
     9         kx 		      /* Preserve the alignment and flags if they are
     9         kx 			 valid.  The gold linker generates RW/4 for
     9         kx 			 the PT_GNU_RELRO section.  It is better for
     9         kx 			 objcopy/strip to honor these attributes
     9         kx 			 otherwise gdb will choke when using separate
     9         kx 			 debug files.  */
     9         kx 		      if (!m->p_align_valid)
     9         kx 			p->p_align = 1;
     9         kx 		      if (!m->p_flags_valid)
     9         kx 			p->p_flags = PF_R;
     9         kx 		      ok = true;
     9         kx 		    }
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  if (!ok)
     9         kx 	    {
     9         kx 	      if (link_info != NULL)
     9         kx 		_bfd_error_handler
     9         kx 		  (_("%pB: warning: unable to allocate any sections"
     9         kx 		     " to PT_GNU_RELRO segment"),
     9         kx 		   abfd);
     9         kx 	      memset (p, 0, sizeof *p);
     9         kx 	    }
     9         kx 	}
     9         kx       else if (p->p_type == PT_GNU_STACK)
     9         kx 	{
     9         kx 	  if (m->p_size_valid)
     9         kx 	    p->p_memsz = m->p_size;
     9         kx 	}
     9         kx       else if (m->count != 0)
     9         kx 	{
     9         kx 	  unsigned int i;
     9         kx 
     9         kx 	  if (p->p_type != PT_LOAD
     9         kx 	      && (p->p_type != PT_NOTE
     9         kx 		  || bfd_get_format (abfd) != bfd_core))
     9         kx 	    {
     9         kx 	      /* A user specified segment layout may include a PHDR
     9         kx 		 segment that overlaps with a LOAD segment...  */
     9         kx 	      if (p->p_type == PT_PHDR)
     9         kx 		{
     9         kx 		  m->count = 0;
     9         kx 		  continue;
     9         kx 		}
     9         kx 
     9         kx 	      if (m->includes_filehdr || m->includes_phdrs)
     9         kx 		{
     9         kx 		  /* PR 17512: file: 2195325e.  */
     9         kx 		  _bfd_error_handler
     9         kx 		    (_("%pB: error: non-load segment %d includes file header "
     9         kx 		       "and/or program header"),
     9         kx 		     abfd, (int) (p - phdrs));
     9         kx 		  return false;
     9         kx 		}
     9         kx 
     9         kx 	      p->p_filesz = 0;
     9         kx 	      p->p_offset = m->sections[0]->filepos;
     9         kx 	      for (i = m->count; i-- != 0;)
     9         kx 		{
     9         kx 		  asection *sect = m->sections[i];
     9         kx 		  Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
     9         kx 		  if (hdr->sh_type != SHT_NOBITS)
     9         kx 		    {
     9         kx 		      p->p_filesz = sect->filepos - p->p_offset + hdr->sh_size;
     9         kx 		      /* NB: p_memsz of the loadable PT_NOTE segment
     9         kx 			 should be the same as p_filesz.  */
     9         kx 		      if (p->p_type == PT_NOTE
     9         kx 			  && (hdr->sh_flags & SHF_ALLOC) != 0)
     9         kx 			p->p_memsz = p->p_filesz;
     9         kx 		      break;
     9         kx 		    }
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static elf_section_list *
     9         kx find_section_in_list (unsigned int i, elf_section_list * list)
     9         kx {
     9         kx   for (;list != NULL; list = list->next)
     9         kx     if (list->ndx == i)
     9         kx       break;
     9         kx   return list;
     9         kx }
     9         kx 
     9         kx /* Work out the file positions of all the sections.  This is called by
     9         kx    _bfd_elf_compute_section_file_positions.  All the section sizes and
     9         kx    VMAs must be known before this is called.
     9         kx 
     9         kx    Reloc sections come in two flavours: Those processed specially as
     9         kx    "side-channel" data attached to a section to which they apply, and
     9         kx    those that bfd doesn't process as relocations.  The latter sort are
     9         kx    stored in a normal bfd section by bfd_section_from_shdr.  We don't
     9         kx    consider the former sort here, unless they form part of the loadable
     9         kx    image.  Reloc sections not assigned here (and compressed debugging
     9         kx    sections and CTF sections which nothing else in the file can rely
     9         kx    upon) will be handled later by assign_file_positions_for_relocs.
     9         kx 
     9         kx    We also don't set the positions of the .symtab and .strtab here.  */
     9         kx 
     9         kx static bool
     9         kx assign_file_positions_except_relocs (bfd *abfd,
     9         kx 				     struct bfd_link_info *link_info)
     9         kx {
     9         kx   struct elf_obj_tdata *tdata = elf_tdata (abfd);
     9         kx   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   unsigned int alloc;
     9         kx 
     9         kx   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
     9         kx       && bfd_get_format (abfd) != bfd_core)
     9         kx     {
     9         kx       Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
     9         kx       unsigned int num_sec = elf_numsections (abfd);
     9         kx       Elf_Internal_Shdr **hdrpp;
     9         kx       unsigned int i;
     9         kx       file_ptr off;
     9         kx 
     9         kx       /* Start after the ELF header.  */
     9         kx       off = i_ehdrp->e_ehsize;
     9         kx 
     9         kx       /* We are not creating an executable, which means that we are
     9         kx 	 not creating a program header, and that the actual order of
     9         kx 	 the sections in the file is unimportant.  */
     9         kx       for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
     9         kx 	{
     9         kx 	  Elf_Internal_Shdr *hdr;
     9         kx 
     9         kx 	  hdr = *hdrpp;
     9         kx 	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
     9         kx 	       && hdr->bfd_section == NULL)
     9         kx 	      /* Do not assign offsets for these sections yet: we don't know
     9         kx 		 their sizes.  */
     9         kx 	      || (abfd->is_linker_output
     9         kx 		  && hdr->bfd_section != NULL
     9         kx 		  && (hdr->sh_name == -1u
     9         kx 		      || bfd_section_is_ctf (hdr->bfd_section)))
     9         kx 	      || i == elf_onesymtab (abfd)
     9         kx 	      || (elf_symtab_shndx_list (abfd) != NULL
     9         kx 		  && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
     9         kx 	      || i == elf_strtab_sec (abfd)
     9         kx 	      || i == elf_shstrtab_sec (abfd))
     9         kx 	    {
     9         kx 	      hdr->sh_offset = -1;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
     9         kx 	}
     9         kx 
     9         kx       elf_next_file_pos (abfd) = off;
     9         kx       elf_program_header_size (abfd) = 0;
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       /* Assign file positions for the loaded sections based on the
     9         kx 	 assignment of sections to segments.  */
     9         kx       if (!assign_file_positions_for_load_sections (abfd, link_info))
     9         kx 	return false;
     9         kx 
     9         kx       /* And for non-load sections.  */
     9         kx       if (!assign_file_positions_for_non_load_sections (abfd, link_info))
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   if (!(*bed->elf_backend_modify_headers) (abfd, link_info))
     9         kx     return false;
     9         kx 
     9         kx   /* Write out the program headers.  */
     9         kx   alloc = i_ehdrp->e_phnum;
     9         kx   if (alloc != 0)
     9         kx     {
     9         kx       if (link_info != NULL && ! link_info->no_warn_rwx_segments)
     9         kx 	{
     9         kx 	  /* Memory resident segments with non-zero size and RWX
     9         kx 	     permissions are a security risk, so we generate a warning
     9         kx 	     here if we are creating any.  */
     9         kx 	  unsigned int i;
     9         kx 
     9         kx 	  for (i = 0; i < alloc; i++)
     9         kx 	    {
     9         kx 	      const Elf_Internal_Phdr * phdr = tdata->phdr + i;
     9         kx 
     9         kx 	      if (phdr->p_memsz == 0)
     9         kx 		continue;
     9         kx 
     9         kx 	      if (phdr->p_type == PT_TLS && (phdr->p_flags & PF_X))
     9         kx 		_bfd_error_handler (_("warning: %pB has a TLS segment"
     9         kx 				      " with execute permission"),
     9         kx 				    abfd);
     9         kx 	      else if (phdr->p_type == PT_LOAD
     9         kx 		       && ((phdr->p_flags & (PF_R | PF_W | PF_X))
     9         kx 			   == (PF_R | PF_W | PF_X)))
     9         kx 		_bfd_error_handler (_("warning: %pB has a LOAD segment"
     9         kx 				      " with RWX permissions"),
     9         kx 				    abfd);
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0
     9         kx 	  || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_init_file_header (bfd *abfd,
     9         kx 			   struct bfd_link_info *info ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form.  */
     9         kx   struct elf_strtab_hash *shstrtab;
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   i_ehdrp = elf_elfheader (abfd);
     9         kx 
     9         kx   shstrtab = _bfd_elf_strtab_init ();
     9         kx   if (shstrtab == NULL)
     9         kx     return false;
     9         kx 
     9         kx   elf_shstrtab (abfd) = shstrtab;
     9         kx 
     9         kx   i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
     9         kx   i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
     9         kx   i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
     9         kx   i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;
     9         kx 
     9         kx   i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
     9         kx   i_ehdrp->e_ident[EI_DATA] =
     9         kx     bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
     9         kx   i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;
     9         kx 
     9         kx   if ((abfd->flags & DYNAMIC) != 0)
     9         kx     i_ehdrp->e_type = ET_DYN;
     9         kx   else if ((abfd->flags & EXEC_P) != 0)
     9         kx     i_ehdrp->e_type = ET_EXEC;
     9         kx   else if (bfd_get_format (abfd) == bfd_core)
     9         kx     i_ehdrp->e_type = ET_CORE;
     9         kx   else
     9         kx     i_ehdrp->e_type = ET_REL;
     9         kx 
     9         kx   switch (bfd_get_arch (abfd))
     9         kx     {
     9         kx     case bfd_arch_unknown:
     9         kx       i_ehdrp->e_machine = EM_NONE;
     9         kx       break;
     9         kx 
     9         kx       /* There used to be a long list of cases here, each one setting
     9         kx 	 e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
     9         kx 	 in the corresponding bfd definition.  To avoid duplication,
     9         kx 	 the switch was removed.  Machines that need special handling
     9         kx 	 can generally do it in elf_backend_final_write_processing(),
     9         kx 	 unless they need the information earlier than the final write.
     9         kx 	 Such need can generally be supplied by replacing the tests for
     9         kx 	 e_machine with the conditions used to determine it.  */
     9         kx     default:
     9         kx       i_ehdrp->e_machine = bed->elf_machine_code;
     9         kx     }
     9         kx 
     9         kx   i_ehdrp->e_version = bed->s->ev_current;
     9         kx   i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
     9         kx 
     9         kx   /* No program header, for now.  */
     9         kx   i_ehdrp->e_phoff = 0;
     9         kx   i_ehdrp->e_phentsize = 0;
     9         kx   i_ehdrp->e_phnum = 0;
     9         kx 
     9         kx   /* Each bfd section is section header entry.  */
     9         kx   i_ehdrp->e_entry = bfd_get_start_address (abfd);
     9         kx   i_ehdrp->e_shentsize = bed->s->sizeof_shdr;
     9         kx 
     9         kx   elf_tdata (abfd)->symtab_hdr.sh_name =
     9         kx     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", false);
     9         kx   elf_tdata (abfd)->strtab_hdr.sh_name =
     9         kx     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", false);
     9         kx   elf_tdata (abfd)->shstrtab_hdr.sh_name =
     9         kx     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", false);
     9         kx   if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
     9         kx       || elf_tdata (abfd)->strtab_hdr.sh_name == (unsigned int) -1
     9         kx       || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
     9         kx     return false;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=.
     9         kx 
     9         kx    FIXME: We used to have code here to sort the PT_LOAD segments into
     9         kx    ascending order, as per the ELF spec.  But this breaks some programs,
     9         kx    including the Linux kernel.  But really either the spec should be
     9         kx    changed or the programs updated.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_modify_headers (bfd *obfd, struct bfd_link_info *link_info)
     9         kx {
     9         kx   if (link_info != NULL && bfd_link_pie (link_info))
     9         kx     {
     9         kx       Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (obfd);
     9         kx       unsigned int num_segments = i_ehdrp->e_phnum;
     9         kx       struct elf_obj_tdata *tdata = elf_tdata (obfd);
     9         kx       Elf_Internal_Phdr *segment = tdata->phdr;
     9         kx       Elf_Internal_Phdr *end_segment = &segment[num_segments];
     9         kx 
     9         kx       /* Find the lowest p_vaddr in PT_LOAD segments.  */
     9         kx       bfd_vma p_vaddr = (bfd_vma) -1;
     9         kx       for (; segment < end_segment; segment++)
     9         kx 	if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
     9         kx 	  p_vaddr = segment->p_vaddr;
     9         kx 
     9         kx       /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
     9         kx 	 segments is non-zero.  */
     9         kx       if (p_vaddr)
     9         kx 	i_ehdrp->e_type = ET_EXEC;
     9         kx     }
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Assign file positions for all the reloc sections which are not part
     9         kx    of the loadable file image, and the file position of section headers.  */
     9         kx 
     9         kx static bool
     9         kx _bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
     9         kx {
     9         kx   file_ptr off;
     9         kx   Elf_Internal_Shdr **shdrpp, **end_shdrpp;
     9         kx   Elf_Internal_Shdr *shdrp;
     9         kx   Elf_Internal_Ehdr *i_ehdrp;
     9         kx   const struct elf_backend_data *bed;
     9         kx 
     9         kx   off = elf_next_file_pos (abfd);
     9         kx 
     9         kx   shdrpp = elf_elfsections (abfd);
     9         kx   end_shdrpp = shdrpp + elf_numsections (abfd);
     9         kx   for (shdrpp++; shdrpp < end_shdrpp; shdrpp++)
     9         kx     {
     9         kx       shdrp = *shdrpp;
     9         kx       if (shdrp->sh_offset == -1)
     9         kx 	{
     9         kx 	  asection *sec = shdrp->bfd_section;
     9         kx 	  if (sec == NULL
     9         kx 	      || shdrp->sh_type == SHT_REL
     9         kx 	      || shdrp->sh_type == SHT_RELA)
     9         kx 	    ;
     9         kx 	  else if (bfd_section_is_ctf (sec))
     9         kx 	    {
     9         kx 	      /* Update section size and contents.	*/
     9         kx 	      shdrp->sh_size = sec->size;
     9         kx 	      shdrp->contents = sec->contents;
     9         kx 	    }
     9         kx 	  else if (shdrp->sh_name == -1u)
     9         kx 	    {
     9         kx 	      const char *name = sec->name;
     9         kx 	      struct bfd_elf_section_data *d;
     9         kx 
     9         kx 	      /* Compress DWARF debug sections.  */
     9         kx 	      if (!bfd_compress_section (abfd, sec, shdrp->contents))
     9         kx 		return false;
     9         kx 
     9         kx 	      if (sec->compress_status == COMPRESS_SECTION_DONE
     9         kx 		  && (abfd->flags & BFD_COMPRESS_GABI) == 0
     9         kx 		  && name[1] == 'd')
     9         kx 		{
     9         kx 		  /* If section is compressed with zlib-gnu, convert
     9         kx 		     section name from .debug_* to .zdebug_*.  */
     9         kx 		  char *new_name = bfd_debug_name_to_zdebug (abfd, name);
     9         kx 		  if (new_name == NULL)
     9         kx 		    return false;
     9         kx 		  name = new_name;
     9         kx 		}
     9         kx 	      /* Add section name to section name section.  */
     9         kx 	      shdrp->sh_name
     9         kx 		= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
     9         kx 						      name, false);
     9         kx 	      d = elf_section_data (sec);
     9         kx 
     9         kx 	      /* Add reloc section name to section name section.  */
     9         kx 	      if (d->rel.hdr
     9         kx 		  && !_bfd_elf_set_reloc_sh_name (abfd, d->rel.hdr,
     9         kx 						  name, false))
     9         kx 		return false;
     9         kx 	      if (d->rela.hdr
     9         kx 		  && !_bfd_elf_set_reloc_sh_name (abfd, d->rela.hdr,
     9         kx 						  name, true))
     9         kx 		return false;
     9         kx 
     9         kx 	      /* Update section size and contents.  */
     9         kx 	      shdrp->sh_size = sec->size;
     9         kx 	      shdrp->contents = sec->contents;
     9         kx 	      sec->contents = NULL;
     9         kx 	    }
     9         kx 
     9         kx 	  off = _bfd_elf_assign_file_position_for_section (shdrp, off, true);
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Place section name section after DWARF debug sections have been
     9         kx      compressed.  */
     9         kx   _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
     9         kx   shdrp = &elf_tdata (abfd)->shstrtab_hdr;
     9         kx   shdrp->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
     9         kx   off = _bfd_elf_assign_file_position_for_section (shdrp, off, true);
     9         kx 
     9         kx   /* Place the section headers.  */
     9         kx   i_ehdrp = elf_elfheader (abfd);
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   off = align_file_position (off, 1 << bed->s->log_file_align);
     9         kx   i_ehdrp->e_shoff = off;
     9         kx   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
     9         kx   elf_next_file_pos (abfd) = off;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_write_object_contents (bfd *abfd)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   Elf_Internal_Shdr **i_shdrp;
     9         kx   bool failed;
     9         kx   unsigned int count, num_sec;
     9         kx   struct elf_obj_tdata *t;
     9         kx 
     9         kx   if (! abfd->output_has_begun
     9         kx       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     9         kx     return false;
     9         kx   /* Do not rewrite ELF data when the BFD has been opened for update.
     9         kx      abfd->output_has_begun was set to TRUE on opening, so creation of
     9         kx      new sections, and modification of existing section sizes was
     9         kx      restricted.  This means the ELF header, program headers and
     9         kx      section headers can't have changed.  If the contents of any
     9         kx      sections has been modified, then those changes have already been
     9         kx      written to the BFD.  */
     9         kx   else if (abfd->direction == both_direction)
     9         kx     {
     9         kx       BFD_ASSERT (abfd->output_has_begun);
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   i_shdrp = elf_elfsections (abfd);
     9         kx 
     9         kx   failed = false;
     9         kx   bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
     9         kx   if (failed)
     9         kx     return false;
     9         kx 
     9         kx   if (!_bfd_elf_assign_file_positions_for_non_load (abfd))
     9         kx     return false;
     9         kx 
     9         kx   /* After writing the headers, we need to write the sections too...  */
     9         kx   num_sec = elf_numsections (abfd);
     9         kx   for (count = 1; count < num_sec; count++)
     9         kx     {
     9         kx       i_shdrp[count]->sh_name
     9         kx 	= _bfd_elf_strtab_offset (elf_shstrtab (abfd),
     9         kx 				  i_shdrp[count]->sh_name);
     9         kx       if (bed->elf_backend_section_processing)
     9         kx 	if (!(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]))
     9         kx 	  return false;
     9         kx       if (i_shdrp[count]->contents)
     9         kx 	{
     9         kx 	  bfd_size_type amt = i_shdrp[count]->sh_size;
     9         kx 
     9         kx 	  if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
     9         kx 	      || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
     9         kx 	    return false;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* Write out the section header names.  */
     9         kx   t = elf_tdata (abfd);
     9         kx   if (elf_shstrtab (abfd) != NULL
     9         kx       && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0
     9         kx 	  || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
     9         kx     return false;
     9         kx 
     9         kx   if (!(*bed->elf_backend_final_write_processing) (abfd))
     9         kx     return false;
     9         kx 
     9         kx   if (!bed->s->write_shdrs_and_ehdr (abfd))
     9         kx     return false;
     9         kx 
     9         kx   /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0].  */
     9         kx   if (t->o->build_id.after_write_object_contents != NULL
     9         kx       && !(*t->o->build_id.after_write_object_contents) (abfd))
     9         kx     return false;
     9         kx   if (t->o->package_metadata.after_write_object_contents != NULL
     9         kx       && !(*t->o->package_metadata.after_write_object_contents) (abfd))
     9         kx     return false;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_write_corefile_contents (bfd *abfd)
     9         kx {
     9         kx   /* Hopefully this can be done just like an object file.  */
     9         kx   return _bfd_elf_write_object_contents (abfd);
     9         kx }
     9         kx 
     9         kx /* Given a section, search the header to find them.  */
     9         kx 
     9         kx unsigned int
     9         kx _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
     9         kx {
     9         kx   const struct elf_backend_data *bed;
     9         kx   unsigned int sec_index;
     9         kx 
     9         kx   if (elf_section_data (asect) != NULL
     9         kx       && elf_section_data (asect)->this_idx != 0)
     9         kx     return elf_section_data (asect)->this_idx;
     9         kx 
     9         kx   if (bfd_is_abs_section (asect))
     9         kx     sec_index = SHN_ABS;
     9         kx   else if (bfd_is_com_section (asect))
     9         kx     sec_index = SHN_COMMON;
     9         kx   else if (bfd_is_und_section (asect))
     9         kx     sec_index = SHN_UNDEF;
     9         kx   else
     9         kx     sec_index = SHN_BAD;
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   if (bed->elf_backend_section_from_bfd_section)
     9         kx     {
     9         kx       int retval = sec_index;
     9         kx 
     9         kx       if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
     9         kx 	return retval;
     9         kx     }
     9         kx 
     9         kx   if (sec_index == SHN_BAD)
     9         kx     bfd_set_error (bfd_error_nonrepresentable_section);
     9         kx 
     9         kx   return sec_index;
     9         kx }
     9         kx 
     9         kx /* Given a BFD symbol, return the index in the ELF symbol table, or -1
     9         kx    on error.  */
     9         kx 
     9         kx int
     9         kx _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
     9         kx {
     9         kx   asymbol *asym_ptr = *asym_ptr_ptr;
     9         kx   int idx;
     9         kx   flagword flags = asym_ptr->flags;
     9         kx 
     9         kx   /* When gas creates relocations against local labels, it creates its
     9         kx      own symbol for the section, but does put the symbol into the
     9         kx      symbol chain, so udata is 0.  When the linker is generating
     9         kx      relocatable output, this section symbol may be for one of the
     9         kx      input sections rather than the output section.  */
     9         kx   if (asym_ptr->udata.i == 0
     9         kx       && (flags & BSF_SECTION_SYM)
     9         kx       && asym_ptr->section)
     9         kx     {
     9         kx       asection *sec;
     9         kx 
     9         kx       sec = asym_ptr->section;
     9         kx       if (sec->owner != abfd && sec->output_section != NULL)
     9         kx 	sec = sec->output_section;
     9         kx       if (sec->owner == abfd
     9         kx 	  && sec->index < elf_num_section_syms (abfd)
     9         kx 	  && elf_section_syms (abfd)[sec->index] != NULL)
     9         kx 	asym_ptr->udata.i = elf_section_syms (abfd)[sec->index]->udata.i;
     9         kx     }
     9         kx 
     9         kx   idx = asym_ptr->udata.i;
     9         kx 
     9         kx   if (idx == 0)
     9         kx     {
     9         kx       /* This case can occur when using --strip-symbol on a symbol
     9         kx 	 which is used in a relocation entry.  */
     9         kx       _bfd_error_handler
     9         kx 	/* xgettext:c-format */
     9         kx 	(_("%pB: symbol `%s' required but not present"),
     9         kx 	 abfd, bfd_asymbol_name (asym_ptr));
     9         kx       bfd_set_error (bfd_error_no_symbols);
     9         kx       return -1;
     9         kx     }
     9         kx 
     9         kx #if DEBUG & 4
     9         kx   {
     9         kx     fprintf (stderr,
     9         kx 	     "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d,"
     9         kx 	     " flags = 0x%.8x\n",
     9         kx 	     (long) asym_ptr, asym_ptr->name, idx, flags);
     9         kx     fflush (stderr);
     9         kx   }
     9         kx #endif
     9         kx 
     9         kx   return idx;
     9         kx }
     9         kx 
     9         kx static inline bfd_vma
     9         kx segment_size (Elf_Internal_Phdr *segment)
     9         kx {
     9         kx   return (segment->p_memsz > segment->p_filesz
     9         kx 	  ? segment->p_memsz : segment->p_filesz);
     9         kx }
     9         kx 
     9         kx 
     9         kx /* Returns the end address of the segment + 1.  */
     9         kx static inline bfd_vma
     9         kx segment_end (Elf_Internal_Phdr *segment, bfd_vma start)
     9         kx {
     9         kx   return start + segment_size (segment);
     9         kx }
     9         kx 
     9         kx static inline bfd_size_type
     9         kx section_size (asection *section, Elf_Internal_Phdr *segment)
     9         kx {
     9         kx   if ((section->flags & SEC_HAS_CONTENTS) != 0
     9         kx       || (section->flags & SEC_THREAD_LOCAL) == 0
     9         kx       || segment->p_type == PT_TLS)
     9         kx     return section->size;
     9         kx   return 0;
     9         kx }
     9         kx 
     9         kx /* Returns TRUE if the given section is contained within the given
     9         kx    segment.  LMA addresses are compared against PADDR when
     9         kx    bed->want_p_paddr_set_to_zero is false, VMA against VADDR when true.  */
     9         kx static bool
     9         kx is_contained_by (asection *section, Elf_Internal_Phdr *segment,
     9         kx 		 bfd_vma paddr, bfd_vma vaddr, unsigned int opb,
     9         kx 		 const struct elf_backend_data *bed)
     9         kx {
     9         kx   bfd_vma seg_addr = !bed->want_p_paddr_set_to_zero ? paddr : vaddr;
     9         kx   bfd_vma addr = !bed->want_p_paddr_set_to_zero ? section->lma : section->vma;
     9         kx   bfd_vma octet;
     9         kx   if (_bfd_mul_overflow (addr, opb, &octet))
     9         kx     return false;
     9         kx   /* The third and fourth lines below are testing that the section end
     9         kx      address is within the segment.  It's written this way to avoid
     9         kx      overflow.  Add seg_addr + section_size to both sides of the
     9         kx      inequality to make it obvious.  */
     9         kx   return (octet >= seg_addr
     9         kx 	  && segment_size (segment) >= section_size (section, segment)
     9         kx 	  && (octet - seg_addr
     9         kx 	      <= segment_size (segment) - section_size (section, segment)));
     9         kx }
     9         kx 
     9         kx /* Handle PT_NOTE segment.  */
     9         kx static bool
     9         kx is_note (asection *s, Elf_Internal_Phdr *p)
     9         kx {
     9         kx   return (p->p_type == PT_NOTE
     9         kx 	  && elf_section_type (s) == SHT_NOTE
     9         kx 	  && (ufile_ptr) s->filepos >= p->p_offset
     9         kx 	  && p->p_filesz >= s->size
     9         kx 	  && (ufile_ptr) s->filepos - p->p_offset <= p->p_filesz - s->size);
     9         kx }
     9         kx 
     9         kx /* Rewrite program header information.  */
     9         kx 
     9         kx static bool
     9         kx rewrite_elf_program_header (bfd *ibfd, bfd *obfd, bfd_vma maxpagesize)
     9         kx {
     9         kx   Elf_Internal_Ehdr *iehdr;
     9         kx   struct elf_segment_map *map;
     9         kx   struct elf_segment_map *map_first;
     9         kx   struct elf_segment_map **pointer_to_map;
     9         kx   Elf_Internal_Phdr *segment;
     9         kx   asection *section;
     9         kx   unsigned int i;
     9         kx   unsigned int num_segments;
     9         kx   bool phdr_included = false;
     9         kx   bool p_paddr_valid;
     9         kx   struct elf_segment_map *phdr_adjust_seg = NULL;
     9         kx   unsigned int phdr_adjust_num = 0;
     9         kx   const struct elf_backend_data *bed;
     9         kx   unsigned int opb = bfd_octets_per_byte (ibfd, NULL);
     9         kx 
     9         kx   bed = get_elf_backend_data (ibfd);
     9         kx   iehdr = elf_elfheader (ibfd);
     9         kx 
     9         kx   map_first = NULL;
     9         kx   pointer_to_map = &map_first;
     9         kx 
     9         kx   num_segments = elf_elfheader (ibfd)->e_phnum;
     9         kx 
     9         kx   /* The complicated case when p_vaddr is 0 is to handle the Solaris
     9         kx      linker, which generates a PT_INTERP section with p_vaddr and
     9         kx      p_memsz set to 0.  */
     9         kx #define IS_SOLARIS_PT_INTERP(p, s)					\
     9         kx   (p->p_vaddr == 0							\
     9         kx    && p->p_paddr == 0							\
     9         kx    && p->p_memsz == 0							\
     9         kx    && p->p_filesz > 0							\
     9         kx    && (s->flags & SEC_HAS_CONTENTS) != 0				\
     9         kx    && s->size > 0							\
     9         kx    && (bfd_vma) s->filepos >= p->p_offset				\
     9         kx    && ((bfd_vma) s->filepos + s->size					\
     9         kx        <= p->p_offset + p->p_filesz))
     9         kx 
     9         kx   /* Decide if the given section should be included in the given segment.
     9         kx      A section will be included if:
     9         kx        1. It is within the address space of the segment -- we use the LMA
     9         kx 	  if that is set for the segment and the VMA otherwise,
     9         kx        2. It is an allocated section or a NOTE section in a PT_NOTE
     9         kx 	  segment.
     9         kx        3. There is an output section associated with it,
     9         kx        4. The section has not already been allocated to a previous segment.
     9         kx        5. PT_GNU_STACK segments do not include any sections.
     9         kx        6. PT_TLS segment includes only SHF_TLS sections.
     9         kx        7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
     9         kx        8. PT_DYNAMIC should not contain empty sections at the beginning
     9         kx 	  (with the possible exception of .dynamic).  */
     9         kx #define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed, opb)		\
     9         kx   (((is_contained_by (section, segment, segment->p_paddr,		\
     9         kx 		      segment->p_vaddr, opb, bed)			\
     9         kx      && (section->flags & SEC_ALLOC) != 0)				\
     9         kx     || is_note (section, segment))					\
     9         kx    && segment->p_type != PT_GNU_STACK					\
     9         kx    && (segment->p_type != PT_TLS					\
     9         kx        || (section->flags & SEC_THREAD_LOCAL))				\
     9         kx    && (segment->p_type == PT_LOAD					\
     9         kx        || segment->p_type == PT_TLS					\
     9         kx        || (section->flags & SEC_THREAD_LOCAL) == 0)			\
     9         kx    && (segment->p_type != PT_DYNAMIC					\
     9         kx        || section_size (section, segment) > 0				\
     9         kx        || (segment->p_paddr						\
     9         kx 	   ? segment->p_paddr != section->lma * (opb)			\
     9         kx 	   : segment->p_vaddr != section->vma * (opb))			\
     9         kx        || (strcmp (bfd_section_name (section), ".dynamic") == 0))	\
     9         kx    && (segment->p_type != PT_LOAD || !section->segment_mark))
     9         kx 
     9         kx /* If the output section of a section in the input segment is NULL,
     9         kx    it is removed from the corresponding output segment.   */
     9         kx #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed, opb)		\
     9         kx   (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb)		\
     9         kx    && section->output_section != NULL)
     9         kx 
     9         kx   /* Returns TRUE iff seg1 starts after the end of seg2.  */
     9         kx #define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)			\
     9         kx   (seg1->field >= segment_end (seg2, seg2->field))
     9         kx 
     9         kx   /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
     9         kx      their VMA address ranges and their LMA address ranges overlap.
     9         kx      It is possible to have overlapping VMA ranges without overlapping LMA
     9         kx      ranges.  RedBoot images for example can have both .data and .bss mapped
     9         kx      to the same VMA range, but with the .data section mapped to a different
     9         kx      LMA.  */
     9         kx #define SEGMENT_OVERLAPS(seg1, seg2)					\
     9         kx   (   !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr)			\
     9         kx 	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr))			\
     9         kx    && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr)			\
     9         kx 	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))
     9         kx 
     9         kx   /* Initialise the segment mark field, and discard stupid alignment.  */
     9         kx   for (section = ibfd->sections; section != NULL; section = section->next)
     9         kx     {
     9         kx       asection *o = section->output_section;
     9         kx       if (o != NULL && o->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
     9         kx 	o->alignment_power = 0;
     9         kx       section->segment_mark = false;
     9         kx     }
     9         kx 
     9         kx   /* The Solaris linker creates program headers in which all the
     9         kx      p_paddr fields are zero.  When we try to objcopy or strip such a
     9         kx      file, we get confused.  Check for this case, and if we find it
     9         kx      don't set the p_paddr_valid fields.  */
     9         kx   p_paddr_valid = false;
     9         kx   for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx        i < num_segments;
     9         kx        i++, segment++)
     9         kx     if (segment->p_paddr != 0)
     9         kx       {
     9         kx 	p_paddr_valid = true;
     9         kx 	break;
     9         kx       }
     9         kx 
     9         kx   /* Scan through the segments specified in the program header
     9         kx      of the input BFD.  For this first scan we look for overlaps
     9         kx      in the loadable segments.  These can be created by weird
     9         kx      parameters to objcopy.  Also, fix some solaris weirdness.  */
     9         kx   for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx        i < num_segments;
     9         kx        i++, segment++)
     9         kx     {
     9         kx       unsigned int j;
     9         kx       Elf_Internal_Phdr *segment2;
     9         kx 
     9         kx       if (segment->p_type == PT_INTERP)
     9         kx 	for (section = ibfd->sections; section; section = section->next)
     9         kx 	  if (IS_SOLARIS_PT_INTERP (segment, section))
     9         kx 	    {
     9         kx 	      /* Mininal change so that the normal section to segment
     9         kx 		 assignment code will work.  */
     9         kx 	      segment->p_vaddr = section->vma * opb;
     9         kx 	      break;
     9         kx 	    }
     9         kx 
     9         kx       if (segment->p_type != PT_LOAD)
     9         kx 	{
     9         kx 	  /* Remove PT_GNU_RELRO segment.  */
     9         kx 	  if (segment->p_type == PT_GNU_RELRO)
     9         kx 	    segment->p_type = PT_NULL;
     9         kx 	  continue;
     9         kx 	}
     9         kx 
     9         kx       /* Determine if this segment overlaps any previous segments.  */
     9         kx       for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
     9         kx 	{
     9         kx 	  bfd_signed_vma extra_length;
     9         kx 
     9         kx 	  if (segment2->p_type != PT_LOAD
     9         kx 	      || !SEGMENT_OVERLAPS (segment, segment2))
     9         kx 	    continue;
     9         kx 
     9         kx 	  /* Merge the two segments together.  */
     9         kx 	  if (segment2->p_vaddr < segment->p_vaddr)
     9         kx 	    {
     9         kx 	      /* Extend SEGMENT2 to include SEGMENT and then delete
     9         kx 		 SEGMENT.  */
     9         kx 	      extra_length = (segment_end (segment, segment->p_vaddr)
     9         kx 			      - segment_end (segment2, segment2->p_vaddr));
     9         kx 
     9         kx 	      if (extra_length > 0)
     9         kx 		{
     9         kx 		  segment2->p_memsz += extra_length;
     9         kx 		  segment2->p_filesz += extra_length;
     9         kx 		}
     9         kx 
     9         kx 	      segment->p_type = PT_NULL;
     9         kx 
     9         kx 	      /* Since we have deleted P we must restart the outer loop.  */
     9         kx 	      i = 0;
     9         kx 	      segment = elf_tdata (ibfd)->phdr;
     9         kx 	      break;
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      /* Extend SEGMENT to include SEGMENT2 and then delete
     9         kx 		 SEGMENT2.  */
     9         kx 	      extra_length = (segment_end (segment2, segment2->p_vaddr)
     9         kx 			      - segment_end (segment, segment->p_vaddr));
     9         kx 
     9         kx 	      if (extra_length > 0)
     9         kx 		{
     9         kx 		  segment->p_memsz += extra_length;
     9         kx 		  segment->p_filesz += extra_length;
     9         kx 		}
     9         kx 
     9         kx 	      segment2->p_type = PT_NULL;
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   /* The second scan attempts to assign sections to segments.  */
     9         kx   for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx        i < num_segments;
     9         kx        i++, segment++)
     9         kx     {
     9         kx       unsigned int section_count;
     9         kx       asection **sections;
     9         kx       asection *output_section;
     9         kx       unsigned int isec;
     9         kx       asection *matching_lma;
     9         kx       asection *suggested_lma;
     9         kx       unsigned int j;
     9         kx       size_t amt;
     9         kx       asection *first_section;
     9         kx 
     9         kx       if (segment->p_type == PT_NULL)
     9         kx 	continue;
     9         kx 
     9         kx       first_section = NULL;
     9         kx       /* Compute how many sections might be placed into this segment.  */
     9         kx       for (section = ibfd->sections, section_count = 0;
     9         kx 	   section != NULL;
     9         kx 	   section = section->next)
     9         kx 	{
     9         kx 	  /* Find the first section in the input segment, which may be
     9         kx 	     removed from the corresponding output segment.   */
     9         kx 	  if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb))
     9         kx 	    {
     9         kx 	      if (first_section == NULL)
     9         kx 		first_section = section;
     9         kx 	      if (section->output_section != NULL)
     9         kx 		++section_count;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       /* Allocate a segment map big enough to contain
     9         kx 	 all of the sections we have selected.  */
     9         kx       amt = sizeof (struct elf_segment_map) - sizeof (asection *);
     9         kx       amt += section_count * sizeof (asection *);
     9         kx       map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
     9         kx       if (map == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       /* Initialise the fields of the segment map.  Default to
     9         kx 	 using the physical address of the segment in the input BFD.  */
     9         kx       map->next = NULL;
     9         kx       map->p_type = segment->p_type;
     9         kx       map->p_flags = segment->p_flags;
     9         kx       map->p_flags_valid = 1;
     9         kx 
     9         kx       if (map->p_type == PT_LOAD
     9         kx 	  && (ibfd->flags & D_PAGED) != 0
     9         kx 	  && maxpagesize > 1
     9         kx 	  && segment->p_align > 1)
     9         kx 	{
     9         kx 	  map->p_align = segment->p_align;
     9         kx 	  if (segment->p_align > maxpagesize)
     9         kx 	    map->p_align = maxpagesize;
     9         kx 	  map->p_align_valid = 1;
     9         kx 	}
     9         kx 
     9         kx       /* If the first section in the input segment is removed, there is
     9         kx 	 no need to preserve segment physical address in the corresponding
     9         kx 	 output segment.  */
     9         kx       if (!first_section || first_section->output_section != NULL)
     9         kx 	{
     9         kx 	  map->p_paddr = segment->p_paddr;
     9         kx 	  map->p_paddr_valid = p_paddr_valid;
     9         kx 	}
     9         kx 
     9         kx       /* Determine if this segment contains the ELF file header
     9         kx 	 and if it contains the program headers themselves.  */
     9         kx       map->includes_filehdr = (segment->p_offset == 0
     9         kx 			       && segment->p_filesz >= iehdr->e_ehsize);
     9         kx       map->includes_phdrs = 0;
     9         kx 
     9         kx       if (!phdr_included || segment->p_type != PT_LOAD)
     9         kx 	{
     9         kx 	  map->includes_phdrs =
     9         kx 	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
     9         kx 	     && (segment->p_offset + segment->p_filesz
     9         kx 		 >= ((bfd_vma) iehdr->e_phoff
     9         kx 		     + iehdr->e_phnum * iehdr->e_phentsize)));
     9         kx 
     9         kx 	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
     9         kx 	    phdr_included = true;
     9         kx 	}
     9         kx 
     9         kx       if (section_count == 0)
     9         kx 	{
     9         kx 	  /* Special segments, such as the PT_PHDR segment, may contain
     9         kx 	     no sections, but ordinary, loadable segments should contain
     9         kx 	     something.  They are allowed by the ELF spec however, so only
     9         kx 	     a warning is produced.
     9         kx 	     There is however the valid use case of embedded systems which
     9         kx 	     have segments with p_filesz of 0 and a p_memsz > 0 to initialize
     9         kx 	     flash memory with zeros.  No warning is shown for that case.  */
     9         kx 	  if (segment->p_type == PT_LOAD
     9         kx 	      && (segment->p_filesz > 0 || segment->p_memsz == 0))
     9         kx 	    /* xgettext:c-format */
     9         kx 	    _bfd_error_handler
     9         kx 	      (_("%pB: warning: empty loadable segment detected"
     9         kx 		 " at vaddr=%#" PRIx64 ", is this intentional?"),
     9         kx 	       ibfd, (uint64_t) segment->p_vaddr);
     9         kx 
     9         kx 	  map->p_vaddr_offset = segment->p_vaddr / opb;
     9         kx 	  map->count = 0;
     9         kx 	  *pointer_to_map = map;
     9         kx 	  pointer_to_map = &map->next;
     9         kx 
     9         kx 	  continue;
     9         kx 	}
     9         kx 
     9         kx       /* Now scan the sections in the input BFD again and attempt
     9         kx 	 to add their corresponding output sections to the segment map.
     9         kx 	 The problem here is how to handle an output section which has
     9         kx 	 been moved (ie had its LMA changed).  There are four possibilities:
     9         kx 
     9         kx 	 1. None of the sections have been moved.
     9         kx 	    In this case we can continue to use the segment LMA from the
     9         kx 	    input BFD.
     9         kx 
     9         kx 	 2. All of the sections have been moved by the same amount.
     9         kx 	    In this case we can change the segment's LMA to match the LMA
     9         kx 	    of the first section.
     9         kx 
     9         kx 	 3. Some of the sections have been moved, others have not.
     9         kx 	    In this case those sections which have not been moved can be
     9         kx 	    placed in the current segment which will have to have its size,
     9         kx 	    and possibly its LMA changed, and a new segment or segments will
     9         kx 	    have to be created to contain the other sections.
     9         kx 
     9         kx 	 4. The sections have been moved, but not by the same amount.
     9         kx 	    In this case we can change the segment's LMA to match the LMA
     9         kx 	    of the first section and we will have to create a new segment
     9         kx 	    or segments to contain the other sections.
     9         kx 
     9         kx 	 In order to save time, we allocate an array to hold the section
     9         kx 	 pointers that we are interested in.  As these sections get assigned
     9         kx 	 to a segment, they are removed from this array.  */
     9         kx 
     9         kx       amt = section_count * sizeof (asection *);
     9         kx       sections = (asection **) bfd_malloc (amt);
     9         kx       if (sections == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       /* Step One: Scan for segment vs section LMA conflicts.
     9         kx 	 Also add the sections to the section array allocated above.
     9         kx 	 Also add the sections to the current segment.  In the common
     9         kx 	 case, where the sections have not been moved, this means that
     9         kx 	 we have completely filled the segment, and there is nothing
     9         kx 	 more to do.  */
     9         kx       isec = 0;
     9         kx       matching_lma = NULL;
     9         kx       suggested_lma = NULL;
     9         kx 
     9         kx       for (section = first_section, j = 0;
     9         kx 	   section != NULL;
     9         kx 	   section = section->next)
     9         kx 	{
     9         kx 	  if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed, opb))
     9         kx 	    {
     9         kx 	      output_section = section->output_section;
     9         kx 
     9         kx 	      sections[j++] = section;
     9         kx 
     9         kx 	      /* The Solaris native linker always sets p_paddr to 0.
     9         kx 		 We try to catch that case here, and set it to the
     9         kx 		 correct value.  Note - some backends require that
     9         kx 		 p_paddr be left as zero.  */
     9         kx 	      if (!p_paddr_valid
     9         kx 		  && segment->p_vaddr != 0
     9         kx 		  && !bed->want_p_paddr_set_to_zero
     9         kx 		  && isec == 0
     9         kx 		  && output_section->lma != 0
     9         kx 		  && (align_power (segment->p_vaddr
     9         kx 				   + (map->includes_filehdr
     9         kx 				      ? iehdr->e_ehsize : 0)
     9         kx 				   + (map->includes_phdrs
     9         kx 				      ? iehdr->e_phnum * iehdr->e_phentsize
     9         kx 				      : 0),
     9         kx 				   output_section->alignment_power * opb)
     9         kx 		      == (output_section->vma * opb)))
     9         kx 		map->p_paddr = segment->p_vaddr;
     9         kx 
     9         kx 	      /* Match up the physical address of the segment with the
     9         kx 		 LMA address of the output section.  */
     9         kx 	      if (is_contained_by (output_section, segment, map->p_paddr,
     9         kx 				   map->p_paddr + map->p_vaddr_offset, opb, bed)
     9         kx 		  || is_note (section, segment))
     9         kx 		{
     9         kx 		  if (matching_lma == NULL
     9         kx 		      || output_section->lma < matching_lma->lma)
     9         kx 		    matching_lma = output_section;
     9         kx 
     9         kx 		  /* We assume that if the section fits within the segment
     9         kx 		     then it does not overlap any other section within that
     9         kx 		     segment.  */
     9         kx 		  map->sections[isec++] = output_section;
     9         kx 		}
     9         kx 	      else if (suggested_lma == NULL)
     9         kx 		suggested_lma = output_section;
     9         kx 
     9         kx 	      if (j == section_count)
     9         kx 		break;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       BFD_ASSERT (j == section_count);
     9         kx 
     9         kx       /* Step Two: Adjust the physical address of the current segment,
     9         kx 	 if necessary.  */
     9         kx       if (isec == section_count)
     9         kx 	{
     9         kx 	  /* All of the sections fitted within the segment as currently
     9         kx 	     specified.  This is the default case.  Add the segment to
     9         kx 	     the list of built segments and carry on to process the next
     9         kx 	     program header in the input BFD.  */
     9         kx 	  map->count = section_count;
     9         kx 	  *pointer_to_map = map;
     9         kx 	  pointer_to_map = &map->next;
     9         kx 
     9         kx 	  if (p_paddr_valid
     9         kx 	      && !bed->want_p_paddr_set_to_zero)
     9         kx 	    {
     9         kx 	      bfd_vma hdr_size = 0;
     9         kx 	      if (map->includes_filehdr)
     9         kx 		hdr_size = iehdr->e_ehsize;
     9         kx 	      if (map->includes_phdrs)
     9         kx 		hdr_size += iehdr->e_phnum * iehdr->e_phentsize;
     9         kx 
     9         kx 	      /* Account for padding before the first section in the
     9         kx 		 segment.  */
     9         kx 	      map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
     9         kx 				     - matching_lma->lma);
     9         kx 	    }
     9         kx 
     9         kx 	  free (sections);
     9         kx 	  continue;
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  /* Change the current segment's physical address to match
     9         kx 	     the LMA of the first section that fitted, or if no
     9         kx 	     section fitted, the first section.  */
     9         kx 	  if (matching_lma == NULL)
     9         kx 	    matching_lma = suggested_lma;
     9         kx 
     9         kx 	  map->p_paddr = matching_lma->lma * opb;
     9         kx 
     9         kx 	  /* Offset the segment physical address from the lma
     9         kx 	     to allow for space taken up by elf headers.  */
     9         kx 	  if (map->includes_phdrs)
     9         kx 	    {
     9         kx 	      map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;
     9         kx 
     9         kx 	      /* iehdr->e_phnum is just an estimate of the number
     9         kx 		 of program headers that we will need.  Make a note
     9         kx 		 here of the number we used and the segment we chose
     9         kx 		 to hold these headers, so that we can adjust the
     9         kx 		 offset when we know the correct value.  */
     9         kx 	      phdr_adjust_num = iehdr->e_phnum;
     9         kx 	      phdr_adjust_seg = map;
     9         kx 	    }
     9         kx 
     9         kx 	  if (map->includes_filehdr)
     9         kx 	    {
     9         kx 	      bfd_vma align = (bfd_vma) 1 << matching_lma->alignment_power;
     9         kx 	      map->p_paddr -= iehdr->e_ehsize;
     9         kx 	      /* We've subtracted off the size of headers from the
     9         kx 		 first section lma, but there may have been some
     9         kx 		 alignment padding before that section too.  Try to
     9         kx 		 account for that by adjusting the segment lma down to
     9         kx 		 the same alignment.  */
     9         kx 	      if (segment->p_align != 0 && segment->p_align < align)
     9         kx 		align = segment->p_align;
     9         kx 	      map->p_paddr &= -(align * opb);
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       /* Step Three: Loop over the sections again, this time assigning
     9         kx 	 those that fit to the current segment and removing them from the
     9         kx 	 sections array; but making sure not to leave large gaps.  Once all
     9         kx 	 possible sections have been assigned to the current segment it is
     9         kx 	 added to the list of built segments and if sections still remain
     9         kx 	 to be assigned, a new segment is constructed before repeating
     9         kx 	 the loop.  */
     9         kx       isec = 0;
     9         kx       do
     9         kx 	{
     9         kx 	  map->count = 0;
     9         kx 	  suggested_lma = NULL;
     9         kx 
     9         kx 	  /* Fill the current segment with sections that fit.  */
     9         kx 	  for (j = 0; j < section_count; j++)
     9         kx 	    {
     9         kx 	      section = sections[j];
     9         kx 
     9         kx 	      if (section == NULL)
     9         kx 		continue;
     9         kx 
     9         kx 	      output_section = section->output_section;
     9         kx 
     9         kx 	      BFD_ASSERT (output_section != NULL);
     9         kx 
     9         kx 	      if (is_contained_by (output_section, segment, map->p_paddr,
     9         kx 				   map->p_paddr + map->p_vaddr_offset, opb, bed)
     9         kx 		  || is_note (section, segment))
     9         kx 		{
     9         kx 		  if (map->count == 0)
     9         kx 		    {
     9         kx 		      /* If the first section in a segment does not start at
     9         kx 			 the beginning of the segment, then something is
     9         kx 			 wrong.  */
     9         kx 		      if (align_power (map->p_paddr
     9         kx 				       + (map->includes_filehdr
     9         kx 					  ? iehdr->e_ehsize : 0)
     9         kx 				       + (map->includes_phdrs
     9         kx 					  ? iehdr->e_phnum * iehdr->e_phentsize
     9         kx 					  : 0),
     9         kx 				       output_section->alignment_power * opb)
     9         kx 			  != output_section->lma * opb)
     9         kx 			goto sorry;
     9         kx 		    }
     9         kx 		  else
     9         kx 		    {
     9         kx 		      asection *prev_sec;
     9         kx 
     9         kx 		      prev_sec = map->sections[map->count - 1];
     9         kx 
     9         kx 		      /* If the gap between the end of the previous section
     9         kx 			 and the start of this section is more than
     9         kx 			 maxpagesize then we need to start a new segment.  */
     9         kx 		      if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
     9         kx 				      maxpagesize)
     9         kx 			   < BFD_ALIGN (output_section->lma, maxpagesize))
     9         kx 			  || (prev_sec->lma + prev_sec->size
     9         kx 			      > output_section->lma))
     9         kx 			{
     9         kx 			  if (suggested_lma == NULL)
     9         kx 			    suggested_lma = output_section;
     9         kx 
     9         kx 			  continue;
     9         kx 			}
     9         kx 		    }
     9         kx 
     9         kx 		  map->sections[map->count++] = output_section;
     9         kx 		  ++isec;
     9         kx 		  sections[j] = NULL;
     9         kx 		  if (segment->p_type == PT_LOAD)
     9         kx 		    section->segment_mark = true;
     9         kx 		}
     9         kx 	      else if (suggested_lma == NULL)
     9         kx 		suggested_lma = output_section;
     9         kx 	    }
     9         kx 
     9         kx 	  /* PR 23932.  A corrupt input file may contain sections that cannot
     9         kx 	     be assigned to any segment - because for example they have a
     9         kx 	     negative size - or segments that do not contain any sections.
     9         kx 	     But there are also valid reasons why a segment can be empty.
     9         kx 	     So allow a count of zero.  */
     9         kx 
     9         kx 	  /* Add the current segment to the list of built segments.  */
     9         kx 	  *pointer_to_map = map;
     9         kx 	  pointer_to_map = &map->next;
     9         kx 
     9         kx 	  if (isec < section_count)
     9         kx 	    {
     9         kx 	      /* We still have not allocated all of the sections to
     9         kx 		 segments.  Create a new segment here, initialise it
     9         kx 		 and carry on looping.  */
     9         kx 	      amt = sizeof (struct elf_segment_map) - sizeof (asection *);
     9         kx 	      amt += section_count * sizeof (asection *);
     9         kx 	      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
     9         kx 	      if (map == NULL)
     9         kx 		{
     9         kx 		  free (sections);
     9         kx 		  return false;
     9         kx 		}
     9         kx 
     9         kx 	      /* Initialise the fields of the segment map.  Set the physical
     9         kx 		 physical address to the LMA of the first section that has
     9         kx 		 not yet been assigned.  */
     9         kx 	      map->next = NULL;
     9         kx 	      map->p_type = segment->p_type;
     9         kx 	      map->p_flags = segment->p_flags;
     9         kx 	      map->p_flags_valid = 1;
     9         kx 	      map->p_paddr = suggested_lma->lma * opb;
     9         kx 	      map->p_paddr_valid = p_paddr_valid;
     9         kx 	      map->includes_filehdr = 0;
     9         kx 	      map->includes_phdrs = 0;
     9         kx 	    }
     9         kx 
     9         kx 	  continue;
     9         kx 	sorry:
     9         kx 	  bfd_set_error (bfd_error_sorry);
     9         kx 	  free (sections);
     9         kx 	  return false;
     9         kx 	}
     9         kx       while (isec < section_count);
     9         kx 
     9         kx       free (sections);
     9         kx     }
     9         kx 
     9         kx   elf_seg_map (obfd) = map_first;
     9         kx 
     9         kx   /* If we had to estimate the number of program headers that were
     9         kx      going to be needed, then check our estimate now and adjust
     9         kx      the offset if necessary.  */
     9         kx   if (phdr_adjust_seg != NULL)
     9         kx     {
     9         kx       unsigned int count;
     9         kx 
     9         kx       for (count = 0, map = map_first; map != NULL; map = map->next)
     9         kx 	count++;
     9         kx 
     9         kx       if (count > phdr_adjust_num)
     9         kx 	phdr_adjust_seg->p_paddr
     9         kx 	  -= (count - phdr_adjust_num) * iehdr->e_phentsize;
     9         kx 
     9         kx       for (map = map_first; map != NULL; map = map->next)
     9         kx 	if (map->p_type == PT_PHDR)
     9         kx 	  {
     9         kx 	    bfd_vma adjust
     9         kx 	      = phdr_adjust_seg->includes_filehdr ? iehdr->e_ehsize : 0;
     9         kx 	    map->p_paddr = phdr_adjust_seg->p_paddr + adjust;
     9         kx 	    break;
     9         kx 	  }
     9         kx     }
     9         kx 
     9         kx #undef IS_SOLARIS_PT_INTERP
     9         kx #undef IS_SECTION_IN_INPUT_SEGMENT
     9         kx #undef INCLUDE_SECTION_IN_SEGMENT
     9         kx #undef SEGMENT_AFTER_SEGMENT
     9         kx #undef SEGMENT_OVERLAPS
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Return true if p_align in the ELF program header in ABFD is valid.  */
     9         kx 
     9         kx static bool
     9         kx elf_is_p_align_valid (bfd *abfd)
     9         kx {
     9         kx   unsigned int i;
     9         kx   Elf_Internal_Phdr *segment;
     9         kx   unsigned int num_segments;
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   bfd_size_type maxpagesize = bed->maxpagesize;
     9         kx   bfd_size_type p_align = bed->p_align;
     9         kx 
     9         kx   /* Return true if the default p_align value isn't set or the maximum
     9         kx      page size is the same as the minimum page size.  */
     9         kx   if (p_align == 0 || maxpagesize == bed->minpagesize)
     9         kx     return true;
     9         kx 
     9         kx   /* When the default p_align value is set, p_align may be set to the
     9         kx      default p_align value while segments are aligned to the maximum
     9         kx      page size.  In this case, the input p_align will be ignored and
     9         kx      the maximum page size will be used to align the output segments.  */
     9         kx   segment = elf_tdata (abfd)->phdr;
     9         kx   num_segments = elf_elfheader (abfd)->e_phnum;
     9         kx   for (i = 0; i < num_segments; i++, segment++)
     9         kx     if (segment->p_type == PT_LOAD
     9         kx 	&& (segment->p_align != p_align
     9         kx 	    || vma_page_aligned_bias (segment->p_vaddr,
     9         kx 				      segment->p_offset,
     9         kx 				      maxpagesize) != 0))
     9         kx       return true;
     9         kx 
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx /* Copy ELF program header information.  */
     9         kx 
     9         kx static bool
     9         kx copy_elf_program_header (bfd *ibfd, bfd *obfd)
     9         kx {
     9         kx   Elf_Internal_Ehdr *iehdr;
     9         kx   struct elf_segment_map *map;
     9         kx   struct elf_segment_map *map_first;
     9         kx   struct elf_segment_map **pointer_to_map;
     9         kx   Elf_Internal_Phdr *segment;
     9         kx   unsigned int i;
     9         kx   unsigned int num_segments;
     9         kx   bool phdr_included = false;
     9         kx   bool p_paddr_valid;
     9         kx   bool p_palign_valid;
     9         kx   unsigned int opb = bfd_octets_per_byte (ibfd, NULL);
     9         kx 
     9         kx   iehdr = elf_elfheader (ibfd);
     9         kx 
     9         kx   map_first = NULL;
     9         kx   pointer_to_map = &map_first;
     9         kx 
     9         kx   /* If all the segment p_paddr fields are zero, don't set
     9         kx      map->p_paddr_valid.  */
     9         kx   p_paddr_valid = false;
     9         kx   num_segments = elf_elfheader (ibfd)->e_phnum;
     9         kx   for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx        i < num_segments;
     9         kx        i++, segment++)
     9         kx     if (segment->p_paddr != 0)
     9         kx       {
     9         kx 	p_paddr_valid = true;
     9         kx 	break;
     9         kx       }
     9         kx 
     9         kx   p_palign_valid = elf_is_p_align_valid (ibfd);
     9         kx 
     9         kx   for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx        i < num_segments;
     9         kx        i++, segment++)
     9         kx     {
     9         kx       asection *section;
     9         kx       unsigned int section_count;
     9         kx       size_t amt;
     9         kx       Elf_Internal_Shdr *this_hdr;
     9         kx       asection *first_section = NULL;
     9         kx       asection *lowest_section;
     9         kx 
     9         kx       /* Compute how many sections are in this segment.  */
     9         kx       for (section = ibfd->sections, section_count = 0;
     9         kx 	   section != NULL;
     9         kx 	   section = section->next)
     9         kx 	{
     9         kx 	  this_hdr = &(elf_section_data(section)->this_hdr);
     9         kx 	  if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
     9         kx 	    {
     9         kx 	      if (first_section == NULL)
     9         kx 		first_section = section;
     9         kx 	      section_count++;
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       /* Allocate a segment map big enough to contain
     9         kx 	 all of the sections we have selected.  */
     9         kx       amt = sizeof (struct elf_segment_map) - sizeof (asection *);
     9         kx       amt += section_count * sizeof (asection *);
     9         kx       map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
     9         kx       if (map == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       /* Initialize the fields of the output segment map with the
     9         kx 	 input segment.  */
     9         kx       map->next = NULL;
     9         kx       map->p_type = segment->p_type;
     9         kx       map->p_flags = segment->p_flags;
     9         kx       map->p_flags_valid = 1;
     9         kx       map->p_paddr = segment->p_paddr;
     9         kx       map->p_paddr_valid = p_paddr_valid;
     9         kx       map->p_align = segment->p_align;
     9         kx       /* Keep p_align of PT_GNU_STACK for stack alignment.  */
     9         kx       map->p_align_valid = (map->p_type == PT_GNU_STACK
     9         kx 			    || p_palign_valid);
     9         kx       map->p_vaddr_offset = 0;
     9         kx 
     9         kx       if (map->p_type == PT_GNU_RELRO
     9         kx 	  || map->p_type == PT_GNU_STACK)
     9         kx 	{
     9         kx 	  /* The PT_GNU_RELRO segment may contain the first a few
     9         kx 	     bytes in the .got.plt section even if the whole .got.plt
     9         kx 	     section isn't in the PT_GNU_RELRO segment.  We won't
     9         kx 	     change the size of the PT_GNU_RELRO segment.
     9         kx 	     Similarly, PT_GNU_STACK size is significant on uclinux
     9         kx 	     systems.    */
     9         kx 	  map->p_size = segment->p_memsz;
     9         kx 	  map->p_size_valid = 1;
     9         kx 	}
     9         kx 
     9         kx       /* Determine if this segment contains the ELF file header
     9         kx 	 and if it contains the program headers themselves.  */
     9         kx       map->includes_filehdr = (segment->p_offset == 0
     9         kx 			       && segment->p_filesz >= iehdr->e_ehsize);
     9         kx 
     9         kx       map->includes_phdrs = 0;
     9         kx       if (! phdr_included || segment->p_type != PT_LOAD)
     9         kx 	{
     9         kx 	  map->includes_phdrs =
     9         kx 	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
     9         kx 	     && (segment->p_offset + segment->p_filesz
     9         kx 		 >= ((bfd_vma) iehdr->e_phoff
     9         kx 		     + iehdr->e_phnum * iehdr->e_phentsize)));
     9         kx 
     9         kx 	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
     9         kx 	    phdr_included = true;
     9         kx 	}
     9         kx 
     9         kx       lowest_section = NULL;
     9         kx       if (section_count != 0)
     9         kx 	{
     9         kx 	  unsigned int isec = 0;
     9         kx 
     9         kx 	  for (section = first_section;
     9         kx 	       section != NULL;
     9         kx 	       section = section->next)
     9         kx 	    {
     9         kx 	      this_hdr = &(elf_section_data(section)->this_hdr);
     9         kx 	      if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
     9         kx 		{
     9         kx 		  map->sections[isec++] = section->output_section;
     9         kx 		  if ((section->flags & SEC_ALLOC) != 0)
     9         kx 		    {
     9         kx 		      bfd_vma seg_off;
     9         kx 
     9         kx 		      if (lowest_section == NULL
     9         kx 			  || section->lma < lowest_section->lma)
     9         kx 			lowest_section = section;
     9         kx 
     9         kx 		      /* Section lmas are set up from PT_LOAD header
     9         kx 			 p_paddr in _bfd_elf_make_section_from_shdr.
     9         kx 			 If this header has a p_paddr that disagrees
     9         kx 			 with the section lma, flag the p_paddr as
     9         kx 			 invalid.  */
     9         kx 		      if ((section->flags & SEC_LOAD) != 0)
     9         kx 			seg_off = this_hdr->sh_offset - segment->p_offset;
     9         kx 		      else
     9         kx 			seg_off = this_hdr->sh_addr - segment->p_vaddr;
     9         kx 		      if (section->lma * opb - segment->p_paddr != seg_off)
     9         kx 			map->p_paddr_valid = false;
     9         kx 		    }
     9         kx 		  if (isec == section_count)
     9         kx 		    break;
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       if (section_count == 0)
     9         kx 	map->p_vaddr_offset = segment->p_vaddr / opb;
     9         kx       else if (map->p_paddr_valid)
     9         kx 	{
     9         kx 	  /* Account for padding before the first section in the segment.  */
     9         kx 	  bfd_vma hdr_size = 0;
     9         kx 	  if (map->includes_filehdr)
     9         kx 	    hdr_size = iehdr->e_ehsize;
     9         kx 	  if (map->includes_phdrs)
     9         kx 	    hdr_size += iehdr->e_phnum * iehdr->e_phentsize;
     9         kx 
     9         kx 	  map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
     9         kx 				 - (lowest_section ? lowest_section->lma : 0));
     9         kx 	}
     9         kx 
     9         kx       map->count = section_count;
     9         kx       *pointer_to_map = map;
     9         kx       pointer_to_map = &map->next;
     9         kx     }
     9         kx 
     9         kx   elf_seg_map (obfd) = map_first;
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Copy private BFD data.  This copies or rewrites ELF program header
     9         kx    information.  */
     9         kx 
     9         kx static bool
     9         kx copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     9         kx {
     9         kx   bfd_vma maxpagesize;
     9         kx 
     9         kx   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
     9         kx       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     9         kx     return true;
     9         kx 
     9         kx   if (elf_tdata (ibfd)->phdr == NULL)
     9         kx     return true;
     9         kx 
     9         kx   if (ibfd->xvec == obfd->xvec)
     9         kx     {
     9         kx       /* Check to see if any sections in the input BFD
     9         kx 	 covered by ELF program header have changed.  */
     9         kx       Elf_Internal_Phdr *segment;
     9         kx       asection *section, *osec;
     9         kx       unsigned int i, num_segments;
     9         kx       Elf_Internal_Shdr *this_hdr;
     9         kx       const struct elf_backend_data *bed;
     9         kx 
     9         kx       bed = get_elf_backend_data (ibfd);
     9         kx 
     9         kx       /* Regenerate the segment map if p_paddr is set to 0.  */
     9         kx       if (bed->want_p_paddr_set_to_zero)
     9         kx 	goto rewrite;
     9         kx 
     9         kx       /* Initialize the segment mark field.  */
     9         kx       for (section = obfd->sections; section != NULL;
     9         kx 	   section = section->next)
     9         kx 	section->segment_mark = false;
     9         kx 
     9         kx       num_segments = elf_elfheader (ibfd)->e_phnum;
     9         kx       for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx 	   i < num_segments;
     9         kx 	   i++, segment++)
     9         kx 	{
     9         kx 	  /* PR binutils/3535.  The Solaris linker always sets the p_paddr
     9         kx 	     and p_memsz fields of special segments (DYNAMIC, INTERP) to 0
     9         kx 	     which severly confuses things, so always regenerate the segment
     9         kx 	     map in this case.  */
     9         kx 	  if (segment->p_paddr == 0
     9         kx 	      && segment->p_memsz == 0
     9         kx 	      && (segment->p_type == PT_INTERP
     9         kx 		  || segment->p_type == PT_DYNAMIC))
     9         kx 	    goto rewrite;
     9         kx 
     9         kx 	  for (section = ibfd->sections;
     9         kx 	       section != NULL; section = section->next)
     9         kx 	    {
     9         kx 	      /* We mark the output section so that we know it comes
     9         kx 		 from the input BFD.  */
     9         kx 	      osec = section->output_section;
     9         kx 	      if (osec)
     9         kx 		osec->segment_mark = true;
     9         kx 
     9         kx 	      /* Check if this section is covered by the segment.  */
     9         kx 	      this_hdr = &(elf_section_data(section)->this_hdr);
     9         kx 	      if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
     9         kx 		{
     9         kx 		  /* FIXME: Check if its output section is changed or
     9         kx 		     removed.  What else do we need to check?  */
     9         kx 		  if (osec == NULL
     9         kx 		      || section->flags != osec->flags
     9         kx 		      || section->lma != osec->lma
     9         kx 		      || section->vma != osec->vma
     9         kx 		      || section->size != osec->size
     9         kx 		      || section->rawsize != osec->rawsize
     9         kx 		      || section->alignment_power != osec->alignment_power)
     9         kx 		    goto rewrite;
     9         kx 		}
     9         kx 	    }
     9         kx 	}
     9         kx 
     9         kx       /* Check to see if any output section do not come from the
     9         kx 	 input BFD.  */
     9         kx       for (section = obfd->sections; section != NULL;
     9         kx 	   section = section->next)
     9         kx 	{
     9         kx 	  if (!section->segment_mark)
     9         kx 	    goto rewrite;
     9         kx 	  else
     9         kx 	    section->segment_mark = false;
     9         kx 	}
     9         kx 
     9         kx       return copy_elf_program_header (ibfd, obfd);
     9         kx     }
     9         kx 
     9         kx  rewrite:
     9         kx   maxpagesize = 0;
     9         kx   if (ibfd->xvec == obfd->xvec)
     9         kx     {
     9         kx       /* When rewriting program header, set the output maxpagesize to
     9         kx 	 the maximum alignment of input PT_LOAD segments.  */
     9         kx       Elf_Internal_Phdr *segment;
     9         kx       unsigned int i;
     9         kx       unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;
     9         kx 
     9         kx       for (i = 0, segment = elf_tdata (ibfd)->phdr;
     9         kx 	   i < num_segments;
     9         kx 	   i++, segment++)
     9         kx 	if (segment->p_type == PT_LOAD
     9         kx 	    && maxpagesize < segment->p_align)
     9         kx 	  {
     9         kx 	    /* PR 17512: file: f17299af.  */
     9         kx 	    if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
     9         kx 	      /* xgettext:c-format */
     9         kx 	      _bfd_error_handler (_("%pB: warning: segment alignment of %#"
     9         kx 				    PRIx64 " is too large"),
     9         kx 				  ibfd, (uint64_t) segment->p_align);
     9         kx 	    else
     9         kx 	      maxpagesize = segment->p_align;
     9         kx 	  }
     9         kx     }
     9         kx   if (maxpagesize == 0)
     9         kx     maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
     9         kx 
     9         kx   return rewrite_elf_program_header (ibfd, obfd, maxpagesize);
     9         kx }
     9         kx 
     9         kx /* Initialize private output section information from input section.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_init_private_section_data (bfd *ibfd,
     9         kx 				    asection *isec,
     9         kx 				    bfd *obfd,
     9         kx 				    asection *osec,
     9         kx 				    struct bfd_link_info *link_info)
     9         kx 
     9         kx {
     9         kx   Elf_Internal_Shdr *ihdr, *ohdr;
     9         kx   bool final_link = (link_info != NULL
     9         kx 		     && !bfd_link_relocatable (link_info));
     9         kx 
     9         kx   if (ibfd->xvec->flavour != bfd_target_elf_flavour
     9         kx       || obfd->xvec->flavour != bfd_target_elf_flavour)
     9         kx     return true;
     9         kx 
     9         kx   BFD_ASSERT (elf_section_data (osec) != NULL);
     9         kx 
     9         kx   /* If this is a known ABI section, ELF section type and flags may
     9         kx      have been set up when OSEC was created.  For normal sections we
     9         kx      allow the user to override the type and flags other than
     9         kx      SHF_MASKOS and SHF_MASKPROC.  */
     9         kx   if (elf_section_type (osec) == SHT_PROGBITS
     9         kx       || elf_section_type (osec) == SHT_NOTE
     9         kx       || elf_section_type (osec) == SHT_NOBITS)
     9         kx     elf_section_type (osec) = SHT_NULL;
     9         kx   /* For objcopy and relocatable link, copy the ELF section type from
     9         kx      the input file if the BFD section flags are the same.  (If they
     9         kx      are different the user may be doing something like
     9         kx      "objcopy --set-section-flags .text=alloc,data".)  For a final
     9         kx      link allow some flags that the linker clears to differ.  */
     9         kx   if (elf_section_type (osec) == SHT_NULL
     9         kx       && (osec->flags == isec->flags
     9         kx 	  || (final_link
     9         kx 	      && ((osec->flags ^ isec->flags)
     9         kx 		  & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
     9         kx     elf_section_type (osec) = elf_section_type (isec);
     9         kx 
     9         kx   /* FIXME: Is this correct for all OS/PROC specific flags?  */
     9         kx   elf_section_flags (osec) = (elf_section_flags (isec)
     9         kx 			      & (SHF_MASKOS | SHF_MASKPROC));
     9         kx 
     9         kx   /* Copy sh_info from input for mbind section.  */
     9         kx   if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
     9         kx       && elf_section_flags (isec) & SHF_GNU_MBIND)
     9         kx     elf_section_data (osec)->this_hdr.sh_info
     9         kx       = elf_section_data (isec)->this_hdr.sh_info;
     9         kx 
     9         kx   /* Set things up for objcopy and relocatable link.  The output
     9         kx      SHT_GROUP section will have its elf_next_in_group pointing back
     9         kx      to the input group members.  Ignore linker created group section.
     9         kx      See elfNN_ia64_object_p in elfxx-ia64.c.  */
     9         kx   if ((link_info == NULL
     9         kx        || !link_info->resolve_section_groups)
     9         kx       && (elf_sec_group (isec) == NULL
     9         kx 	  || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0))
     9         kx     {
     9         kx       if (elf_section_flags (isec) & SHF_GROUP)
     9         kx 	elf_section_flags (osec) |= SHF_GROUP;
     9         kx       elf_next_in_group (osec) = elf_next_in_group (isec);
     9         kx       elf_section_data (osec)->group = elf_section_data (isec)->group;
     9         kx     }
     9         kx 
     9         kx   /* If not decompress, preserve SHF_COMPRESSED.  */
     9         kx   if (!final_link && (ibfd->flags & BFD_DECOMPRESS) == 0)
     9         kx     elf_section_flags (osec) |= (elf_section_flags (isec)
     9         kx 				 & SHF_COMPRESSED);
     9         kx 
     9         kx   ihdr = &elf_section_data (isec)->this_hdr;
     9         kx 
     9         kx   /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
     9         kx      don't use the output section of the linked-to section since it
     9         kx      may be NULL at this point.  */
     9         kx   if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
     9         kx     {
     9         kx       ohdr = &elf_section_data (osec)->this_hdr;
     9         kx       ohdr->sh_flags |= SHF_LINK_ORDER;
     9         kx       elf_linked_to_section (osec) = elf_linked_to_section (isec);
     9         kx     }
     9         kx 
     9         kx   osec->use_rela_p = isec->use_rela_p;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Copy private section information.  This copies over the entsize
     9         kx    field, and sometimes the info field.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_copy_private_section_data (bfd *ibfd,
     9         kx 				    asection *isec,
     9         kx 				    bfd *obfd,
     9         kx 				    asection *osec)
     9         kx {
     9         kx   Elf_Internal_Shdr *ihdr, *ohdr;
     9         kx 
     9         kx   if (ibfd->xvec->flavour != bfd_target_elf_flavour
     9         kx       || obfd->xvec->flavour != bfd_target_elf_flavour)
     9         kx     return true;
     9         kx 
     9         kx   ihdr = &elf_section_data (isec)->this_hdr;
     9         kx   ohdr = &elf_section_data (osec)->this_hdr;
     9         kx 
     9         kx   ohdr->sh_entsize = ihdr->sh_entsize;
     9         kx 
     9         kx   if (ihdr->sh_type == SHT_SYMTAB
     9         kx       || ihdr->sh_type == SHT_DYNSYM
     9         kx       || ihdr->sh_type == SHT_GNU_verneed
     9         kx       || ihdr->sh_type == SHT_GNU_verdef)
     9         kx     ohdr->sh_info = ihdr->sh_info;
     9         kx 
     9         kx   return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
     9         kx 					     NULL);
     9         kx }
     9         kx 
     9         kx /* Look at all the SHT_GROUP sections in IBFD, making any adjustments
     9         kx    necessary if we are removing either the SHT_GROUP section or any of
     9         kx    the group member sections.  DISCARDED is the value that a section's
     9         kx    output_section has if the section will be discarded, NULL when this
     9         kx    function is called from objcopy, bfd_abs_section_ptr when called
     9         kx    from the linker.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
     9         kx {
     9         kx   asection *isec;
     9         kx 
     9         kx   for (isec = ibfd->sections; isec != NULL; isec = isec->next)
     9         kx     if (elf_section_type (isec) == SHT_GROUP)
     9         kx       {
     9         kx 	asection *first = elf_next_in_group (isec);
     9         kx 	asection *s = first;
     9         kx 	bfd_size_type removed = 0;
     9         kx 
     9         kx 	while (s != NULL)
     9         kx 	  {
     9         kx 	    /* If this member section is being output but the
     9         kx 	       SHT_GROUP section is not, then clear the group info
     9         kx 	       set up by _bfd_elf_copy_private_section_data.  */
     9         kx 	    if (s->output_section != discarded
     9         kx 		&& isec->output_section == discarded)
     9         kx 	      {
     9         kx 		elf_section_flags (s->output_section) &= ~SHF_GROUP;
     9         kx 		elf_group_name (s->output_section) = NULL;
     9         kx 	      }
     9         kx 	    else
     9         kx 	      {
     9         kx 		struct bfd_elf_section_data *elf_sec = elf_section_data (s);
     9         kx 		if (s->output_section == discarded
     9         kx 		    && isec->output_section != discarded)
     9         kx 		  {
     9         kx 		    /* Conversely, if the member section is not being
     9         kx 		       output but the SHT_GROUP section is, then adjust
     9         kx 		       its size.  */
     9         kx 		    removed += 4;
     9         kx 		    if (elf_sec->rel.hdr != NULL
     9         kx 			&& (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
     9         kx 		      removed += 4;
     9         kx 		    if (elf_sec->rela.hdr != NULL
     9         kx 			&& (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
     9         kx 		      removed += 4;
     9         kx 		  }
     9         kx 		else
     9         kx 		  {
     9         kx 		    /* Also adjust for zero-sized relocation member
     9         kx 		       section.  */
     9         kx 		    if (elf_sec->rel.hdr != NULL
     9         kx 			&& elf_sec->rel.hdr->sh_size == 0)
     9         kx 		      removed += 4;
     9         kx 		    if (elf_sec->rela.hdr != NULL
     9         kx 			&& elf_sec->rela.hdr->sh_size == 0)
     9         kx 		      removed += 4;
     9         kx 		  }
     9         kx 	      }
     9         kx 	    s = elf_next_in_group (s);
     9         kx 	    if (s == first)
     9         kx 	      break;
     9         kx 	  }
     9         kx 	if (removed != 0)
     9         kx 	  {
     9         kx 	    if (discarded != NULL)
     9         kx 	      {
     9         kx 		/* If we've been called for ld -r, then we need to
     9         kx 		   adjust the input section size.  */
     9         kx 		if (isec->rawsize == 0)
     9         kx 		  isec->rawsize = isec->size;
     9         kx 		isec->size = isec->rawsize - removed;
     9         kx 		if (isec->size <= 4)
     9         kx 		  {
     9         kx 		    isec->size = 0;
     9         kx 		    isec->flags |= SEC_EXCLUDE;
     9         kx 		  }
     9         kx 	      }
     9         kx 	    else if (isec->output_section != NULL)
     9         kx 	      {
     9         kx 		/* Adjust the output section size when called from
     9         kx 		   objcopy. */
     9         kx 		isec->output_section->size -= removed;
     9         kx 		if (isec->output_section->size <= 4)
     9         kx 		  {
     9         kx 		    isec->output_section->size = 0;
     9         kx 		    isec->output_section->flags |= SEC_EXCLUDE;
     9         kx 		  }
     9         kx 	      }
     9         kx 	  }
     9         kx       }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Copy private header information.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
     9         kx {
     9         kx   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
     9         kx       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     9         kx     return true;
     9         kx 
     9         kx   /* Copy over private BFD data if it has not already been copied.
     9         kx      This must be done here, rather than in the copy_private_bfd_data
     9         kx      entry point, because the latter is called after the section
     9         kx      contents have been set, which means that the program headers have
     9         kx      already been worked out.  */
     9         kx   if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL)
     9         kx     {
     9         kx       if (! copy_private_bfd_data (ibfd, obfd))
     9         kx 	return false;
     9         kx     }
     9         kx 
     9         kx   return _bfd_elf_fixup_group_sections (ibfd, NULL);
     9         kx }
     9         kx 
     9         kx /* Copy private symbol information.  If this symbol is in a section
     9         kx    which we did not map into a BFD section, try to map the section
     9         kx    index correctly.  We use special macro definitions for the mapped
     9         kx    section indices; these definitions are interpreted by the
     9         kx    swap_out_syms function.  */
     9         kx 
     9         kx #define MAP_ONESYMTAB (SHN_HIOS + 1)
     9         kx #define MAP_DYNSYMTAB (SHN_HIOS + 2)
     9         kx #define MAP_STRTAB    (SHN_HIOS + 3)
     9         kx #define MAP_SHSTRTAB  (SHN_HIOS + 4)
     9         kx #define MAP_SYM_SHNDX (SHN_HIOS + 5)
     9         kx 
     9         kx bool
     9         kx _bfd_elf_copy_private_symbol_data (bfd *ibfd,
     9         kx 				   asymbol *isymarg,
     9         kx 				   bfd *obfd,
     9         kx 				   asymbol *osymarg)
     9         kx {
     9         kx   elf_symbol_type *isym, *osym;
     9         kx 
     9         kx   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
     9         kx       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     9         kx     return true;
     9         kx 
     9         kx   isym = elf_symbol_from (isymarg);
     9         kx   osym = elf_symbol_from (osymarg);
     9         kx 
     9         kx   if (isym != NULL
     9         kx       && isym->internal_elf_sym.st_shndx != 0
     9         kx       && osym != NULL
     9         kx       && bfd_is_abs_section (isym->symbol.section))
     9         kx     {
     9         kx       unsigned int shndx;
     9         kx 
     9         kx       shndx = isym->internal_elf_sym.st_shndx;
     9         kx       if (shndx == elf_onesymtab (ibfd))
     9         kx 	shndx = MAP_ONESYMTAB;
     9         kx       else if (shndx == elf_dynsymtab (ibfd))
     9         kx 	shndx = MAP_DYNSYMTAB;
     9         kx       else if (shndx == elf_strtab_sec (ibfd))
     9         kx 	shndx = MAP_STRTAB;
     9         kx       else if (shndx == elf_shstrtab_sec (ibfd))
     9         kx 	shndx = MAP_SHSTRTAB;
     9         kx       else if (find_section_in_list (shndx, elf_symtab_shndx_list (ibfd)))
     9         kx 	shndx = MAP_SYM_SHNDX;
     9         kx       osym->internal_elf_sym.st_shndx = shndx;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Swap out the symbols.  */
     9         kx 
     9         kx static bool
     9         kx swap_out_syms (bfd *abfd,
     9         kx 	       struct elf_strtab_hash **sttp,
     9         kx 	       int relocatable_p,
     9         kx 	       struct bfd_link_info *info)
     9         kx {
     9         kx   const struct elf_backend_data *bed;
     9         kx   unsigned int symcount;
     9         kx   asymbol **syms;
     9         kx   struct elf_strtab_hash *stt;
     9         kx   Elf_Internal_Shdr *symtab_hdr;
     9         kx   Elf_Internal_Shdr *symtab_shndx_hdr;
     9         kx   Elf_Internal_Shdr *symstrtab_hdr;
     9         kx   struct elf_sym_strtab *symstrtab;
     9         kx   bfd_byte *outbound_syms;
     9         kx   bfd_byte *outbound_shndx;
     9         kx   unsigned long outbound_syms_index;
     9         kx   unsigned int idx;
     9         kx   unsigned int num_locals;
     9         kx   size_t amt;
     9         kx   bool name_local_sections;
     9         kx 
     9         kx   if (!elf_map_symbols (abfd, &num_locals))
     9         kx     return false;
     9         kx 
     9         kx   /* Dump out the symtabs.  */
     9         kx   stt = _bfd_elf_strtab_init ();
     9         kx   if (stt == NULL)
     9         kx     return false;
     9         kx 
     9         kx   bed = get_elf_backend_data (abfd);
     9         kx   symcount = bfd_get_symcount (abfd);
     9         kx   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
     9         kx   symtab_hdr->sh_type = SHT_SYMTAB;
     9         kx   symtab_hdr->sh_entsize = bed->s->sizeof_sym;
     9         kx   symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
     9         kx   symtab_hdr->sh_info = num_locals + 1;
     9         kx   symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
     9         kx 
     9         kx   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
     9         kx   symstrtab_hdr->sh_type = SHT_STRTAB;
     9         kx 
     9         kx   /* Allocate buffer to swap out the .strtab section.  */
     9         kx   if (_bfd_mul_overflow (symcount + 1, sizeof (*symstrtab), &amt)
     9         kx       || (symstrtab = (struct elf_sym_strtab *) bfd_malloc (amt)) == NULL)
     9         kx     {
     9         kx       bfd_set_error (bfd_error_no_memory);
     9         kx       _bfd_elf_strtab_free (stt);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   if (_bfd_mul_overflow (symcount + 1, bed->s->sizeof_sym, &amt)
     9         kx       || (outbound_syms = (bfd_byte *) bfd_alloc (abfd, amt)) == NULL)
     9         kx     {
     9         kx     error_no_mem:
     9         kx       bfd_set_error (bfd_error_no_memory);
     9         kx     error_return:
     9         kx       free (symstrtab);
     9         kx       _bfd_elf_strtab_free (stt);
     9         kx       return false;
     9         kx     }
     9         kx   symtab_hdr->contents = outbound_syms;
     9         kx   outbound_syms_index = 0;
     9         kx 
     9         kx   outbound_shndx = NULL;
     9         kx 
     9         kx   if (elf_symtab_shndx_list (abfd))
     9         kx     {
     9         kx       symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
     9         kx       if (symtab_shndx_hdr->sh_name != 0)
     9         kx 	{
     9         kx 	  if (_bfd_mul_overflow (symcount + 1,
     9         kx 				 sizeof (Elf_External_Sym_Shndx), &amt))
     9         kx 	    goto error_no_mem;
     9         kx 	  outbound_shndx =  (bfd_byte *) bfd_zalloc (abfd, amt);
     9         kx 	  if (outbound_shndx == NULL)
     9         kx 	    goto error_return;
     9         kx 
     9         kx 	  symtab_shndx_hdr->contents = outbound_shndx;
     9         kx 	  symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
     9         kx 	  symtab_shndx_hdr->sh_size = amt;
     9         kx 	  symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
     9         kx 	  symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
     9         kx 	}
     9         kx       /* FIXME: What about any other headers in the list ?  */
     9         kx     }
     9         kx 
     9         kx   /* Now generate the data (for "contents").  */
     9         kx   {
     9         kx     /* Fill in zeroth symbol and swap it out.  */
     9         kx     Elf_Internal_Sym sym;
     9         kx     sym.st_name = 0;
     9         kx     sym.st_value = 0;
     9         kx     sym.st_size = 0;
     9         kx     sym.st_info = 0;
     9         kx     sym.st_other = 0;
     9         kx     sym.st_shndx = SHN_UNDEF;
     9         kx     sym.st_target_internal = 0;
     9         kx     symstrtab[0].sym = sym;
     9         kx     symstrtab[0].dest_index = outbound_syms_index;
     9         kx     outbound_syms_index++;
     9         kx   }
     9         kx 
     9         kx   name_local_sections
     9         kx     = (bed->elf_backend_name_local_section_symbols
     9         kx        && bed->elf_backend_name_local_section_symbols (abfd));
     9         kx 
     9         kx   syms = bfd_get_outsymbols (abfd);
     9         kx   for (idx = 0; idx < symcount;)
     9         kx     {
     9         kx       Elf_Internal_Sym sym;
     9         kx       bfd_vma value = syms[idx]->value;
     9         kx       elf_symbol_type *type_ptr;
     9         kx       flagword flags = syms[idx]->flags;
     9         kx       int type;
     9         kx 
     9         kx       if (!name_local_sections
     9         kx 	  && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
     9         kx 	{
     9         kx 	  /* Local section symbols have no name.  */
     9         kx 	  sym.st_name = (unsigned long) -1;
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
     9         kx 	     to get the final offset for st_name.  */
     9         kx 	  sym.st_name
     9         kx 	    = (unsigned long) _bfd_elf_strtab_add (stt, syms[idx]->name,
     9         kx 						   false);
     9         kx 	  if (sym.st_name == (unsigned long) -1)
     9         kx 	    goto error_return;
     9         kx 	}
     9         kx 
     9         kx       type_ptr = elf_symbol_from (syms[idx]);
     9         kx 
     9         kx       if ((flags & BSF_SECTION_SYM) == 0
     9         kx 	  && bfd_is_com_section (syms[idx]->section))
     9         kx 	{
     9         kx 	  /* ELF common symbols put the alignment into the `value' field,
     9         kx 	     and the size into the `size' field.  This is backwards from
     9         kx 	     how BFD handles it, so reverse it here.  */
     9         kx 	  sym.st_size = value;
     9         kx 	  if (type_ptr == NULL
     9         kx 	      || type_ptr->internal_elf_sym.st_value == 0)
     9         kx 	    sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
     9         kx 	  else
     9         kx 	    sym.st_value = type_ptr->internal_elf_sym.st_value;
     9         kx 	  sym.st_shndx = _bfd_elf_section_from_bfd_section
     9         kx 	    (abfd, syms[idx]->section);
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  asection *sec = syms[idx]->section;
     9         kx 	  unsigned int shndx;
     9         kx 
     9         kx 	  if (sec->output_section)
     9         kx 	    {
     9         kx 	      value += sec->output_offset;
     9         kx 	      sec = sec->output_section;
     9         kx 	    }
     9         kx 
     9         kx 	  /* Don't add in the section vma for relocatable output.  */
     9         kx 	  if (! relocatable_p)
     9         kx 	    value += sec->vma;
     9         kx 	  sym.st_value = value;
     9         kx 	  sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;
     9         kx 
     9         kx 	  if (bfd_is_abs_section (sec)
     9         kx 	      && type_ptr != NULL
     9         kx 	      && type_ptr->internal_elf_sym.st_shndx != 0)
     9         kx 	    {
     9         kx 	      /* This symbol is in a real ELF section which we did
     9         kx 		 not create as a BFD section.  Undo the mapping done
     9         kx 		 by copy_private_symbol_data.  */
     9         kx 	      shndx = type_ptr->internal_elf_sym.st_shndx;
     9         kx 	      switch (shndx)
     9         kx 		{
     9         kx 		case MAP_ONESYMTAB:
     9         kx 		  shndx = elf_onesymtab (abfd);
     9         kx 		  break;
     9         kx 		case MAP_DYNSYMTAB:
     9         kx 		  shndx = elf_dynsymtab (abfd);
     9         kx 		  break;
     9         kx 		case MAP_STRTAB:
     9         kx 		  shndx = elf_strtab_sec (abfd);
     9         kx 		  break;
     9         kx 		case MAP_SHSTRTAB:
     9         kx 		  shndx = elf_shstrtab_sec (abfd);
     9         kx 		  break;
     9         kx 		case MAP_SYM_SHNDX:
     9         kx 		  if (elf_symtab_shndx_list (abfd))
     9         kx 		    shndx = elf_symtab_shndx_list (abfd)->ndx;
     9         kx 		  break;
     9         kx 		case SHN_COMMON:
     9         kx 		case SHN_ABS:
     9         kx 		  shndx = SHN_ABS;
     9         kx 		  break;
     9         kx 		default:
     9         kx 		  if (shndx >= SHN_LOPROC && shndx <= SHN_HIOS)
     9         kx 		    {
     9         kx 		      if (bed->symbol_section_index)
     9         kx 			shndx = bed->symbol_section_index (abfd, type_ptr);
     9         kx 		      /* Otherwise just leave the index alone.  */
     9         kx 		    }
     9         kx 		  else
     9         kx 		    {
     9         kx 		      if (shndx > SHN_HIOS && shndx < SHN_HIRESERVE)
     9         kx 			_bfd_error_handler (_("%pB: \
     9         kx Unable to handle section index %x in ELF symbol.  Using ABS instead."),
     9         kx 					  abfd, shndx);
     9         kx 		      shndx = SHN_ABS;
     9         kx 		    }
     9         kx 		  break;
     9         kx 		}
     9         kx 	    }
     9         kx 	  else
     9         kx 	    {
     9         kx 	      shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
     9         kx 
     9         kx 	      if (shndx == SHN_BAD)
     9         kx 		{
     9         kx 		  asection *sec2;
     9         kx 
     9         kx 		  /* Writing this would be a hell of a lot easier if
     9         kx 		     we had some decent documentation on bfd, and
     9         kx 		     knew what to expect of the library, and what to
     9         kx 		     demand of applications.  For example, it
     9         kx 		     appears that `objcopy' might not set the
     9         kx 		     section of a symbol to be a section that is
     9         kx 		     actually in the output file.  */
     9         kx 		  sec2 = bfd_get_section_by_name (abfd, sec->name);
     9         kx 		  if (sec2 != NULL)
     9         kx 		    shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
     9         kx 		  if (shndx == SHN_BAD)
     9         kx 		    {
     9         kx 		      /* xgettext:c-format */
     9         kx 		      _bfd_error_handler
     9         kx 			(_("unable to find equivalent output section"
     9         kx 			   " for symbol '%s' from section '%s'"),
     9         kx 			 syms[idx]->name ? syms[idx]->name : "<Local sym>",
     9         kx 			 sec->name);
     9         kx 		      bfd_set_error (bfd_error_invalid_operation);
     9         kx 		      goto error_return;
     9         kx 		    }
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  sym.st_shndx = shndx;
     9         kx 	}
     9         kx 
     9         kx       if ((flags & BSF_THREAD_LOCAL) != 0)
     9         kx 	type = STT_TLS;
     9         kx       else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
     9         kx 	type = STT_GNU_IFUNC;
     9         kx       else if ((flags & BSF_FUNCTION) != 0)
     9         kx 	type = STT_FUNC;
     9         kx       else if ((flags & BSF_OBJECT) != 0)
     9         kx 	type = STT_OBJECT;
     9         kx       else if ((flags & BSF_RELC) != 0)
     9         kx 	type = STT_RELC;
     9         kx       else if ((flags & BSF_SRELC) != 0)
     9         kx 	type = STT_SRELC;
     9         kx       else
     9         kx 	type = STT_NOTYPE;
     9         kx 
     9         kx       if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
     9         kx 	type = STT_TLS;
     9         kx 
     9         kx       /* Processor-specific types.  */
     9         kx       if (type_ptr != NULL
     9         kx 	  && bed->elf_backend_get_symbol_type)
     9         kx 	type = ((*bed->elf_backend_get_symbol_type)
     9         kx 		(&type_ptr->internal_elf_sym, type));
     9         kx 
     9         kx       if (flags & BSF_SECTION_SYM)
     9         kx 	{
     9         kx 	  if (flags & BSF_GLOBAL)
     9         kx 	    sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
     9         kx 	  else
     9         kx 	    sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
     9         kx 	}
     9         kx       else if (bfd_is_com_section (syms[idx]->section))
     9         kx 	{
     9         kx 	  if (type != STT_TLS)
     9         kx 	    {
     9         kx 	      if ((abfd->flags & BFD_CONVERT_ELF_COMMON))
     9         kx 		type = ((abfd->flags & BFD_USE_ELF_STT_COMMON)
     9         kx 			? STT_COMMON : STT_OBJECT);
     9         kx 	      else
     9         kx 		type = ((flags & BSF_ELF_COMMON) != 0
     9         kx 			? STT_COMMON : STT_OBJECT);
     9         kx 	    }
     9         kx 	  sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
     9         kx 	}
     9         kx       else if (bfd_is_und_section (syms[idx]->section))
     9         kx 	sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
     9         kx 				    ? STB_WEAK
     9         kx 				    : STB_GLOBAL),
     9         kx 				   type);
     9         kx       else if (flags & BSF_FILE)
     9         kx 	sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
     9         kx       else
     9         kx 	{
     9         kx 	  int bind = STB_LOCAL;
     9         kx 
     9         kx 	  if (flags & BSF_LOCAL)
     9         kx 	    bind = STB_LOCAL;
     9         kx 	  else if (flags & BSF_GNU_UNIQUE)
     9         kx 	    bind = STB_GNU_UNIQUE;
     9         kx 	  else if (flags & BSF_WEAK)
     9         kx 	    bind = STB_WEAK;
     9         kx 	  else if (flags & BSF_GLOBAL)
     9         kx 	    bind = STB_GLOBAL;
     9         kx 
     9         kx 	  sym.st_info = ELF_ST_INFO (bind, type);
     9         kx 	}
     9         kx 
     9         kx       if (type_ptr != NULL)
     9         kx 	{
     9         kx 	  sym.st_other = type_ptr->internal_elf_sym.st_other;
     9         kx 	  sym.st_target_internal
     9         kx 	    = type_ptr->internal_elf_sym.st_target_internal;
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  sym.st_other = 0;
     9         kx 	  sym.st_target_internal = 0;
     9         kx 	}
     9         kx 
     9         kx       idx++;
     9         kx       symstrtab[idx].sym = sym;
     9         kx       symstrtab[idx].dest_index = outbound_syms_index;
     9         kx 
     9         kx       outbound_syms_index++;
     9         kx     }
     9         kx 
     9         kx   /* Finalize the .strtab section.  */
     9         kx   _bfd_elf_strtab_finalize (stt);
     9         kx 
     9         kx   /* Swap out the .strtab section.  */
     9         kx   for (idx = 0; idx <= symcount; idx++)
     9         kx     {
     9         kx       struct elf_sym_strtab *elfsym = &symstrtab[idx];
     9         kx       if (elfsym->sym.st_name == (unsigned long) -1)
     9         kx 	elfsym->sym.st_name = 0;
     9         kx       else
     9         kx 	elfsym->sym.st_name = _bfd_elf_strtab_offset (stt,
     9         kx 						      elfsym->sym.st_name);
     9         kx       if (info && info->callbacks->ctf_new_symbol)
     9         kx 	info->callbacks->ctf_new_symbol (elfsym->dest_index,
     9         kx 					 &elfsym->sym);
     9         kx 
     9         kx       /* Inform the linker of the addition of this symbol.  */
     9         kx 
     9         kx       bed->s->swap_symbol_out (abfd, &elfsym->sym,
     9         kx 			       (outbound_syms
     9         kx 				+ (elfsym->dest_index
     9         kx 				   * bed->s->sizeof_sym)),
     9         kx 			       NPTR_ADD (outbound_shndx,
     9         kx 					 (elfsym->dest_index
     9         kx 					  * sizeof (Elf_External_Sym_Shndx))));
     9         kx     }
     9         kx   free (symstrtab);
     9         kx 
     9         kx   *sttp = stt;
     9         kx   symstrtab_hdr->sh_size = _bfd_elf_strtab_size (stt);
     9         kx   symstrtab_hdr->sh_type = SHT_STRTAB;
     9         kx   symstrtab_hdr->sh_flags = bed->elf_strtab_flags;
     9         kx   symstrtab_hdr->sh_addr = 0;
     9         kx   symstrtab_hdr->sh_entsize = 0;
     9         kx   symstrtab_hdr->sh_link = 0;
     9         kx   symstrtab_hdr->sh_info = 0;
     9         kx   symstrtab_hdr->sh_addralign = 1;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Return the number of bytes required to hold the symtab vector.
     9         kx 
     9         kx    Note that we base it on the count plus 1, since we will null terminate
     9         kx    the vector allocated based on this size.  However, the ELF symbol table
     9         kx    always has a dummy entry as symbol #0, so it ends up even.  */
     9         kx 
     9         kx long
     9         kx _bfd_elf_get_symtab_upper_bound (bfd *abfd)
     9         kx {
     9         kx   bfd_size_type symcount;
     9         kx   long symtab_size;
     9         kx   Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;
     9         kx 
     9         kx   symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
     9         kx   if (symcount > LONG_MAX / sizeof (asymbol *))
     9         kx     {
     9         kx       bfd_set_error (bfd_error_file_too_big);
     9         kx       return -1;
     9         kx     }
     9         kx   symtab_size = symcount * (sizeof (asymbol *));
     9         kx   if (symcount == 0)
     9         kx     symtab_size = sizeof (asymbol *);
     9         kx   else if (!bfd_write_p (abfd))
     9         kx     {
     9         kx       ufile_ptr filesize = bfd_get_file_size (abfd);
     9         kx 
     9         kx       if (filesize != 0 && (unsigned long) symtab_size > filesize)
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_truncated);
     9         kx 	  return -1;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return symtab_size;
     9         kx }
     9         kx 
     9         kx long
     9         kx _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
     9         kx {
     9         kx   bfd_size_type symcount;
     9         kx   long symtab_size;
     9         kx   Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;
     9         kx 
     9         kx   if (elf_dynsymtab (abfd) == 0)
     9         kx     {
     9         kx       bfd_set_error (bfd_error_invalid_operation);
     9         kx       return -1;
     9         kx     }
     9         kx 
     9         kx   symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
     9         kx   if (symcount > LONG_MAX / sizeof (asymbol *))
     9         kx     {
     9         kx       bfd_set_error (bfd_error_file_too_big);
     9         kx       return -1;
     9         kx     }
     9         kx   symtab_size = symcount * (sizeof (asymbol *));
     9         kx   if (symcount == 0)
     9         kx     symtab_size = sizeof (asymbol *);
     9         kx   else if (!bfd_write_p (abfd))
     9         kx     {
     9         kx       ufile_ptr filesize = bfd_get_file_size (abfd);
     9         kx 
     9         kx       if (filesize != 0 && (unsigned long) symtab_size > filesize)
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_truncated);
     9         kx 	  return -1;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return symtab_size;
     9         kx }
     9         kx 
     9         kx long
     9         kx _bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
     9         kx {
     9         kx   if (asect->reloc_count != 0 && !bfd_write_p (abfd))
     9         kx     {
     9         kx       /* Sanity check reloc section size.  */
     9         kx       ufile_ptr filesize = bfd_get_file_size (abfd);
     9         kx 
     9         kx       if (filesize != 0)
     9         kx 	{
     9         kx 	  struct bfd_elf_section_data *d = elf_section_data (asect);
     9         kx 	  bfd_size_type rel_size = d->rel.hdr ? d->rel.hdr->sh_size : 0;
     9         kx 	  bfd_size_type rela_size = d->rela.hdr ? d->rela.hdr->sh_size : 0;
     9         kx 
     9         kx 	  if (rel_size + rela_size > filesize
     9         kx 	      || rel_size + rela_size < rel_size)
     9         kx 	    {
     9         kx 	      bfd_set_error (bfd_error_file_truncated);
     9         kx 	      return -1;
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx #if SIZEOF_LONG == SIZEOF_INT
     9         kx   if (asect->reloc_count >= LONG_MAX / sizeof (arelent *))
     9         kx     {
     9         kx       bfd_set_error (bfd_error_file_too_big);
     9         kx       return -1;
     9         kx     }
     9         kx #endif
     9         kx   return (asect->reloc_count + 1L) * sizeof (arelent *);
     9         kx }
     9         kx 
     9         kx /* Canonicalize the relocs.  */
     9         kx 
     9         kx long
     9         kx _bfd_elf_canonicalize_reloc (bfd *abfd,
     9         kx 			     sec_ptr section,
     9         kx 			     arelent **relptr,
     9         kx 			     asymbol **symbols)
     9         kx {
     9         kx   arelent *tblptr;
     9         kx   unsigned int i;
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   if (! bed->s->slurp_reloc_table (abfd, section, symbols, false))
     9         kx     return -1;
     9         kx 
     9         kx   tblptr = section->relocation;
     9         kx   for (i = 0; i < section->reloc_count; i++)
     9         kx     *relptr++ = tblptr++;
     9         kx 
     9         kx   *relptr = NULL;
     9         kx 
     9         kx   return section->reloc_count;
     9         kx }
     9         kx 
     9         kx long
     9         kx _bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   long symcount = bed->s->slurp_symbol_table (abfd, allocation, false);
     9         kx 
     9         kx   if (symcount >= 0)
     9         kx     abfd->symcount = symcount;
     9         kx   return symcount;
     9         kx }
     9         kx 
     9         kx long
     9         kx _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
     9         kx 				      asymbol **allocation)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   long symcount = bed->s->slurp_symbol_table (abfd, allocation, true);
     9         kx 
     9         kx   if (symcount >= 0)
     9         kx     abfd->dynsymcount = symcount;
     9         kx   return symcount;
     9         kx }
     9         kx 
     9         kx /* Return the size required for the dynamic reloc entries.  Any loadable
     9         kx    section that was actually installed in the BFD, and has type SHT_REL
     9         kx    or SHT_RELA, and uses the dynamic symbol table, is considered to be a
     9         kx    dynamic reloc section.  */
     9         kx 
     9         kx long
     9         kx _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
     9         kx {
     9         kx   bfd_size_type count, ext_rel_size;
     9         kx   asection *s;
     9         kx 
     9         kx   if (elf_dynsymtab (abfd) == 0)
     9         kx     {
     9         kx       bfd_set_error (bfd_error_invalid_operation);
     9         kx       return -1;
     9         kx     }
     9         kx 
     9         kx   count = 1;
     9         kx   ext_rel_size = 0;
     9         kx   for (s = abfd->sections; s != NULL; s = s->next)
     9         kx     if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
     9         kx 	&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
     9         kx 	    || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
     9         kx       {
     9         kx 	ext_rel_size += s->size;
     9         kx 	if (ext_rel_size < s->size)
     9         kx 	  {
     9         kx 	    bfd_set_error (bfd_error_file_truncated);
     9         kx 	    return -1;
     9         kx 	  }
     9         kx 	count += s->size / elf_section_data (s)->this_hdr.sh_entsize;
     9         kx 	if (count > LONG_MAX / sizeof (arelent *))
     9         kx 	  {
     9         kx 	    bfd_set_error (bfd_error_file_too_big);
     9         kx 	    return -1;
     9         kx 	  }
     9         kx       }
     9         kx   if (count > 1 && !bfd_write_p (abfd))
     9         kx     {
     9         kx       /* Sanity check reloc section sizes.  */
     9         kx       ufile_ptr filesize = bfd_get_file_size (abfd);
     9         kx       if (filesize != 0 && ext_rel_size > filesize)
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_truncated);
     9         kx 	  return -1;
     9         kx 	}
     9         kx     }
     9         kx   return count * sizeof (arelent *);
     9         kx }
     9         kx 
     9         kx /* Canonicalize the dynamic relocation entries.  Note that we return the
     9         kx    dynamic relocations as a single block, although they are actually
     9         kx    associated with particular sections; the interface, which was
     9         kx    designed for SunOS style shared libraries, expects that there is only
     9         kx    one set of dynamic relocs.  Any loadable section that was actually
     9         kx    installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the
     9         kx    dynamic symbol table, is considered to be a dynamic reloc section.  */
     9         kx 
     9         kx long
     9         kx _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
     9         kx 				     arelent **storage,
     9         kx 				     asymbol **syms)
     9         kx {
     9         kx   bool (*slurp_relocs) (bfd *, asection *, asymbol **, bool);
     9         kx   asection *s;
     9         kx   long ret;
     9         kx 
     9         kx   if (elf_dynsymtab (abfd) == 0)
     9         kx     {
     9         kx       bfd_set_error (bfd_error_invalid_operation);
     9         kx       return -1;
     9         kx     }
     9         kx 
     9         kx   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
     9         kx   ret = 0;
     9         kx   for (s = abfd->sections; s != NULL; s = s->next)
     9         kx     {
     9         kx       if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
     9         kx 	  && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
     9         kx 	      || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
     9         kx 	{
     9         kx 	  arelent *p;
     9         kx 	  long count, i;
     9         kx 
     9         kx 	  if (! (*slurp_relocs) (abfd, s, syms, true))
     9         kx 	    return -1;
     9         kx 	  count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
     9         kx 	  p = s->relocation;
     9         kx 	  for (i = 0; i < count; i++)
     9         kx 	    *storage++ = p++;
     9         kx 	  ret += count;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   *storage = NULL;
     9         kx 
     9         kx   return ret;
     9         kx }
     9         kx 
     9         kx /* Read in the version information.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_slurp_version_tables (bfd *abfd, bool default_imported_symver)
     9         kx {
     9         kx   bfd_byte *contents = NULL;
     9         kx   unsigned int freeidx = 0;
     9         kx   size_t amt;
     9         kx 
     9         kx   if (elf_dynverref (abfd) != 0)
     9         kx     {
     9         kx       Elf_Internal_Shdr *hdr;
     9         kx       Elf_External_Verneed *everneed;
     9         kx       Elf_Internal_Verneed *iverneed;
     9         kx       unsigned int i;
     9         kx       bfd_byte *contents_end;
     9         kx 
     9         kx       hdr = &elf_tdata (abfd)->dynverref_hdr;
     9         kx 
     9         kx       if (hdr->sh_info > hdr->sh_size / sizeof (Elf_External_Verneed))
     9         kx 	{
     9         kx 	error_return_bad_verref:
     9         kx 	  _bfd_error_handler
     9         kx 	    (_("%pB: .gnu.version_r invalid entry"), abfd);
     9         kx 	  bfd_set_error (bfd_error_bad_value);
     9         kx 	error_return_verref:
     9         kx 	  elf_tdata (abfd)->verref = NULL;
     9         kx 	  elf_tdata (abfd)->cverrefs = 0;
     9         kx 	  goto error_return;
     9         kx 	}
     9         kx 
     9         kx       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
     9         kx 	goto error_return_verref;
     9         kx       contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
     9         kx       if (contents == NULL)
     9         kx 	goto error_return_verref;
     9         kx 
     9         kx       if (_bfd_mul_overflow (hdr->sh_info, sizeof (Elf_Internal_Verneed), &amt))
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_too_big);
     9         kx 	  goto error_return_verref;
     9         kx 	}
     9         kx       if (amt == 0)
     9         kx 	goto error_return_verref;
     9         kx       elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) bfd_zalloc (abfd, amt);
     9         kx       if (elf_tdata (abfd)->verref == NULL)
     9         kx 	goto error_return_verref;
     9         kx 
     9         kx       BFD_ASSERT (sizeof (Elf_External_Verneed)
     9         kx 		  == sizeof (Elf_External_Vernaux));
     9         kx       contents_end = contents + hdr->sh_size - sizeof (Elf_External_Verneed);
     9         kx       everneed = (Elf_External_Verneed *) contents;
     9         kx       iverneed = elf_tdata (abfd)->verref;
     9         kx       for (i = 0; i < hdr->sh_info; i++, iverneed++)
     9         kx 	{
     9         kx 	  Elf_External_Vernaux *evernaux;
     9         kx 	  Elf_Internal_Vernaux *ivernaux;
     9         kx 	  unsigned int j;
     9         kx 
     9         kx 	  _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);
     9         kx 
     9         kx 	  iverneed->vn_bfd = abfd;
     9         kx 
     9         kx 	  iverneed->vn_filename =
     9         kx 	    bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
     9         kx 					     iverneed->vn_file);
     9         kx 	  if (iverneed->vn_filename == NULL)
     9         kx 	    goto error_return_bad_verref;
     9         kx 
     9         kx 	  if (iverneed->vn_cnt == 0)
     9         kx 	    iverneed->vn_auxptr = NULL;
     9         kx 	  else
     9         kx 	    {
     9         kx 	      if (_bfd_mul_overflow (iverneed->vn_cnt,
     9         kx 				     sizeof (Elf_Internal_Vernaux), &amt))
     9         kx 		{
     9         kx 		  bfd_set_error (bfd_error_file_too_big);
     9         kx 		  goto error_return_verref;
     9         kx 		}
     9         kx 	      iverneed->vn_auxptr = (struct elf_internal_vernaux *)
     9         kx 		bfd_alloc (abfd, amt);
     9         kx 	      if (iverneed->vn_auxptr == NULL)
     9         kx 		goto error_return_verref;
     9         kx 	    }
     9         kx 
     9         kx 	  if (iverneed->vn_aux
     9         kx 	      > (size_t) (contents_end - (bfd_byte *) everneed))
     9         kx 	    goto error_return_bad_verref;
     9         kx 
     9         kx 	  evernaux = ((Elf_External_Vernaux *)
     9         kx 		      ((bfd_byte *) everneed + iverneed->vn_aux));
     9         kx 	  ivernaux = iverneed->vn_auxptr;
     9         kx 	  for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
     9         kx 	    {
     9         kx 	      _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);
     9         kx 
     9         kx 	      ivernaux->vna_nodename =
     9         kx 		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
     9         kx 						 ivernaux->vna_name);
     9         kx 	      if (ivernaux->vna_nodename == NULL)
     9         kx 		goto error_return_bad_verref;
     9         kx 
     9         kx 	      if (ivernaux->vna_other > freeidx)
     9         kx 		freeidx = ivernaux->vna_other;
     9         kx 
     9         kx 	      ivernaux->vna_nextptr = NULL;
     9         kx 	      if (ivernaux->vna_next == 0)
     9         kx 		{
     9         kx 		  iverneed->vn_cnt = j + 1;
     9         kx 		  break;
     9         kx 		}
     9         kx 	      if (j + 1 < iverneed->vn_cnt)
     9         kx 		ivernaux->vna_nextptr = ivernaux + 1;
     9         kx 
     9         kx 	      if (ivernaux->vna_next
     9         kx 		  > (size_t) (contents_end - (bfd_byte *) evernaux))
     9         kx 		goto error_return_bad_verref;
     9         kx 
     9         kx 	      evernaux = ((Elf_External_Vernaux *)
     9         kx 			  ((bfd_byte *) evernaux + ivernaux->vna_next));
     9         kx 	    }
     9         kx 
     9         kx 	  iverneed->vn_nextref = NULL;
     9         kx 	  if (iverneed->vn_next == 0)
     9         kx 	    break;
     9         kx 	  if (i + 1 < hdr->sh_info)
     9         kx 	    iverneed->vn_nextref = iverneed + 1;
     9         kx 
     9         kx 	  if (iverneed->vn_next
     9         kx 	      > (size_t) (contents_end - (bfd_byte *) everneed))
     9         kx 	    goto error_return_bad_verref;
     9         kx 
     9         kx 	  everneed = ((Elf_External_Verneed *)
     9         kx 		      ((bfd_byte *) everneed + iverneed->vn_next));
     9         kx 	}
     9         kx       elf_tdata (abfd)->cverrefs = i;
     9         kx 
     9         kx       free (contents);
     9         kx       contents = NULL;
     9         kx     }
     9         kx 
     9         kx   if (elf_dynverdef (abfd) != 0)
     9         kx     {
     9         kx       Elf_Internal_Shdr *hdr;
     9         kx       Elf_External_Verdef *everdef;
     9         kx       Elf_Internal_Verdef *iverdef;
     9         kx       Elf_Internal_Verdef *iverdefarr;
     9         kx       Elf_Internal_Verdef iverdefmem;
     9         kx       unsigned int i;
     9         kx       unsigned int maxidx;
     9         kx       bfd_byte *contents_end_def, *contents_end_aux;
     9         kx 
     9         kx       hdr = &elf_tdata (abfd)->dynverdef_hdr;
     9         kx 
     9         kx       if (hdr->sh_size < sizeof (Elf_External_Verdef))
     9         kx 	{
     9         kx 	error_return_bad_verdef:
     9         kx 	  _bfd_error_handler
     9         kx 	    (_("%pB: .gnu.version_d invalid entry"), abfd);
     9         kx 	  bfd_set_error (bfd_error_bad_value);
     9         kx 	error_return_verdef:
     9         kx 	  elf_tdata (abfd)->verdef = NULL;
     9         kx 	  elf_tdata (abfd)->cverdefs = 0;
     9         kx 	  goto error_return;
     9         kx 	}
     9         kx 
     9         kx       if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
     9         kx 	goto error_return_verdef;
     9         kx       contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
     9         kx       if (contents == NULL)
     9         kx 	goto error_return_verdef;
     9         kx 
     9         kx       BFD_ASSERT (sizeof (Elf_External_Verdef)
     9         kx 		  >= sizeof (Elf_External_Verdaux));
     9         kx       contents_end_def = contents + hdr->sh_size
     9         kx 			 - sizeof (Elf_External_Verdef);
     9         kx       contents_end_aux = contents + hdr->sh_size
     9         kx 			 - sizeof (Elf_External_Verdaux);
     9         kx 
     9         kx       /* We know the number of entries in the section but not the maximum
     9         kx 	 index.  Therefore we have to run through all entries and find
     9         kx 	 the maximum.  */
     9         kx       everdef = (Elf_External_Verdef *) contents;
     9         kx       maxidx = 0;
     9         kx       for (i = 0; i < hdr->sh_info; ++i)
     9         kx 	{
     9         kx 	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
     9         kx 
     9         kx 	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) == 0)
     9         kx 	    goto error_return_bad_verdef;
     9         kx 	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
     9         kx 	    maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
     9         kx 
     9         kx 	  if (iverdefmem.vd_next == 0)
     9         kx 	    break;
     9         kx 
     9         kx 	  if (iverdefmem.vd_next
     9         kx 	      > (size_t) (contents_end_def - (bfd_byte *) everdef))
     9         kx 	    goto error_return_bad_verdef;
     9         kx 
     9         kx 	  everdef = ((Elf_External_Verdef *)
     9         kx 		     ((bfd_byte *) everdef + iverdefmem.vd_next));
     9         kx 	}
     9         kx 
     9         kx       if (default_imported_symver)
     9         kx 	{
     9         kx 	  if (freeidx > maxidx)
     9         kx 	    maxidx = ++freeidx;
     9         kx 	  else
     9         kx 	    freeidx = ++maxidx;
     9         kx 	}
     9         kx       if (_bfd_mul_overflow (maxidx, sizeof (Elf_Internal_Verdef), &amt))
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_too_big);
     9         kx 	  goto error_return_verdef;
     9         kx 	}
     9         kx       elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
     9         kx       if (elf_tdata (abfd)->verdef == NULL)
     9         kx 	goto error_return_verdef;
     9         kx 
     9         kx       elf_tdata (abfd)->cverdefs = maxidx;
     9         kx 
     9         kx       everdef = (Elf_External_Verdef *) contents;
     9         kx       iverdefarr = elf_tdata (abfd)->verdef;
     9         kx       for (i = 0; i < hdr->sh_info; i++)
     9         kx 	{
     9         kx 	  Elf_External_Verdaux *everdaux;
     9         kx 	  Elf_Internal_Verdaux *iverdaux;
     9         kx 	  unsigned int j;
     9         kx 
     9         kx 	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
     9         kx 
     9         kx 	  if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
     9         kx 	    goto error_return_bad_verdef;
     9         kx 
     9         kx 	  iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
     9         kx 	  memcpy (iverdef, &iverdefmem, offsetof (Elf_Internal_Verdef, vd_bfd));
     9         kx 
     9         kx 	  iverdef->vd_bfd = abfd;
     9         kx 
     9         kx 	  if (iverdef->vd_cnt == 0)
     9         kx 	    iverdef->vd_auxptr = NULL;
     9         kx 	  else
     9         kx 	    {
     9         kx 	      if (_bfd_mul_overflow (iverdef->vd_cnt,
     9         kx 				     sizeof (Elf_Internal_Verdaux), &amt))
     9         kx 		{
     9         kx 		  bfd_set_error (bfd_error_file_too_big);
     9         kx 		  goto error_return_verdef;
     9         kx 		}
     9         kx 	      iverdef->vd_auxptr = (struct elf_internal_verdaux *)
     9         kx 		bfd_alloc (abfd, amt);
     9         kx 	      if (iverdef->vd_auxptr == NULL)
     9         kx 		goto error_return_verdef;
     9         kx 	    }
     9         kx 
     9         kx 	  if (iverdef->vd_aux
     9         kx 	      > (size_t) (contents_end_aux - (bfd_byte *) everdef))
     9         kx 	    goto error_return_bad_verdef;
     9         kx 
     9         kx 	  everdaux = ((Elf_External_Verdaux *)
     9         kx 		      ((bfd_byte *) everdef + iverdef->vd_aux));
     9         kx 	  iverdaux = iverdef->vd_auxptr;
     9         kx 	  for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
     9         kx 	    {
     9         kx 	      _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);
     9         kx 
     9         kx 	      iverdaux->vda_nodename =
     9         kx 		bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
     9         kx 						 iverdaux->vda_name);
     9         kx 	      if (iverdaux->vda_nodename == NULL)
     9         kx 		goto error_return_bad_verdef;
     9         kx 
     9         kx 	      iverdaux->vda_nextptr = NULL;
     9         kx 	      if (iverdaux->vda_next == 0)
     9         kx 		{
     9         kx 		  iverdef->vd_cnt = j + 1;
     9         kx 		  break;
     9         kx 		}
     9         kx 	      if (j + 1 < iverdef->vd_cnt)
     9         kx 		iverdaux->vda_nextptr = iverdaux + 1;
     9         kx 
     9         kx 	      if (iverdaux->vda_next
     9         kx 		  > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
     9         kx 		goto error_return_bad_verdef;
     9         kx 
     9         kx 	      everdaux = ((Elf_External_Verdaux *)
     9         kx 			  ((bfd_byte *) everdaux + iverdaux->vda_next));
     9         kx 	    }
     9         kx 
     9         kx 	  iverdef->vd_nodename = NULL;
     9         kx 	  if (iverdef->vd_cnt)
     9         kx 	    iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
     9         kx 
     9         kx 	  iverdef->vd_nextdef = NULL;
     9         kx 	  if (iverdef->vd_next == 0)
     9         kx 	    break;
     9         kx 	  if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
     9         kx 	    iverdef->vd_nextdef = iverdef + 1;
     9         kx 
     9         kx 	  everdef = ((Elf_External_Verdef *)
     9         kx 		     ((bfd_byte *) everdef + iverdef->vd_next));
     9         kx 	}
     9         kx 
     9         kx       free (contents);
     9         kx       contents = NULL;
     9         kx     }
     9         kx   else if (default_imported_symver)
     9         kx     {
     9         kx       if (freeidx < 3)
     9         kx 	freeidx = 3;
     9         kx       else
     9         kx 	freeidx++;
     9         kx 
     9         kx       if (_bfd_mul_overflow (freeidx, sizeof (Elf_Internal_Verdef), &amt))
     9         kx 	{
     9         kx 	  bfd_set_error (bfd_error_file_too_big);
     9         kx 	  goto error_return;
     9         kx 	}
     9         kx       elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
     9         kx       if (elf_tdata (abfd)->verdef == NULL)
     9         kx 	goto error_return;
     9         kx 
     9         kx       elf_tdata (abfd)->cverdefs = freeidx;
     9         kx     }
     9         kx 
     9         kx   /* Create a default version based on the soname.  */
     9         kx   if (default_imported_symver)
     9         kx     {
     9         kx       Elf_Internal_Verdef *iverdef;
     9         kx       Elf_Internal_Verdaux *iverdaux;
     9         kx 
     9         kx       iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];
     9         kx 
     9         kx       iverdef->vd_version = VER_DEF_CURRENT;
     9         kx       iverdef->vd_flags = 0;
     9         kx       iverdef->vd_ndx = freeidx;
     9         kx       iverdef->vd_cnt = 1;
     9         kx 
     9         kx       iverdef->vd_bfd = abfd;
     9         kx 
     9         kx       iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
     9         kx       if (iverdef->vd_nodename == NULL)
     9         kx 	goto error_return_verdef;
     9         kx       iverdef->vd_nextdef = NULL;
     9         kx       iverdef->vd_auxptr = ((struct elf_internal_verdaux *)
     9         kx 			    bfd_zalloc (abfd, sizeof (Elf_Internal_Verdaux)));
     9         kx       if (iverdef->vd_auxptr == NULL)
     9         kx 	goto error_return_verdef;
     9         kx 
     9         kx       iverdaux = iverdef->vd_auxptr;
     9         kx       iverdaux->vda_nodename = iverdef->vd_nodename;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx 
     9         kx  error_return:
     9         kx   free (contents);
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx asymbol *
     9         kx _bfd_elf_make_empty_symbol (bfd *abfd)
     9         kx {
     9         kx   elf_symbol_type *newsym;
     9         kx 
     9         kx   newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (*newsym));
     9         kx   if (!newsym)
     9         kx     return NULL;
     9         kx   newsym->symbol.the_bfd = abfd;
     9         kx   return &newsym->symbol;
     9         kx }
     9         kx 
     9         kx void
     9         kx _bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
     9         kx 			  asymbol *symbol,
     9         kx 			  symbol_info *ret)
     9         kx {
     9         kx   bfd_symbol_info (symbol, ret);
     9         kx }
     9         kx 
     9         kx /* Return whether a symbol name implies a local symbol.  Most targets
     9         kx    use this function for the is_local_label_name entry point, but some
     9         kx    override it.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
     9         kx 			      const char *name)
     9         kx {
     9         kx   /* Normal local symbols start with ``.L''.  */
     9         kx   if (name[0] == '.' && name[1] == 'L')
     9         kx     return true;
     9         kx 
     9         kx   /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
     9         kx      DWARF debugging symbols starting with ``..''.  */
     9         kx   if (name[0] == '.' && name[1] == '.')
     9         kx     return true;
     9         kx 
     9         kx   /* gcc will sometimes generate symbols beginning with ``_.L_'' when
     9         kx      emitting DWARF debugging output.  I suspect this is actually a
     9         kx      small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
     9         kx      ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
     9         kx      underscore to be emitted on some ELF targets).  For ease of use,
     9         kx      we treat such symbols as local.  */
     9         kx   if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
     9         kx     return true;
     9         kx 
     9         kx   /* Treat assembler generated fake symbols, dollar local labels and
     9         kx      forward-backward labels (aka local labels) as locals.
     9         kx      These labels have the form:
     9         kx 
     9         kx        L0^A.*				       (fake symbols)
     9         kx 
     9         kx        [.]?L[0123456789]+{^A|^B}[0123456789]*  (local labels)
     9         kx 
     9         kx      Versions which start with .L will have already been matched above,
     9         kx      so we only need to match the rest.  */
     9         kx   if (name[0] == 'L' && ISDIGIT (name[1]))
     9         kx     {
     9         kx       bool ret = false;
     9         kx       const char * p;
     9         kx       char c;
     9         kx 
     9         kx       for (p = name + 2; (c = *p); p++)
     9         kx 	{
     9         kx 	  if (c == 1 || c == 2)
     9         kx 	    {
     9         kx 	      if (c == 1 && p == name + 2)
     9         kx 		/* A fake symbol.  */
     9         kx 		return true;
     9         kx 
     9         kx 	      /* FIXME: We are being paranoid here and treating symbols like
     9         kx 		 L0^Bfoo as if there were non-local, on the grounds that the
     9         kx 		 assembler will never generate them.  But can any symbol
     9         kx 		 containing an ASCII value in the range 1-31 ever be anything
     9         kx 		 other than some kind of local ?  */
     9         kx 	      ret = true;
     9         kx 	    }
     9         kx 
     9         kx 	  if (! ISDIGIT (c))
     9         kx 	    {
     9         kx 	      ret = false;
     9         kx 	      break;
     9         kx 	    }
     9         kx 	}
     9         kx       return ret;
     9         kx     }
     9         kx 
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx alent *
     9         kx _bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED,
     9         kx 		     asymbol *symbol ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   abort ();
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_set_arch_mach (bfd *abfd,
     9         kx 			enum bfd_architecture arch,
     9         kx 			unsigned long machine)
     9         kx {
     9         kx   /* If this isn't the right architecture for this backend, and this
     9         kx      isn't the generic backend, fail.  */
     9         kx   if (arch != get_elf_backend_data (abfd)->arch
     9         kx       && arch != bfd_arch_unknown
     9         kx       && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
     9         kx     return false;
     9         kx 
     9         kx   return bfd_default_set_arch_mach (abfd, arch, machine);
     9         kx }
     9         kx 
     9         kx /* Find the nearest line to a particular section and offset,
     9         kx    for error reporting.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_find_nearest_line (bfd *abfd,
     9         kx 			    asymbol **symbols,
     9         kx 			    asection *section,
     9         kx 			    bfd_vma offset,
     9         kx 			    const char **filename_ptr,
     9         kx 			    const char **functionname_ptr,
     9         kx 			    unsigned int *line_ptr,
     9         kx 			    unsigned int *discriminator_ptr)
     9         kx {
     9         kx   return _bfd_elf_find_nearest_line_with_alt (abfd, NULL, symbols, section,
     9         kx 					      offset, filename_ptr,
     9         kx 					      functionname_ptr, line_ptr,
     9         kx 					      discriminator_ptr);
     9         kx }
     9         kx 
     9         kx /* Find the nearest line to a particular section and offset,
     9         kx    for error reporting.  ALT_BFD representing a .gnu_debugaltlink file
     9         kx    can be optionally specified.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_find_nearest_line_with_alt (bfd *abfd,
     9         kx 				     const char *alt_filename,
     9         kx 				     asymbol **symbols,
     9         kx 				     asection *section,
     9         kx 				     bfd_vma offset,
     9         kx 				     const char **filename_ptr,
     9         kx 				     const char **functionname_ptr,
     9         kx 				     unsigned int *line_ptr,
     9         kx 				     unsigned int *discriminator_ptr)
     9         kx {
     9         kx   bool found;
     9         kx 
     9         kx   if (_bfd_dwarf2_find_nearest_line_with_alt (abfd, alt_filename, symbols, NULL,
     9         kx 					      section, offset, filename_ptr,
     9         kx 					      functionname_ptr, line_ptr,
     9         kx 					      discriminator_ptr,
     9         kx 					      dwarf_debug_sections,
     9         kx 					      &elf_tdata (abfd)->dwarf2_find_line_info))
     9         kx     return true;
     9         kx 
     9         kx   if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
     9         kx 				     filename_ptr, functionname_ptr, line_ptr))
     9         kx     {
     9         kx       if (!*functionname_ptr)
     9         kx 	_bfd_elf_find_function (abfd, symbols, section, offset,
     9         kx 				*filename_ptr ? NULL : filename_ptr,
     9         kx 				functionname_ptr);
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
     9         kx 					     &found, filename_ptr,
     9         kx 					     functionname_ptr, line_ptr,
     9         kx 					     &elf_tdata (abfd)->line_info))
     9         kx     return false;
     9         kx   if (found && (*functionname_ptr || *line_ptr))
     9         kx     return true;
     9         kx 
     9         kx   if (symbols == NULL)
     9         kx     return false;
     9         kx 
     9         kx   if (! _bfd_elf_find_function (abfd, symbols, section, offset,
     9         kx 				filename_ptr, functionname_ptr))
     9         kx     return false;
     9         kx 
     9         kx   *line_ptr = 0;
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Find the line for a symbol.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
     9         kx 		    const char **filename_ptr, unsigned int *line_ptr)
     9         kx {
     9         kx   struct elf_obj_tdata *tdata = elf_tdata (abfd);
     9         kx   return _bfd_dwarf2_find_nearest_line (abfd, symbols, symbol, NULL, 0,
     9         kx 					filename_ptr, NULL, line_ptr, NULL,
     9         kx 					dwarf_debug_sections,
     9         kx 					&tdata->dwarf2_find_line_info);
     9         kx }
     9         kx 
     9         kx /* After a call to bfd_find_nearest_line, successive calls to
     9         kx    bfd_find_inliner_info can be used to get source information about
     9         kx    each level of function inlining that terminated at the address
     9         kx    passed to bfd_find_nearest_line.  Currently this is only supported
     9         kx    for DWARF2 with appropriate DWARF3 extensions. */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_find_inliner_info (bfd *abfd,
     9         kx 			    const char **filename_ptr,
     9         kx 			    const char **functionname_ptr,
     9         kx 			    unsigned int *line_ptr)
     9         kx {
     9         kx   struct elf_obj_tdata *tdata = elf_tdata (abfd);
     9         kx   return _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
     9         kx 					functionname_ptr, line_ptr,
     9         kx 					&tdata->dwarf2_find_line_info);
     9         kx }
     9         kx 
     9         kx int
     9         kx _bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   int ret = bed->s->sizeof_ehdr;
     9         kx 
     9         kx   if (!bfd_link_relocatable (info))
     9         kx     {
     9         kx       bfd_size_type phdr_size = elf_program_header_size (abfd);
     9         kx 
     9         kx       if (phdr_size == (bfd_size_type) -1)
     9         kx 	{
     9         kx 	  struct elf_segment_map *m;
     9         kx 
     9         kx 	  phdr_size = 0;
     9         kx 	  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
     9         kx 	    phdr_size += bed->s->sizeof_phdr;
     9         kx 
     9         kx 	  if (phdr_size == 0)
     9         kx 	    phdr_size = get_program_header_size (abfd, info);
     9         kx 	}
     9         kx 
     9         kx       elf_program_header_size (abfd) = phdr_size;
     9         kx       ret += phdr_size;
     9         kx     }
     9         kx 
     9         kx   return ret;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_set_section_contents (bfd *abfd,
     9         kx 			       sec_ptr section,
     9         kx 			       const void *location,
     9         kx 			       file_ptr offset,
     9         kx 			       bfd_size_type count)
     9         kx {
     9         kx   Elf_Internal_Shdr *hdr;
     9         kx 
     9         kx   if (! abfd->output_has_begun
     9         kx       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     9         kx     return false;
     9         kx 
     9         kx   if (!count)
     9         kx     return true;
     9         kx 
     9         kx   hdr = &elf_section_data (section)->this_hdr;
     9         kx   if (hdr->sh_offset == (file_ptr) -1)
     9         kx     {
     9         kx       unsigned char *contents;
     9         kx 
     9         kx       if (bfd_section_is_ctf (section))
     9         kx 	/* Nothing to do with this section: the contents are generated
     9         kx 	   later.  */
     9         kx 	return true;
     9         kx 
     9         kx       if ((offset + count) > hdr->sh_size)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    (_("%pB:%pA: error: attempting to write"
     9         kx 	       " over the end of the section"),
     9         kx 	     abfd, section);
     9         kx 
     9         kx 	  bfd_set_error (bfd_error_invalid_operation);
     9         kx 	  return false;
     9         kx 	}
     9         kx 
     9         kx       contents = hdr->contents;
     9         kx       if (contents == NULL)
     9         kx 	{
     9         kx 	  _bfd_error_handler
     9         kx 	    (_("%pB:%pA: error: attempting to write"
     9         kx 	       " section into an empty buffer"),
     9         kx 	     abfd, section);
     9         kx 
     9         kx 	  bfd_set_error (bfd_error_invalid_operation);
     9         kx 	  return false;
     9         kx 	}
     9         kx 
     9         kx       memcpy (contents + offset, location, count);
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   return _bfd_generic_set_section_contents (abfd, section,
     9         kx 					    location, offset, count);
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
     9         kx 			   arelent *cache_ptr ATTRIBUTE_UNUSED,
     9         kx 			   Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   abort ();
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx /* Try to convert a non-ELF reloc into an ELF one.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
     9         kx {
     9         kx   /* Check whether we really have an ELF howto.  */
     9         kx 
     9         kx   if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
     9         kx     {
     9         kx       bfd_reloc_code_real_type code;
     9         kx       reloc_howto_type *howto;
     9         kx 
     9         kx       /* Alien reloc: Try to determine its type to replace it with an
     9         kx 	 equivalent ELF reloc.  */
     9         kx 
     9         kx       if (areloc->howto->pc_relative)
     9         kx 	{
     9         kx 	  switch (areloc->howto->bitsize)
     9         kx 	    {
     9         kx 	    case 8:
     9         kx 	      code = BFD_RELOC_8_PCREL;
     9         kx 	      break;
     9         kx 	    case 12:
     9         kx 	      code = BFD_RELOC_12_PCREL;
     9         kx 	      break;
     9         kx 	    case 16:
     9         kx 	      code = BFD_RELOC_16_PCREL;
     9         kx 	      break;
     9         kx 	    case 24:
     9         kx 	      code = BFD_RELOC_24_PCREL;
     9         kx 	      break;
     9         kx 	    case 32:
     9         kx 	      code = BFD_RELOC_32_PCREL;
     9         kx 	      break;
     9         kx 	    case 64:
     9         kx 	      code = BFD_RELOC_64_PCREL;
     9         kx 	      break;
     9         kx 	    default:
     9         kx 	      goto fail;
     9         kx 	    }
     9         kx 
     9         kx 	  howto = bfd_reloc_type_lookup (abfd, code);
     9         kx 
     9         kx 	  if (howto && areloc->howto->pcrel_offset != howto->pcrel_offset)
     9         kx 	    {
     9         kx 	      if (howto->pcrel_offset)
     9         kx 		areloc->addend += areloc->address;
     9         kx 	      else
     9         kx 		areloc->addend -= areloc->address; /* addend is unsigned!! */
     9         kx 	    }
     9         kx 	}
     9         kx       else
     9         kx 	{
     9         kx 	  switch (areloc->howto->bitsize)
     9         kx 	    {
     9         kx 	    case 8:
     9         kx 	      code = BFD_RELOC_8;
     9         kx 	      break;
     9         kx 	    case 14:
     9         kx 	      code = BFD_RELOC_14;
     9         kx 	      break;
     9         kx 	    case 16:
     9         kx 	      code = BFD_RELOC_16;
     9         kx 	      break;
     9         kx 	    case 26:
     9         kx 	      code = BFD_RELOC_26;
     9         kx 	      break;
     9         kx 	    case 32:
     9         kx 	      code = BFD_RELOC_32;
     9         kx 	      break;
     9         kx 	    case 64:
     9         kx 	      code = BFD_RELOC_64;
     9         kx 	      break;
     9         kx 	    default:
     9         kx 	      goto fail;
     9         kx 	    }
     9         kx 
     9         kx 	  howto = bfd_reloc_type_lookup (abfd, code);
     9         kx 	}
     9         kx 
     9         kx       if (howto)
     9         kx 	areloc->howto = howto;
     9         kx       else
     9         kx 	goto fail;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx 
     9         kx  fail:
     9         kx   /* xgettext:c-format */
     9         kx   _bfd_error_handler (_("%pB: %s unsupported"),
     9         kx 		      abfd, areloc->howto->name);
     9         kx   bfd_set_error (bfd_error_sorry);
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx bool
     9         kx _bfd_elf_close_and_cleanup (bfd *abfd)
     9         kx {
     9         kx   struct elf_obj_tdata *tdata = elf_tdata (abfd);
     9         kx   if (tdata != NULL
     9         kx       && (bfd_get_format (abfd) == bfd_object
     9         kx 	  || bfd_get_format (abfd) == bfd_core))
     9         kx     {
     9         kx       if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
     9         kx 	_bfd_elf_strtab_free (elf_shstrtab (abfd));
     9         kx       _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
     9         kx       _bfd_stab_cleanup (abfd, &tdata->line_info);
     9         kx     }
     9         kx 
     9         kx   return _bfd_generic_close_and_cleanup (abfd);
     9         kx }
     9         kx 
     9         kx /* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY
     9         kx    in the relocation's offset.  Thus we cannot allow any sort of sanity
     9         kx    range-checking to interfere.  There is nothing else to do in processing
     9         kx    this reloc.  */
     9         kx 
     9         kx bfd_reloc_status_type
     9         kx _bfd_elf_rel_vtable_reloc_fn
     9         kx   (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
     9         kx    struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
     9         kx    void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
     9         kx    bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   return bfd_reloc_ok;
     9         kx }
     9         kx 
     9         kx /* Elf core file support.  Much of this only works on native
     9         kx    toolchains, since we rely on knowing the
     9         kx    machine-dependent procfs structure in order to pick
     9         kx    out details about the corefile.  */
     9         kx 
     9         kx #ifdef HAVE_SYS_PROCFS_H
     9         kx # include <sys/procfs.h>
     9         kx #endif
     9         kx 
     9         kx /* Return a PID that identifies a "thread" for threaded cores, or the
     9         kx    PID of the main process for non-threaded cores.  */
     9         kx 
     9         kx static int
     9         kx elfcore_make_pid (bfd *abfd)
     9         kx {
     9         kx   int pid;
     9         kx 
     9         kx   pid = elf_tdata (abfd)->core->lwpid;
     9         kx   if (pid == 0)
     9         kx     pid = elf_tdata (abfd)->core->pid;
     9         kx 
     9         kx   return pid;
     9         kx }
     9         kx 
     9         kx /* If there isn't a section called NAME, make one, using data from
     9         kx    SECT.  Note, this function will generate a reference to NAME, so
     9         kx    you shouldn't deallocate or overwrite it.  */
     9         kx 
     9         kx static bool
     9         kx elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
     9         kx {
     9         kx   asection *sect2;
     9         kx 
     9         kx   if (bfd_get_section_by_name (abfd, name) != NULL)
     9         kx     return true;
     9         kx 
     9         kx   sect2 = bfd_make_section_with_flags (abfd, name, sect->flags);
     9         kx   if (sect2 == NULL)
     9         kx     return false;
     9         kx 
     9         kx   sect2->size = sect->size;
     9         kx   sect2->filepos = sect->filepos;
     9         kx   sect2->alignment_power = sect->alignment_power;
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Create a pseudosection containing SIZE bytes at FILEPOS.  This
     9         kx    actually creates up to two pseudosections:
     9         kx    - For the single-threaded case, a section named NAME, unless
     9         kx      such a section already exists.
     9         kx    - For the multi-threaded case, a section named "NAME/PID", where
     9         kx      PID is elfcore_make_pid (abfd).
     9         kx    Both pseudosections have identical contents.  */
     9         kx bool
     9         kx _bfd_elfcore_make_pseudosection (bfd *abfd,
     9         kx 				 char *name,
     9         kx 				 size_t size,
     9         kx 				 ufile_ptr filepos)
     9         kx {
     9         kx   char buf[100];
     9         kx   char *threaded_name;
     9         kx   size_t len;
     9         kx   asection *sect;
     9         kx 
     9         kx   /* Build the section name.  */
     9         kx 
     9         kx   sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
     9         kx   len = strlen (buf) + 1;
     9         kx   threaded_name = (char *) bfd_alloc (abfd, len);
     9         kx   if (threaded_name == NULL)
     9         kx     return false;
     9         kx   memcpy (threaded_name, buf, len);
     9         kx 
     9         kx   sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
     9         kx 					     SEC_HAS_CONTENTS);
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx   sect->size = size;
     9         kx   sect->filepos = filepos;
     9         kx   sect->alignment_power = 2;
     9         kx 
     9         kx   return elfcore_maybe_make_sect (abfd, name, sect);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_make_auxv_note_section (bfd *abfd, Elf_Internal_Note *note,
     9         kx 				size_t offs)
     9         kx {
     9         kx   asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
     9         kx 						       SEC_HAS_CONTENTS);
     9         kx 
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx 
     9         kx   sect->size = note->descsz - offs;
     9         kx   sect->filepos = note->descpos + offs;
     9         kx   sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* prstatus_t exists on:
     9         kx      solaris 2.5+
     9         kx      linux 2.[01] + glibc
     9         kx      unixware 4.2
     9         kx */
     9         kx 
     9         kx #if defined (HAVE_PRSTATUS_T)
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   size_t size;
     9         kx   int offset;
     9         kx 
     9         kx   if (note->descsz == sizeof (prstatus_t))
     9         kx     {
     9         kx       prstatus_t prstat;
     9         kx 
     9         kx       size = sizeof (prstat.pr_reg);
     9         kx       offset   = offsetof (prstatus_t, pr_reg);
     9         kx       memcpy (&prstat, note->descdata, sizeof (prstat));
     9         kx 
     9         kx       /* Do not overwrite the core signal if it
     9         kx 	 has already been set by another thread.  */
     9         kx       if (elf_tdata (abfd)->core->signal == 0)
     9         kx 	elf_tdata (abfd)->core->signal = prstat.pr_cursig;
     9         kx       if (elf_tdata (abfd)->core->pid == 0)
     9         kx 	elf_tdata (abfd)->core->pid = prstat.pr_pid;
     9         kx 
     9         kx       /* pr_who exists on:
     9         kx 	 solaris 2.5+
     9         kx 	 unixware 4.2
     9         kx 	 pr_who doesn't exist on:
     9         kx 	 linux 2.[01]
     9         kx 	 */
     9         kx #if defined (HAVE_PRSTATUS_T_PR_WHO)
     9         kx       elf_tdata (abfd)->core->lwpid = prstat.pr_who;
     9         kx #else
     9         kx       elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
     9         kx #endif
     9         kx     }
     9         kx #if defined (HAVE_PRSTATUS32_T)
     9         kx   else if (note->descsz == sizeof (prstatus32_t))
     9         kx     {
     9         kx       /* 64-bit host, 32-bit corefile */
     9         kx       prstatus32_t prstat;
     9         kx 
     9         kx       size = sizeof (prstat.pr_reg);
     9         kx       offset   = offsetof (prstatus32_t, pr_reg);
     9         kx       memcpy (&prstat, note->descdata, sizeof (prstat));
     9         kx 
     9         kx       /* Do not overwrite the core signal if it
     9         kx 	 has already been set by another thread.  */
     9         kx       if (elf_tdata (abfd)->core->signal == 0)
     9         kx 	elf_tdata (abfd)->core->signal = prstat.pr_cursig;
     9         kx       if (elf_tdata (abfd)->core->pid == 0)
     9         kx 	elf_tdata (abfd)->core->pid = prstat.pr_pid;
     9         kx 
     9         kx       /* pr_who exists on:
     9         kx 	 solaris 2.5+
     9         kx 	 unixware 4.2
     9         kx 	 pr_who doesn't exist on:
     9         kx 	 linux 2.[01]
     9         kx 	 */
     9         kx #if defined (HAVE_PRSTATUS32_T_PR_WHO)
     9         kx       elf_tdata (abfd)->core->lwpid = prstat.pr_who;
     9         kx #else
     9         kx       elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
     9         kx #endif
     9         kx     }
     9         kx #endif /* HAVE_PRSTATUS32_T */
     9         kx   else
     9         kx     {
     9         kx       /* Fail - we don't know how to handle any other
     9         kx 	 note size (ie. data object type).  */
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   /* Make a ".reg/999" section and a ".reg" section.  */
     9         kx   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
     9         kx 					  size, note->descpos + offset);
     9         kx }
     9         kx #endif /* defined (HAVE_PRSTATUS_T) */
     9         kx 
     9         kx /* Create a pseudosection containing the exact contents of NOTE.  */
     9         kx static bool
     9         kx elfcore_make_note_pseudosection (bfd *abfd,
     9         kx 				 char *name,
     9         kx 				 Elf_Internal_Note *note)
     9         kx {
     9         kx   return _bfd_elfcore_make_pseudosection (abfd, name,
     9         kx 					  note->descsz, note->descpos);
     9         kx }
     9         kx 
     9         kx /* There isn't a consistent prfpregset_t across platforms,
     9         kx    but it doesn't matter, because we don't have to pick this
     9         kx    data structure apart.  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg2", note);
     9         kx }
     9         kx 
     9         kx /* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
     9         kx    type of NT_PRXFPREG.  Just include the whole note's contents
     9         kx    literally.  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
     9         kx }
     9         kx 
     9         kx /* Linux dumps the Intel XSAVE extended state in a note named "LINUX"
     9         kx    with a note type of NT_X86_XSTATE.  Just include the whole note's
     9         kx    contents literally.  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-xstate", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tar (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tar", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_ppr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ppr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_dscr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-dscr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_ebb (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ebb", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_pmu (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-pmu", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_cgpr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cgpr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_cfpr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cfpr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_cvmx (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvmx", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_cvsx (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvsx", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_spr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-spr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_ctar (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-ctar", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_cppr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cppr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_ppc_tm_cdscr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cdscr", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_vxrs_low (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-low", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_vxrs_high (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-high", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_gs_cb (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-cb", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_s390_gs_bc (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-bc", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_aarch_sve (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-sve", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_aarch_pauth (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-pauth", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_aarch_mte (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-mte",
     9         kx 					  note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-arc-v2", note);
     9         kx }
     9         kx 
     9         kx /* Convert NOTE into a bfd_section called ".reg-riscv-csr".  Return TRUE if
     9         kx    successful otherwise, return FALSE.  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_riscv_csr (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-riscv-csr", note);
     9         kx }
     9         kx 
     9         kx /* Convert NOTE into a bfd_section called ".gdb-tdesc".  Return TRUE if
     9         kx    successful otherwise, return FALSE.  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_gdb_tdesc (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".gdb-tdesc", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_loongarch_cpucfg (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-cpucfg", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_loongarch_lbt (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lbt", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_loongarch_lsx (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lsx", note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_loongarch_lasx (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lasx", note);
     9         kx }
     9         kx 
     9         kx #if defined (HAVE_PRPSINFO_T)
     9         kx typedef prpsinfo_t   elfcore_psinfo_t;
     9         kx #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
     9         kx typedef prpsinfo32_t elfcore_psinfo32_t;
     9         kx #endif
     9         kx #endif
     9         kx 
     9         kx #if defined (HAVE_PSINFO_T)
     9         kx typedef psinfo_t   elfcore_psinfo_t;
     9         kx #if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
     9         kx typedef psinfo32_t elfcore_psinfo32_t;
     9         kx #endif
     9         kx #endif
     9         kx 
     9         kx /* return a malloc'ed copy of a string at START which is at
     9         kx    most MAX bytes long, possibly without a terminating '\0'.
     9         kx    the copy will always have a terminating '\0'.  */
     9         kx 
     9         kx char *
     9         kx _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
     9         kx {
     9         kx   char *dups;
     9         kx   char *end = (char *) memchr (start, '\0', max);
     9         kx   size_t len;
     9         kx 
     9         kx   if (end == NULL)
     9         kx     len = max;
     9         kx   else
     9         kx     len = end - start;
     9         kx 
     9         kx   dups = (char *) bfd_alloc (abfd, len + 1);
     9         kx   if (dups == NULL)
     9         kx     return NULL;
     9         kx 
     9         kx   memcpy (dups, start, len);
     9         kx   dups[len] = '\0';
     9         kx 
     9         kx   return dups;
     9         kx }
     9         kx 
     9         kx #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
     9         kx static bool
     9         kx elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (note->descsz == sizeof (elfcore_psinfo_t))
     9         kx     {
     9         kx       elfcore_psinfo_t psinfo;
     9         kx 
     9         kx       memcpy (&psinfo, note->descdata, sizeof (psinfo));
     9         kx 
     9         kx #if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
     9         kx       elf_tdata (abfd)->core->pid = psinfo.pr_pid;
     9         kx #endif
     9         kx       elf_tdata (abfd)->core->program
     9         kx 	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
     9         kx 				sizeof (psinfo.pr_fname));
     9         kx 
     9         kx       elf_tdata (abfd)->core->command
     9         kx 	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
     9         kx 				sizeof (psinfo.pr_psargs));
     9         kx     }
     9         kx #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
     9         kx   else if (note->descsz == sizeof (elfcore_psinfo32_t))
     9         kx     {
     9         kx       /* 64-bit host, 32-bit corefile */
     9         kx       elfcore_psinfo32_t psinfo;
     9         kx 
     9         kx       memcpy (&psinfo, note->descdata, sizeof (psinfo));
     9         kx 
     9         kx #if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
     9         kx       elf_tdata (abfd)->core->pid = psinfo.pr_pid;
     9         kx #endif
     9         kx       elf_tdata (abfd)->core->program
     9         kx 	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
     9         kx 				sizeof (psinfo.pr_fname));
     9         kx 
     9         kx       elf_tdata (abfd)->core->command
     9         kx 	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
     9         kx 				sizeof (psinfo.pr_psargs));
     9         kx     }
     9         kx #endif
     9         kx 
     9         kx   else
     9         kx     {
     9         kx       /* Fail - we don't know how to handle any other
     9         kx 	 note size (ie. data object type).  */
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   /* Note that for some reason, a spurious space is tacked
     9         kx      onto the end of the args in some (at least one anyway)
     9         kx      implementations, so strip it off if it exists.  */
     9         kx 
     9         kx   {
     9         kx     char *command = elf_tdata (abfd)->core->command;
     9         kx     int n = strlen (command);
     9         kx 
     9         kx     if (0 < n && command[n - 1] == ' ')
     9         kx       command[n - 1] = '\0';
     9         kx   }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx #endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
     9         kx 
     9         kx #if defined (HAVE_PSTATUS_T)
     9         kx static bool
     9         kx elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (note->descsz == sizeof (pstatus_t)
     9         kx #if defined (HAVE_PXSTATUS_T)
     9         kx       || note->descsz == sizeof (pxstatus_t)
     9         kx #endif
     9         kx       )
     9         kx     {
     9         kx       pstatus_t pstat;
     9         kx 
     9         kx       memcpy (&pstat, note->descdata, sizeof (pstat));
     9         kx 
     9         kx       elf_tdata (abfd)->core->pid = pstat.pr_pid;
     9         kx     }
     9         kx #if defined (HAVE_PSTATUS32_T)
     9         kx   else if (note->descsz == sizeof (pstatus32_t))
     9         kx     {
     9         kx       /* 64-bit host, 32-bit corefile */
     9         kx       pstatus32_t pstat;
     9         kx 
     9         kx       memcpy (&pstat, note->descdata, sizeof (pstat));
     9         kx 
     9         kx       elf_tdata (abfd)->core->pid = pstat.pr_pid;
     9         kx     }
     9         kx #endif
     9         kx   /* Could grab some more details from the "representative"
     9         kx      lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
     9         kx      NT_LWPSTATUS note, presumably.  */
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx #endif /* defined (HAVE_PSTATUS_T) */
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T)
     9         kx static bool
     9         kx elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   lwpstatus_t lwpstat;
     9         kx   char buf[100];
     9         kx   char *name;
     9         kx   size_t len;
     9         kx   asection *sect;
     9         kx 
     9         kx   if (note->descsz != sizeof (lwpstat)
     9         kx #if defined (HAVE_LWPXSTATUS_T)
     9         kx       && note->descsz != sizeof (lwpxstatus_t)
     9         kx #endif
     9         kx       )
     9         kx     return true;
     9         kx 
     9         kx   memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
     9         kx 
     9         kx   elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
     9         kx   /* Do not overwrite the core signal if it has already been set by
     9         kx      another thread.  */
     9         kx   if (elf_tdata (abfd)->core->signal == 0)
     9         kx     elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;
     9         kx 
     9         kx   /* Make a ".reg/999" section.  */
     9         kx 
     9         kx   sprintf (buf, ".reg/%d", elfcore_make_pid (abfd));
     9         kx   len = strlen (buf) + 1;
     9         kx   name = bfd_alloc (abfd, len);
     9         kx   if (name == NULL)
     9         kx     return false;
     9         kx   memcpy (name, buf, len);
     9         kx 
     9         kx   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
     9         kx   sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
     9         kx   sect->filepos = note->descpos
     9         kx     + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
     9         kx #endif
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T_PR_REG)
     9         kx   sect->size = sizeof (lwpstat.pr_reg);
     9         kx   sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
     9         kx #endif
     9         kx 
     9         kx   sect->alignment_power = 2;
     9         kx 
     9         kx   if (!elfcore_maybe_make_sect (abfd, ".reg", sect))
     9         kx     return false;
     9         kx 
     9         kx   /* Make a ".reg2/999" section */
     9         kx 
     9         kx   sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
     9         kx   len = strlen (buf) + 1;
     9         kx   name = bfd_alloc (abfd, len);
     9         kx   if (name == NULL)
     9         kx     return false;
     9         kx   memcpy (name, buf, len);
     9         kx 
     9         kx   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
     9         kx   sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
     9         kx   sect->filepos = note->descpos
     9         kx     + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
     9         kx #endif
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T_PR_FPREG)
     9         kx   sect->size = sizeof (lwpstat.pr_fpreg);
     9         kx   sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
     9         kx #endif
     9         kx 
     9         kx   sect->alignment_power = 2;
     9         kx 
     9         kx   return elfcore_maybe_make_sect (abfd, ".reg2", sect);
     9         kx }
     9         kx #endif /* defined (HAVE_LWPSTATUS_T) */
     9         kx 
     9         kx /* These constants, and the structure offsets used below, are defined by
     9         kx    Cygwin's core_dump.h */
     9         kx #define NOTE_INFO_PROCESS  1
     9         kx #define NOTE_INFO_THREAD   2
     9         kx #define NOTE_INFO_MODULE   3
     9         kx #define NOTE_INFO_MODULE64 4
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   char buf[30];
     9         kx   char *name;
     9         kx   size_t len;
     9         kx   unsigned int name_size;
     9         kx   asection *sect;
     9         kx   unsigned int type;
     9         kx   int is_active_thread;
     9         kx   bfd_vma base_addr;
     9         kx 
     9         kx   if (note->descsz < 4)
     9         kx     return true;
     9         kx 
     9         kx   if (! startswith (note->namedata, "win32"))
     9         kx     return true;
     9         kx 
     9         kx   type = bfd_get_32 (abfd, note->descdata);
     9         kx 
     9         kx   struct
     9         kx   {
     9         kx     const char *type_name;
     9         kx     unsigned long min_size;
     9         kx   } size_check[] =
     9         kx       {
     9         kx        { "NOTE_INFO_PROCESS", 12 },
     9         kx        { "NOTE_INFO_THREAD", 12 },
     9         kx        { "NOTE_INFO_MODULE", 12 },
     9         kx        { "NOTE_INFO_MODULE64", 16 },
     9         kx       };
     9         kx 
     9         kx   if (type == 0 || type > (sizeof(size_check)/sizeof(size_check[0])))
     9         kx       return true;
     9         kx 
     9         kx   if (note->descsz < size_check[type - 1].min_size)
     9         kx     {
     9         kx       _bfd_error_handler (_("%pB: warning: win32pstatus %s of size %lu bytes"
     9         kx 			    " is too small"),
     9         kx 			  abfd, size_check[type - 1].type_name, note->descsz);
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   switch (type)
     9         kx     {
     9         kx     case NOTE_INFO_PROCESS:
     9         kx       /* FIXME: need to add ->core->command.  */
     9         kx       elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 4);
     9         kx       elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 8);
     9         kx       break;
     9         kx 
     9         kx     case NOTE_INFO_THREAD:
     9         kx       /* Make a ".reg/<tid>" section containing the Win32 API thread CONTEXT
     9         kx 	 structure. */
     9         kx       /* thread_info.tid */
     9         kx       sprintf (buf, ".reg/%ld", (long) bfd_get_32 (abfd, note->descdata + 4));
     9         kx 
     9         kx       len = strlen (buf) + 1;
     9         kx       name = (char *) bfd_alloc (abfd, len);
     9         kx       if (name == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       memcpy (name, buf, len);
     9         kx 
     9         kx       sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx       if (sect == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       /* sizeof (thread_info.thread_context) */
     9         kx       sect->size = note->descsz - 12;
     9         kx       /* offsetof (thread_info.thread_context) */
     9         kx       sect->filepos = note->descpos + 12;
     9         kx       sect->alignment_power = 2;
     9         kx 
     9         kx       /* thread_info.is_active_thread */
     9         kx       is_active_thread = bfd_get_32 (abfd, note->descdata + 8);
     9         kx 
     9         kx       if (is_active_thread)
     9         kx 	if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
     9         kx 	  return false;
     9         kx       break;
     9         kx 
     9         kx     case NOTE_INFO_MODULE:
     9         kx     case NOTE_INFO_MODULE64:
     9         kx       /* Make a ".module/xxxxxxxx" section.  */
     9         kx       if (type == NOTE_INFO_MODULE)
     9         kx 	{
     9         kx 	  /* module_info.base_address */
     9         kx 	  base_addr = bfd_get_32 (abfd, note->descdata + 4);
     9         kx 	  sprintf (buf, ".module/%08lx", (unsigned long) base_addr);
     9         kx 	  /* module_info.module_name_size */
     9         kx 	  name_size = bfd_get_32 (abfd, note->descdata + 8);
     9         kx 	}
     9         kx       else /* NOTE_INFO_MODULE64 */
     9         kx 	{
     9         kx 	  /* module_info.base_address */
     9         kx 	  base_addr = bfd_get_64 (abfd, note->descdata + 4);
     9         kx 	  sprintf (buf, ".module/%016lx", (unsigned long) base_addr);
     9         kx 	  /* module_info.module_name_size */
     9         kx 	  name_size = bfd_get_32 (abfd, note->descdata + 12);
     9         kx 	}
     9         kx 
     9         kx       len = strlen (buf) + 1;
     9         kx       name = (char *) bfd_alloc (abfd, len);
     9         kx       if (name == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       memcpy (name, buf, len);
     9         kx 
     9         kx       sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx 
     9         kx       if (sect == NULL)
     9         kx 	return false;
     9         kx 
     9         kx       if (note->descsz < 12 + name_size)
     9         kx 	{
     9         kx 	  _bfd_error_handler (_("%pB: win32pstatus NOTE_INFO_MODULE of size %lu"
     9         kx 				" is too small to contain a name of size %u"),
     9         kx 			      abfd, note->descsz, name_size);
     9         kx 	  return true;
     9         kx 	}
     9         kx 
     9         kx       sect->size = note->descsz;
     9         kx       sect->filepos = note->descpos;
     9         kx       sect->alignment_power = 2;
     9         kx       break;
     9         kx 
     9         kx     default:
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   switch (note->type)
     9         kx     {
     9         kx     default:
     9         kx       return true;
     9         kx 
     9         kx     case NT_PRSTATUS:
     9         kx       if (bed->elf_backend_grok_prstatus)
     9         kx 	if ((*bed->elf_backend_grok_prstatus) (abfd, note))
     9         kx 	  return true;
     9         kx #if defined (HAVE_PRSTATUS_T)
     9         kx       return elfcore_grok_prstatus (abfd, note);
     9         kx #else
     9         kx       return true;
     9         kx #endif
     9         kx 
     9         kx #if defined (HAVE_PSTATUS_T)
     9         kx     case NT_PSTATUS:
     9         kx       return elfcore_grok_pstatus (abfd, note);
     9         kx #endif
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T)
     9         kx     case NT_LWPSTATUS:
     9         kx       return elfcore_grok_lwpstatus (abfd, note);
     9         kx #endif
     9         kx 
     9         kx     case NT_FPREGSET:		/* FIXME: rename to NT_PRFPREG */
     9         kx       return elfcore_grok_prfpreg (abfd, note);
     9         kx 
     9         kx     case NT_WIN32PSTATUS:
     9         kx       return elfcore_grok_win32pstatus (abfd, note);
     9         kx 
     9         kx     case NT_PRXFPREG:		/* Linux SSE extension */
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_prxfpreg (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_X86_XSTATE:		/* Linux XSAVE extension */
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_xstatereg (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_VMX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_vmx (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_VSX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_vsx (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TAR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tar (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_PPR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_ppr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_DSCR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_dscr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_EBB:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_ebb (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_PMU:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_pmu (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CGPR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_cgpr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CFPR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_cfpr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CVMX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_cvmx (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CVSX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_cvsx (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_SPR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_spr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CTAR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_ctar (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CPPR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_cppr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PPC_TM_CDSCR:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_ppc_tm_cdscr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_HIGH_GPRS:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_high_gprs (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_TIMER:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_timer (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_TODCMP:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_todcmp (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_TODPREG:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_todpreg (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_CTRS:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_ctrs (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_PREFIX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_prefix (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_LAST_BREAK:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_last_break (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_SYSTEM_CALL:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_system_call (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_TDB:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_tdb (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_VXRS_LOW:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_vxrs_low (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_VXRS_HIGH:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_vxrs_high (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_GS_CB:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_gs_cb (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_S390_GS_BC:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_s390_gs_bc (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARC_V2:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_arc_v2 (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_VFP:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_arm_vfp (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_TLS:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_aarch_tls (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_HW_BREAK:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_aarch_hw_break (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_HW_WATCH:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_aarch_hw_watch (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_SVE:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_aarch_sve (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_PAC_MASK:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_aarch_pauth (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_ARM_TAGGED_ADDR_CTRL:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_aarch_mte (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_GDB_TDESC:
     9         kx       if (note->namesz == 4
     9         kx 	  && strcmp (note->namedata, "GDB") == 0)
     9         kx 	return elfcore_grok_gdb_tdesc (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_RISCV_CSR:
     9         kx       if (note->namesz == 4
     9         kx 	  && strcmp (note->namedata, "GDB") == 0)
     9         kx 	return elfcore_grok_riscv_csr (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_LARCH_CPUCFG:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_loongarch_cpucfg (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_LARCH_LBT:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_loongarch_lbt (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_LARCH_LSX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_loongarch_lsx (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_LARCH_LASX:
     9         kx       if (note->namesz == 6
     9         kx 	  && strcmp (note->namedata, "LINUX") == 0)
     9         kx 	return elfcore_grok_loongarch_lasx (abfd, note);
     9         kx       else
     9         kx 	return true;
     9         kx 
     9         kx     case NT_PRPSINFO:
     9         kx     case NT_PSINFO:
     9         kx       if (bed->elf_backend_grok_psinfo)
     9         kx 	if ((*bed->elf_backend_grok_psinfo) (abfd, note))
     9         kx 	  return true;
     9         kx #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
     9         kx       return elfcore_grok_psinfo (abfd, note);
     9         kx #else
     9         kx       return true;
     9         kx #endif
     9         kx 
     9         kx     case NT_AUXV:
     9         kx       return elfcore_make_auxv_note_section (abfd, note, 0);
     9         kx 
     9         kx     case NT_FILE:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
     9         kx 					      note);
     9         kx 
     9         kx     case NT_SIGINFO:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
     9         kx 					      note);
     9         kx 
     9         kx     }
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   struct bfd_build_id* build_id;
     9         kx 
     9         kx   if (note->descsz == 0)
     9         kx     return false;
     9         kx 
     9         kx   build_id = bfd_alloc (abfd, sizeof (struct bfd_build_id) - 1 + note->descsz);
     9         kx   if (build_id == NULL)
     9         kx     return false;
     9         kx 
     9         kx   build_id->size = note->descsz;
     9         kx   memcpy (build_id->data, note->descdata, note->descsz);
     9         kx   abfd->build_id = build_id;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   switch (note->type)
     9         kx     {
     9         kx     default:
     9         kx       return true;
     9         kx 
     9         kx     case NT_GNU_PROPERTY_TYPE_0:
     9         kx       return _bfd_elf_parse_gnu_properties (abfd, note);
     9         kx 
     9         kx     case NT_GNU_BUILD_ID:
     9         kx       return elfobj_grok_gnu_build_id (abfd, note);
     9         kx     }
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   struct sdt_note *cur =
     9         kx     (struct sdt_note *) bfd_alloc (abfd,
     9         kx 				   sizeof (struct sdt_note) + note->descsz);
     9         kx 
     9         kx   cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head;
     9         kx   cur->size = (bfd_size_type) note->descsz;
     9         kx   memcpy (cur->data, note->descdata, note->descsz);
     9         kx 
     9         kx   elf_tdata (abfd)->sdt_note_head = cur;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   switch (note->type)
     9         kx     {
     9         kx     case NT_STAPSDT:
     9         kx       return elfobj_grok_stapsdt_note_1 (abfd, note);
     9         kx 
     9         kx     default:
     9         kx       return true;
     9         kx     }
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   size_t offset;
     9         kx 
     9         kx   switch (elf_elfheader (abfd)->e_ident[EI_CLASS])
     9         kx     {
     9         kx     case ELFCLASS32:
     9         kx       if (note->descsz < 108)
     9         kx 	return false;
     9         kx       break;
     9         kx 
     9         kx     case ELFCLASS64:
     9         kx       if (note->descsz < 120)
     9         kx 	return false;
     9         kx       break;
     9         kx 
     9         kx     default:
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   /* Check for version 1 in pr_version.  */
     9         kx   if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
     9         kx     return false;
     9         kx 
     9         kx   offset = 4;
     9         kx 
     9         kx   /* Skip over pr_psinfosz. */
     9         kx   if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
     9         kx     offset += 4;
     9         kx   else
     9         kx     {
     9         kx       offset += 4;	/* Padding before pr_psinfosz. */
     9         kx       offset += 8;
     9         kx     }
     9         kx 
     9         kx   /* pr_fname is PRFNAMESZ (16) + 1 bytes in size.  */
     9         kx   elf_tdata (abfd)->core->program
     9         kx     = _bfd_elfcore_strndup (abfd, note->descdata + offset, 17);
     9         kx   offset += 17;
     9         kx 
     9         kx   /* pr_psargs is PRARGSZ (80) + 1 bytes in size.  */
     9         kx   elf_tdata (abfd)->core->command
     9         kx     = _bfd_elfcore_strndup (abfd, note->descdata + offset, 81);
     9         kx   offset += 81;
     9         kx 
     9         kx   /* Padding before pr_pid.  */
     9         kx   offset += 2;
     9         kx 
     9         kx   /* The pr_pid field was added in version "1a".  */
     9         kx   if (note->descsz < offset + 4)
     9         kx     return true;
     9         kx 
     9         kx   elf_tdata (abfd)->core->pid
     9         kx     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   size_t offset;
     9         kx   size_t size;
     9         kx   size_t min_size;
     9         kx 
     9         kx   /* Compute offset of pr_getregsz, skipping over pr_statussz.
     9         kx      Also compute minimum size of this note.  */
     9         kx   switch (elf_elfheader (abfd)->e_ident[EI_CLASS])
     9         kx     {
     9         kx     case ELFCLASS32:
     9         kx       offset = 4 + 4;
     9         kx       min_size = offset + (4 * 2) + 4 + 4 + 4;
     9         kx       break;
     9         kx 
     9         kx     case ELFCLASS64:
     9         kx       offset = 4 + 4 + 8;	/* Includes padding before pr_statussz.  */
     9         kx       min_size = offset + (8 * 2) + 4 + 4 + 4 + 4;
     9         kx       break;
     9         kx 
     9         kx     default:
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   if (note->descsz < min_size)
     9         kx     return false;
     9         kx 
     9         kx   /* Check for version 1 in pr_version.  */
     9         kx   if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
     9         kx     return false;
     9         kx 
     9         kx   /* Extract size of pr_reg from pr_gregsetsz.  */
     9         kx   /* Skip over pr_gregsetsz and pr_fpregsetsz.  */
     9         kx   if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
     9         kx     {
     9         kx       size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
     9         kx       offset += 4 * 2;
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
     9         kx       offset += 8 * 2;
     9         kx     }
     9         kx 
     9         kx   /* Skip over pr_osreldate.  */
     9         kx   offset += 4;
     9         kx 
     9         kx   /* Read signal from pr_cursig.  */
     9         kx   if (elf_tdata (abfd)->core->signal == 0)
     9         kx     elf_tdata (abfd)->core->signal
     9         kx       = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
     9         kx   offset += 4;
     9         kx 
     9         kx   /* Read TID from pr_pid.  */
     9         kx   elf_tdata (abfd)->core->lwpid
     9         kx       = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
     9         kx   offset += 4;
     9         kx 
     9         kx   /* Padding before pr_reg.  */
     9         kx   if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
     9         kx     offset += 4;
     9         kx 
     9         kx   /* Make sure that there is enough data remaining in the note.  */
     9         kx   if ((note->descsz - offset) < size)
     9         kx     return false;
     9         kx 
     9         kx   /* Make a ".reg/999" section and a ".reg" section.  */
     9         kx   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
     9         kx 					  size, note->descpos + offset);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   switch (note->type)
     9         kx     {
     9         kx     case NT_PRSTATUS:
     9         kx       if (bed->elf_backend_grok_freebsd_prstatus)
     9         kx 	if ((*bed->elf_backend_grok_freebsd_prstatus) (abfd, note))
     9         kx 	  return true;
     9         kx       return elfcore_grok_freebsd_prstatus (abfd, note);
     9         kx 
     9         kx     case NT_FPREGSET:
     9         kx       return elfcore_grok_prfpreg (abfd, note);
     9         kx 
     9         kx     case NT_PRPSINFO:
     9         kx       return elfcore_grok_freebsd_psinfo (abfd, note);
     9         kx 
     9         kx     case NT_FREEBSD_THRMISC:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);
     9         kx 
     9         kx     case NT_FREEBSD_PROCSTAT_PROC:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.proc",
     9         kx 					      note);
     9         kx 
     9         kx     case NT_FREEBSD_PROCSTAT_FILES:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.files",
     9         kx 					      note);
     9         kx 
     9         kx     case NT_FREEBSD_PROCSTAT_VMMAP:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.vmmap",
     9         kx 					      note);
     9         kx 
     9         kx     case NT_FREEBSD_PROCSTAT_AUXV:
     9         kx       return elfcore_make_auxv_note_section (abfd, note, 4);
     9         kx 
     9         kx     case NT_FREEBSD_X86_SEGBASES:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".reg-x86-segbases", note);
     9         kx 
     9         kx     case NT_X86_XSTATE:
     9         kx       return elfcore_grok_xstatereg (abfd, note);
     9         kx 
     9         kx     case NT_FREEBSD_PTLWPINFO:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
     9         kx 					      note);
     9         kx 
     9         kx     case NT_ARM_TLS:
     9         kx       return elfcore_grok_aarch_tls (abfd, note);
     9         kx 
     9         kx     case NT_ARM_VFP:
     9         kx       return elfcore_grok_arm_vfp (abfd, note);
     9         kx 
     9         kx     default:
     9         kx       return true;
     9         kx     }
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
     9         kx {
     9         kx   char *cp;
     9         kx 
     9         kx   cp = strchr (note->namedata, '@');
     9         kx   if (cp != NULL)
     9         kx     {
     9         kx       *lwpidp = atoi(cp + 1);
     9         kx       return true;
     9         kx     }
     9         kx   return false;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (note->descsz <= 0x7c + 31)
     9         kx     return false;
     9         kx 
     9         kx   /* Signal number at offset 0x08. */
     9         kx   elf_tdata (abfd)->core->signal
     9         kx     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
     9         kx 
     9         kx   /* Process ID at offset 0x50. */
     9         kx   elf_tdata (abfd)->core->pid
     9         kx     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
     9         kx 
     9         kx   /* Command name at 0x7c (max 32 bytes, including nul). */
     9         kx   elf_tdata (abfd)->core->command
     9         kx     = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
     9         kx 
     9         kx   return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
     9         kx 					  note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   int lwp;
     9         kx 
     9         kx   if (elfcore_netbsd_get_lwpid (note, &lwp))
     9         kx     elf_tdata (abfd)->core->lwpid = lwp;
     9         kx 
     9         kx   switch (note->type)
     9         kx     {
     9         kx     case NT_NETBSDCORE_PROCINFO:
     9         kx       /* NetBSD-specific core "procinfo".  Note that we expect to
     9         kx 	 find this note before any of the others, which is fine,
     9         kx 	 since the kernel writes this note out first when it
     9         kx 	 creates a core file.  */
     9         kx       return elfcore_grok_netbsd_procinfo (abfd, note);
     9         kx     case NT_NETBSDCORE_AUXV:
     9         kx       /* NetBSD-specific Elf Auxiliary Vector data. */
     9         kx       return elfcore_make_auxv_note_section (abfd, note, 4);
     9         kx     case NT_NETBSDCORE_LWPSTATUS:
     9         kx       return elfcore_make_note_pseudosection (abfd,
     9         kx 					      ".note.netbsdcore.lwpstatus",
     9         kx 					      note);
     9         kx     default:
     9         kx       break;
     9         kx     }
     9         kx 
     9         kx   /* As of March 2020 there are no other machine-independent notes
     9         kx      defined for NetBSD core files.  If the note type is less
     9         kx      than the start of the machine-dependent note types, we don't
     9         kx      understand it.  */
     9         kx 
     9         kx   if (note->type < NT_NETBSDCORE_FIRSTMACH)
     9         kx     return true;
     9         kx 
     9         kx 
     9         kx   switch (bfd_get_arch (abfd))
     9         kx     {
     9         kx       /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
     9         kx 	 PT_GETFPREGS == mach+2.  */
     9         kx 
     9         kx     case bfd_arch_aarch64:
     9         kx     case bfd_arch_alpha:
     9         kx     case bfd_arch_sparc:
     9         kx       switch (note->type)
     9         kx 	{
     9         kx 	case NT_NETBSDCORE_FIRSTMACH+0:
     9         kx 	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
     9         kx 
     9         kx 	case NT_NETBSDCORE_FIRSTMACH+2:
     9         kx 	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
     9         kx 
     9         kx 	default:
     9         kx 	  return true;
     9         kx 	}
     9         kx 
     9         kx       /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
     9         kx 	 There's also old PT___GETREGS40 == mach + 1 for old reg
     9         kx 	 structure which lacks GBR.  */
     9         kx 
     9         kx     case bfd_arch_sh:
     9         kx       switch (note->type)
     9         kx 	{
     9         kx 	case NT_NETBSDCORE_FIRSTMACH+3:
     9         kx 	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
     9         kx 
     9         kx 	case NT_NETBSDCORE_FIRSTMACH+5:
     9         kx 	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
     9         kx 
     9         kx 	default:
     9         kx 	  return true;
     9         kx 	}
     9         kx 
     9         kx       /* On all other arch's, PT_GETREGS == mach+1 and
     9         kx 	 PT_GETFPREGS == mach+3.  */
     9         kx 
     9         kx     default:
     9         kx       switch (note->type)
     9         kx 	{
     9         kx 	case NT_NETBSDCORE_FIRSTMACH+1:
     9         kx 	  return elfcore_make_note_pseudosection (abfd, ".reg", note);
     9         kx 
     9         kx 	case NT_NETBSDCORE_FIRSTMACH+3:
     9         kx 	  return elfcore_make_note_pseudosection (abfd, ".reg2", note);
     9         kx 
     9         kx 	default:
     9         kx 	  return true;
     9         kx 	}
     9         kx     }
     9         kx     /* NOTREACHED */
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (note->descsz <= 0x48 + 31)
     9         kx     return false;
     9         kx 
     9         kx   /* Signal number at offset 0x08. */
     9         kx   elf_tdata (abfd)->core->signal
     9         kx     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
     9         kx 
     9         kx   /* Process ID at offset 0x20. */
     9         kx   elf_tdata (abfd)->core->pid
     9         kx     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
     9         kx 
     9         kx   /* Command name at 0x48 (max 32 bytes, including nul). */
     9         kx   elf_tdata (abfd)->core->command
     9         kx     = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Processes Solaris's process status note.
     9         kx    sig_off ~ offsetof(prstatus_t, pr_cursig)
     9         kx    pid_off ~ offsetof(prstatus_t, pr_pid)
     9         kx    lwpid_off ~ offsetof(prstatus_t, pr_who)
     9         kx    gregset_size ~ sizeof(gregset_t)
     9         kx    gregset_offset ~ offsetof(prstatus_t, pr_reg)  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_solaris_prstatus (bfd *abfd, Elf_Internal_Note* note, int sig_off,
     9         kx 			       int pid_off, int lwpid_off, size_t gregset_size,
     9         kx 			       size_t gregset_offset)
     9         kx {
     9         kx   asection *sect = NULL;
     9         kx   elf_tdata (abfd)->core->signal
     9         kx     = bfd_get_16 (abfd, note->descdata + sig_off);
     9         kx   elf_tdata (abfd)->core->pid
     9         kx     = bfd_get_32 (abfd, note->descdata + pid_off);
     9         kx   elf_tdata (abfd)->core->lwpid
     9         kx     = bfd_get_32 (abfd, note->descdata + lwpid_off);
     9         kx 
     9         kx   sect = bfd_get_section_by_name (abfd, ".reg");
     9         kx   if (sect != NULL)
     9         kx     sect->size = gregset_size;
     9         kx 
     9         kx   return _bfd_elfcore_make_pseudosection (abfd, ".reg", gregset_size,
     9         kx 					  note->descpos + gregset_offset);
     9         kx }
     9         kx 
     9         kx /* Gets program and arguments from a core.
     9         kx    prog_off ~ offsetof(prpsinfo | psinfo_t, pr_fname)
     9         kx    comm_off ~ offsetof(prpsinfo | psinfo_t, pr_psargs)  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_solaris_info(bfd *abfd, Elf_Internal_Note* note,
     9         kx 			  int prog_off, int comm_off)
     9         kx {
     9         kx   elf_tdata (abfd)->core->program
     9         kx     = _bfd_elfcore_strndup (abfd, note->descdata + prog_off, 16);
     9         kx   elf_tdata (abfd)->core->command
     9         kx     = _bfd_elfcore_strndup (abfd, note->descdata + comm_off, 80);
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Processes Solaris's LWP status note.
     9         kx    gregset_size ~ sizeof(gregset_t)
     9         kx    gregset_off ~ offsetof(lwpstatus_t, pr_reg)
     9         kx    fpregset_size ~ sizeof(fpregset_t)
     9         kx    fpregset_off ~ offsetof(lwpstatus_t, pr_fpreg)  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_solaris_lwpstatus (bfd *abfd, Elf_Internal_Note* note,
     9         kx 				size_t gregset_size, int gregset_off,
     9         kx 				size_t fpregset_size, int fpregset_off)
     9         kx {
     9         kx   asection *sect = NULL;
     9         kx   char reg2_section_name[16] = { 0 };
     9         kx 
     9         kx   (void) snprintf (reg2_section_name, 16, "%s/%i", ".reg2",
     9         kx 		   elf_tdata (abfd)->core->lwpid);
     9         kx 
     9         kx   /* offsetof(lwpstatus_t, pr_lwpid) */
     9         kx   elf_tdata (abfd)->core->lwpid
     9         kx     = bfd_get_32 (abfd, note->descdata + 4);
     9         kx   /* offsetof(lwpstatus_t, pr_cursig) */
     9         kx   elf_tdata (abfd)->core->signal
     9         kx     = bfd_get_16 (abfd, note->descdata + 12);
     9         kx 
     9         kx   sect = bfd_get_section_by_name (abfd, ".reg");
     9         kx   if (sect != NULL)
     9         kx     sect->size = gregset_size;
     9         kx   else if (!_bfd_elfcore_make_pseudosection (abfd, ".reg", gregset_size,
     9         kx 					     note->descpos + gregset_off))
     9         kx     return false;
     9         kx 
     9         kx   sect = bfd_get_section_by_name (abfd, reg2_section_name);
     9         kx   if (sect != NULL)
     9         kx     {
     9         kx       sect->size = fpregset_size;
     9         kx       sect->filepos = note->descpos + fpregset_off;
     9         kx       sect->alignment_power = 2;
     9         kx     }
     9         kx   else if (!_bfd_elfcore_make_pseudosection (abfd, ".reg2", fpregset_size,
     9         kx 					     note->descpos + fpregset_off))
     9         kx     return false;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_solaris_note_impl (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (note == NULL)
     9         kx     return false;
     9         kx 
     9         kx   /* core files are identified as 32- or 64-bit, SPARC or x86,
     9         kx      by the size of the descsz which matches the sizeof()
     9         kx      the type appropriate for that note type (e.g., prstatus_t for
     9         kx      SOLARIS_NT_PRSTATUS) for the corresponding architecture
     9         kx      on Solaris. The core file bitness may differ from the bitness of
     9         kx      gdb itself, so fixed values are used instead of sizeof().
     9         kx      Appropriate fixed offsets are also used to obtain data from
     9         kx      the note.  */
     9         kx 
     9         kx   switch ((int) note->type)
     9         kx     {
     9         kx     case SOLARIS_NT_PRSTATUS:
     9         kx       switch (note->descsz)
     9         kx 	{
     9         kx 	case 508: /* sizeof(prstatus_t) SPARC 32-bit */
     9         kx 	  return elfcore_grok_solaris_prstatus(abfd, note,
     9         kx 					       136, 216, 308, 152, 356);
     9         kx 	case 904: /* sizeof(prstatus_t) SPARC 64-bit */
     9         kx 	  return elfcore_grok_solaris_prstatus(abfd, note,
     9         kx 					       264, 360, 520, 304, 600);
     9         kx 	case 432: /* sizeof(prstatus_t) Intel 32-bit */
     9         kx 	  return elfcore_grok_solaris_prstatus(abfd, note,
     9         kx 					       136, 216, 308, 76, 356);
     9         kx 	case 824: /* sizeof(prstatus_t) Intel 64-bit */
     9         kx 	  return elfcore_grok_solaris_prstatus(abfd, note,
     9         kx 					       264, 360, 520, 224, 600);
     9         kx 	default:
     9         kx 	  return true;
     9         kx 	}
     9         kx 
     9         kx     case SOLARIS_NT_PSINFO:
     9         kx     case SOLARIS_NT_PRPSINFO:
     9         kx       switch (note->descsz)
     9         kx 	{
     9         kx 	case 260: /* sizeof(prpsinfo_t) SPARC and Intel 32-bit */
     9         kx 	  return elfcore_grok_solaris_info(abfd, note, 84, 100);
     9         kx 	case 328: /* sizeof(prpsinfo_t) SPARC and Intel 64-bit */
     9         kx 	  return elfcore_grok_solaris_info(abfd, note, 120, 136);
     9         kx 	case 360: /* sizeof(psinfo_t) SPARC and Intel 32-bit */
     9         kx 	  return elfcore_grok_solaris_info(abfd, note, 88, 104);
     9         kx 	case 440: /* sizeof(psinfo_t) SPARC and Intel 64-bit */
     9         kx 	  return elfcore_grok_solaris_info(abfd, note, 136, 152);
     9         kx 	default:
     9         kx 	  return true;
     9         kx 	}
     9         kx 
     9         kx     case SOLARIS_NT_LWPSTATUS:
     9         kx       switch (note->descsz)
     9         kx 	{
     9         kx 	case 896: /* sizeof(lwpstatus_t) SPARC 32-bit */
     9         kx 	  return elfcore_grok_solaris_lwpstatus(abfd, note,
     9         kx 						152, 344, 400, 496);
     9         kx 	case 1392: /* sizeof(lwpstatus_t) SPARC 64-bit */
     9         kx 	  return elfcore_grok_solaris_lwpstatus(abfd, note,
     9         kx 						304, 544, 544, 848);
     9         kx 	case 800: /* sizeof(lwpstatus_t) Intel 32-bit */
     9         kx 	  return elfcore_grok_solaris_lwpstatus(abfd, note,
     9         kx 						76, 344, 380, 420);
     9         kx 	case 1296: /* sizeof(lwpstatus_t) Intel 64-bit */
     9         kx 	  return elfcore_grok_solaris_lwpstatus(abfd, note,
     9         kx 						224, 544, 528, 768);
     9         kx 	default:
     9         kx 	  return true;
     9         kx 	}
     9         kx 
     9         kx     case SOLARIS_NT_LWPSINFO:
     9         kx       /* sizeof(lwpsinfo_t) on 32- and 64-bit, respectively */
     9         kx       if (note->descsz == 128 || note->descsz == 152)
     9         kx 	elf_tdata (abfd)->core->lwpid =
     9         kx 	  bfd_get_32 (abfd, note->descdata + 4);
     9         kx       break;
     9         kx 
     9         kx     default:
     9         kx       break;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* For name starting with "CORE" this may be either a Solaris
     9         kx    core file or a gdb-generated core file.  Do Solaris-specific
     9         kx    processing on selected note types first with
     9         kx    elfcore_grok_solaris_note(), then process the note
     9         kx    in elfcore_grok_note().  */
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_solaris_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (!elfcore_grok_solaris_note_impl (abfd, note))
     9         kx     return false;
     9         kx 
     9         kx   return elfcore_grok_note (abfd, note);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   if (note->type == NT_OPENBSD_PROCINFO)
     9         kx     return elfcore_grok_openbsd_procinfo (abfd, note);
     9         kx 
     9         kx   if (note->type == NT_OPENBSD_REGS)
     9         kx     return elfcore_make_note_pseudosection (abfd, ".reg", note);
     9         kx 
     9         kx   if (note->type == NT_OPENBSD_FPREGS)
     9         kx     return elfcore_make_note_pseudosection (abfd, ".reg2", note);
     9         kx 
     9         kx   if (note->type == NT_OPENBSD_XFPREGS)
     9         kx     return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
     9         kx 
     9         kx   if (note->type == NT_OPENBSD_AUXV)
     9         kx     return elfcore_make_auxv_note_section (abfd, note, 0);
     9         kx 
     9         kx   if (note->type == NT_OPENBSD_WCOOKIE)
     9         kx     {
     9         kx       asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
     9         kx 							   SEC_HAS_CONTENTS);
     9         kx 
     9         kx       if (sect == NULL)
     9         kx 	return false;
     9         kx       sect->size = note->descsz;
     9         kx       sect->filepos = note->descpos;
     9         kx       sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;
     9         kx 
     9         kx       return true;
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
     9         kx {
     9         kx   void *ddata = note->descdata;
     9         kx   char buf[100];
     9         kx   char *name;
     9         kx   asection *sect;
     9         kx   short sig;
     9         kx   unsigned flags;
     9         kx 
     9         kx   if (note->descsz < 16)
     9         kx     return false;
     9         kx 
     9         kx   /* nto_procfs_status 'pid' field is at offset 0.  */
     9         kx   elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
     9         kx 
     9         kx   /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
     9         kx   *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
     9         kx 
     9         kx   /* nto_procfs_status 'flags' field is at offset 8.  */
     9         kx   flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);
     9         kx 
     9         kx   /* nto_procfs_status 'what' field is at offset 14.  */
     9         kx   if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
     9         kx     {
     9         kx       elf_tdata (abfd)->core->signal = sig;
     9         kx       elf_tdata (abfd)->core->lwpid = *tid;
     9         kx     }
     9         kx 
     9         kx   /* _DEBUG_FLAG_CURTID (current thread) is 0x80.  Some cores
     9         kx      do not come from signals so we make sure we set the current
     9         kx      thread just in case.  */
     9         kx   if (flags & 0x00000080)
     9         kx     elf_tdata (abfd)->core->lwpid = *tid;
     9         kx 
     9         kx   /* Make a ".qnx_core_status/%d" section.  */
     9         kx   sprintf (buf, ".qnx_core_status/%ld", *tid);
     9         kx 
     9         kx   name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
     9         kx   if (name == NULL)
     9         kx     return false;
     9         kx   strcpy (name, buf);
     9         kx 
     9         kx   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx 
     9         kx   sect->size		= note->descsz;
     9         kx   sect->filepos		= note->descpos;
     9         kx   sect->alignment_power = 2;
     9         kx 
     9         kx   return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_nto_regs (bfd *abfd,
     9         kx 		       Elf_Internal_Note *note,
     9         kx 		       long tid,
     9         kx 		       char *base)
     9         kx {
     9         kx   char buf[100];
     9         kx   char *name;
     9         kx   asection *sect;
     9         kx 
     9         kx   /* Make a "(base)/%d" section.  */
     9         kx   sprintf (buf, "%s/%ld", base, tid);
     9         kx 
     9         kx   name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
     9         kx   if (name == NULL)
     9         kx     return false;
     9         kx   strcpy (name, buf);
     9         kx 
     9         kx   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx 
     9         kx   sect->size		= note->descsz;
     9         kx   sect->filepos		= note->descpos;
     9         kx   sect->alignment_power = 2;
     9         kx 
     9         kx   /* This is the current thread.  */
     9         kx   if (elf_tdata (abfd)->core->lwpid == tid)
     9         kx     return elfcore_maybe_make_sect (abfd, base, sect);
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx #define BFD_QNT_CORE_INFO	7
     9         kx #define BFD_QNT_CORE_STATUS	8
     9         kx #define BFD_QNT_CORE_GREG	9
     9         kx #define BFD_QNT_CORE_FPREG	10
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   /* Every GREG section has a STATUS section before it.  Store the
     9         kx      tid from the previous call to pass down to the next gregs
     9         kx      function.  */
     9         kx   static long tid = 1;
     9         kx 
     9         kx   switch (note->type)
     9         kx     {
     9         kx     case BFD_QNT_CORE_INFO:
     9         kx       return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
     9         kx     case BFD_QNT_CORE_STATUS:
     9         kx       return elfcore_grok_nto_status (abfd, note, &tid);
     9         kx     case BFD_QNT_CORE_GREG:
     9         kx       return elfcore_grok_nto_regs (abfd, note, tid, ".reg");
     9         kx     case BFD_QNT_CORE_FPREG:
     9         kx       return elfcore_grok_nto_regs (abfd, note, tid, ".reg2");
     9         kx     default:
     9         kx       return true;
     9         kx     }
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note)
     9         kx {
     9         kx   char *name;
     9         kx   asection *sect;
     9         kx   size_t len;
     9         kx 
     9         kx   /* Use note name as section name.  */
     9         kx   len = note->namesz;
     9         kx   name = (char *) bfd_alloc (abfd, len);
     9         kx   if (name == NULL)
     9         kx     return false;
     9         kx   memcpy (name, note->namedata, len);
     9         kx   name[len - 1] = '\0';
     9         kx 
     9         kx   sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
     9         kx   if (sect == NULL)
     9         kx     return false;
     9         kx 
     9         kx   sect->size		= note->descsz;
     9         kx   sect->filepos		= note->descpos;
     9         kx   sect->alignment_power = 1;
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Function: elfcore_write_note
     9         kx 
     9         kx    Inputs:
     9         kx      buffer to hold note, and current size of buffer
     9         kx      name of note
     9         kx      type of note
     9         kx      data for note
     9         kx      size of data for note
     9         kx 
     9         kx    Writes note to end of buffer.  ELF64 notes are written exactly as
     9         kx    for ELF32, despite the current (as of 2006) ELF gabi specifying
     9         kx    that they ought to have 8-byte namesz and descsz field, and have
     9         kx    8-byte alignment.  Other writers, eg. Linux kernel, do the same.
     9         kx 
     9         kx    Return:
     9         kx    Pointer to realloc'd buffer, *BUFSIZ updated.  */
     9         kx 
     9         kx char *
     9         kx elfcore_write_note (bfd *abfd,
     9         kx 		    char *buf,
     9         kx 		    int *bufsiz,
     9         kx 		    const char *name,
     9         kx 		    int type,
     9         kx 		    const void *input,
     9         kx 		    int size)
     9         kx {
     9         kx   Elf_External_Note *xnp;
     9         kx   size_t namesz;
     9         kx   size_t newspace;
     9         kx   char *dest;
     9         kx 
     9         kx   namesz = 0;
     9         kx   if (name != NULL)
     9         kx     namesz = strlen (name) + 1;
     9         kx 
     9         kx   newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);
     9         kx 
     9         kx   buf = (char *) realloc (buf, *bufsiz + newspace);
     9         kx   if (buf == NULL)
     9         kx     return buf;
     9         kx   dest = buf + *bufsiz;
     9         kx   *bufsiz += newspace;
     9         kx   xnp = (Elf_External_Note *) dest;
     9         kx   H_PUT_32 (abfd, namesz, xnp->namesz);
     9         kx   H_PUT_32 (abfd, size, xnp->descsz);
     9         kx   H_PUT_32 (abfd, type, xnp->type);
     9         kx   dest = xnp->name;
     9         kx   if (name != NULL)
     9         kx     {
     9         kx       memcpy (dest, name, namesz);
     9         kx       dest += namesz;
     9         kx       while (namesz & 3)
     9         kx 	{
     9         kx 	  *dest++ = '\0';
     9         kx 	  ++namesz;
     9         kx 	}
     9         kx     }
     9         kx   memcpy (dest, input, size);
     9         kx   dest += size;
     9         kx   while (size & 3)
     9         kx     {
     9         kx       *dest++ = '\0';
     9         kx       ++size;
     9         kx     }
     9         kx   return buf;
     9         kx }
     9         kx 
     9         kx /* gcc-8 warns (*) on all the strncpy calls in this function about
     9         kx    possible string truncation.  The "truncation" is not a bug.  We
     9         kx    have an external representation of structs with fields that are not
     9         kx    necessarily NULL terminated and corresponding internal
     9         kx    representation fields that are one larger so that they can always
     9         kx    be NULL terminated.
     9         kx    gcc versions between 4.2 and 4.6 do not allow pragma control of
     9         kx    diagnostics inside functions, giving a hard error if you try to use
     9         kx    the finer control available with later versions.
     9         kx    gcc prior to 4.2 warns about diagnostic push and pop.
     9         kx    gcc-5, gcc-6 and gcc-7 warn that -Wstringop-truncation is unknown,
     9         kx    unless you also add #pragma GCC diagnostic ignored "-Wpragma".
     9         kx    (*) Depending on your system header files!  */
     9         kx #if GCC_VERSION >= 8000
     9         kx # pragma GCC diagnostic push
     9         kx # pragma GCC diagnostic ignored "-Wstringop-truncation"
     9         kx #endif
     9         kx char *
     9         kx elfcore_write_prpsinfo (bfd  *abfd,
     9         kx 			char *buf,
     9         kx 			int  *bufsiz,
     9         kx 			const char *fname,
     9         kx 			const char *psargs)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   if (bed->elf_backend_write_core_note != NULL)
     9         kx     {
     9         kx       char *ret;
     9         kx       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
     9         kx 						 NT_PRPSINFO, fname, psargs);
     9         kx       if (ret != NULL)
     9         kx 	return ret;
     9         kx     }
     9         kx 
     9         kx #if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
     9         kx # if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
     9         kx   if (bed->s->elfclass == ELFCLASS32)
     9         kx     {
     9         kx #  if defined (HAVE_PSINFO32_T)
     9         kx       psinfo32_t data;
     9         kx       int note_type = NT_PSINFO;
     9         kx #  else
     9         kx       prpsinfo32_t data;
     9         kx       int note_type = NT_PRPSINFO;
     9         kx #  endif
     9         kx 
     9         kx       memset (&data, 0, sizeof (data));
     9         kx       strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
     9         kx       strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
     9         kx       return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 				 "CORE", note_type, &data, sizeof (data));
     9         kx     }
     9         kx   else
     9         kx # endif
     9         kx     {
     9         kx # if defined (HAVE_PSINFO_T)
     9         kx       psinfo_t data;
     9         kx       int note_type = NT_PSINFO;
     9         kx # else
     9         kx       prpsinfo_t data;
     9         kx       int note_type = NT_PRPSINFO;
     9         kx # endif
     9         kx 
     9         kx       memset (&data, 0, sizeof (data));
     9         kx       strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
     9         kx       strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
     9         kx       return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 				 "CORE", note_type, &data, sizeof (data));
     9         kx     }
     9         kx #endif	/* PSINFO_T or PRPSINFO_T */
     9         kx 
     9         kx   free (buf);
     9         kx   return NULL;
     9         kx }
     9         kx #if GCC_VERSION >= 8000
     9         kx # pragma GCC diagnostic pop
     9         kx #endif
     9         kx 
     9         kx char *
     9         kx elfcore_write_linux_prpsinfo32
     9         kx   (bfd *abfd, char *buf, int *bufsiz,
     9         kx    const struct elf_internal_linux_prpsinfo *prpsinfo)
     9         kx {
     9         kx   if (get_elf_backend_data (abfd)->linux_prpsinfo32_ugid16)
     9         kx     {
     9         kx       struct elf_external_linux_prpsinfo32_ugid16 data;
     9         kx 
     9         kx       swap_linux_prpsinfo32_ugid16_out (abfd, prpsinfo, &data);
     9         kx       return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
     9         kx 				 &data, sizeof (data));
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       struct elf_external_linux_prpsinfo32_ugid32 data;
     9         kx 
     9         kx       swap_linux_prpsinfo32_ugid32_out (abfd, prpsinfo, &data);
     9         kx       return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
     9         kx 				 &data, sizeof (data));
     9         kx     }
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_linux_prpsinfo64
     9         kx   (bfd *abfd, char *buf, int *bufsiz,
     9         kx    const struct elf_internal_linux_prpsinfo *prpsinfo)
     9         kx {
     9         kx   if (get_elf_backend_data (abfd)->linux_prpsinfo64_ugid16)
     9         kx     {
     9         kx       struct elf_external_linux_prpsinfo64_ugid16 data;
     9         kx 
     9         kx       swap_linux_prpsinfo64_ugid16_out (abfd, prpsinfo, &data);
     9         kx       return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 				 "CORE", NT_PRPSINFO, &data, sizeof (data));
     9         kx     }
     9         kx   else
     9         kx     {
     9         kx       struct elf_external_linux_prpsinfo64_ugid32 data;
     9         kx 
     9         kx       swap_linux_prpsinfo64_ugid32_out (abfd, prpsinfo, &data);
     9         kx       return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 				 "CORE", NT_PRPSINFO, &data, sizeof (data));
     9         kx     }
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_prstatus (bfd *abfd,
     9         kx 			char *buf,
     9         kx 			int *bufsiz,
     9         kx 			long pid,
     9         kx 			int cursig,
     9         kx 			const void *gregs)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   if (bed->elf_backend_write_core_note != NULL)
     9         kx     {
     9         kx       char *ret;
     9         kx       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
     9         kx 						 NT_PRSTATUS,
     9         kx 						 pid, cursig, gregs);
     9         kx       if (ret != NULL)
     9         kx 	return ret;
     9         kx     }
     9         kx 
     9         kx #if defined (HAVE_PRSTATUS_T)
     9         kx #if defined (HAVE_PRSTATUS32_T)
     9         kx   if (bed->s->elfclass == ELFCLASS32)
     9         kx     {
     9         kx       prstatus32_t prstat;
     9         kx 
     9         kx       memset (&prstat, 0, sizeof (prstat));
     9         kx       prstat.pr_pid = pid;
     9         kx       prstat.pr_cursig = cursig;
     9         kx       memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
     9         kx       return elfcore_write_note (abfd, buf, bufsiz, "CORE",
     9         kx 				 NT_PRSTATUS, &prstat, sizeof (prstat));
     9         kx     }
     9         kx   else
     9         kx #endif
     9         kx     {
     9         kx       prstatus_t prstat;
     9         kx 
     9         kx       memset (&prstat, 0, sizeof (prstat));
     9         kx       prstat.pr_pid = pid;
     9         kx       prstat.pr_cursig = cursig;
     9         kx       memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
     9         kx       return elfcore_write_note (abfd, buf, bufsiz, "CORE",
     9         kx 				 NT_PRSTATUS, &prstat, sizeof (prstat));
     9         kx     }
     9         kx #endif /* HAVE_PRSTATUS_T */
     9         kx 
     9         kx   free (buf);
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx #if defined (HAVE_LWPSTATUS_T)
     9         kx char *
     9         kx elfcore_write_lwpstatus (bfd *abfd,
     9         kx 			 char *buf,
     9         kx 			 int *bufsiz,
     9         kx 			 long pid,
     9         kx 			 int cursig,
     9         kx 			 const void *gregs)
     9         kx {
     9         kx   lwpstatus_t lwpstat;
     9         kx   const char *note_name = "CORE";
     9         kx 
     9         kx   memset (&lwpstat, 0, sizeof (lwpstat));
     9         kx   lwpstat.pr_lwpid  = pid >> 16;
     9         kx   lwpstat.pr_cursig = cursig;
     9         kx #if defined (HAVE_LWPSTATUS_T_PR_REG)
     9         kx   memcpy (&lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
     9         kx #elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
     9         kx #if !defined(gregs)
     9         kx   memcpy (lwpstat.pr_context.uc_mcontext.gregs,
     9         kx 	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
     9         kx #else
     9         kx   memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
     9         kx 	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
     9         kx #endif
     9         kx #endif
     9         kx   return elfcore_write_note (abfd, buf, bufsiz, note_name,
     9         kx 			     NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
     9         kx }
     9         kx #endif /* HAVE_LWPSTATUS_T */
     9         kx 
     9         kx #if defined (HAVE_PSTATUS_T)
     9         kx char *
     9         kx elfcore_write_pstatus (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       long pid,
     9         kx 		       int cursig ATTRIBUTE_UNUSED,
     9         kx 		       const void *gregs ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   const char *note_name = "CORE";
     9         kx #if defined (HAVE_PSTATUS32_T)
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 
     9         kx   if (bed->s->elfclass == ELFCLASS32)
     9         kx     {
     9         kx       pstatus32_t pstat;
     9         kx 
     9         kx       memset (&pstat, 0, sizeof (pstat));
     9         kx       pstat.pr_pid = pid & 0xffff;
     9         kx       buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
     9         kx 				NT_PSTATUS, &pstat, sizeof (pstat));
     9         kx       return buf;
     9         kx     }
     9         kx   else
     9         kx #endif
     9         kx     {
     9         kx       pstatus_t pstat;
     9         kx 
     9         kx       memset (&pstat, 0, sizeof (pstat));
     9         kx       pstat.pr_pid = pid & 0xffff;
     9         kx       buf = elfcore_write_note (abfd, buf, bufsiz, note_name,
     9         kx 				NT_PSTATUS, &pstat, sizeof (pstat));
     9         kx       return buf;
     9         kx     }
     9         kx }
     9         kx #endif /* HAVE_PSTATUS_T */
     9         kx 
     9         kx char *
     9         kx elfcore_write_prfpreg (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *fpregs,
     9         kx 		       int size)
     9         kx {
     9         kx   const char *note_name = "CORE";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_FPREGSET, fpregs, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_prxfpreg (bfd *abfd,
     9         kx 			char *buf,
     9         kx 			int *bufsiz,
     9         kx 			const void *xfpregs,
     9         kx 			int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PRXFPREG, xfpregs, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
     9         kx 			 const void *xfpregs, int size)
     9         kx {
     9         kx   char *note_name;
     9         kx   if (get_elf_backend_data (abfd)->elf_osabi == ELFOSABI_FREEBSD)
     9         kx     note_name = "FreeBSD";
     9         kx   else
     9         kx     note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_X86_XSTATE, xfpregs, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_x86_segbases (bfd *abfd, char *buf, int *bufsiz,
     9         kx 			    const void *regs, int size)
     9         kx {
     9         kx   char *note_name = "FreeBSD";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_FREEBSD_X86_SEGBASES, regs, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_vmx (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *ppc_vmx,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_VMX, ppc_vmx, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_vsx (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *ppc_vsx,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_VSX, ppc_vsx, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tar (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *ppc_tar,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TAR, ppc_tar, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_ppr (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *ppc_ppr,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_PPR, ppc_ppr, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_dscr (bfd *abfd,
     9         kx 			char *buf,
     9         kx 			int *bufsiz,
     9         kx 			const void *ppc_dscr,
     9         kx 			int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_DSCR, ppc_dscr, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_ebb (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *ppc_ebb,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_EBB, ppc_ebb, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_pmu (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *ppc_pmu,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_PMU, ppc_pmu, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_cgpr (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *ppc_tm_cgpr,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CGPR, ppc_tm_cgpr, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_cfpr (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *ppc_tm_cfpr,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CFPR, ppc_tm_cfpr, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_cvmx (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *ppc_tm_cvmx,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CVMX, ppc_tm_cvmx, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_cvsx (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *ppc_tm_cvsx,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CVSX, ppc_tm_cvsx, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_spr (bfd *abfd,
     9         kx 			  char *buf,
     9         kx 			  int *bufsiz,
     9         kx 			  const void *ppc_tm_spr,
     9         kx 			  int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_SPR, ppc_tm_spr, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_ctar (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *ppc_tm_ctar,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CTAR, ppc_tm_ctar, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_cppr (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *ppc_tm_cppr,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CPPR, ppc_tm_cppr, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_ppc_tm_cdscr (bfd *abfd,
     9         kx 			    char *buf,
     9         kx 			    int *bufsiz,
     9         kx 			    const void *ppc_tm_cdscr,
     9         kx 			    int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_PPC_TM_CDSCR, ppc_tm_cdscr, size);
     9         kx }
     9         kx 
     9         kx static char *
     9         kx elfcore_write_s390_high_gprs (bfd *abfd,
     9         kx 			      char *buf,
     9         kx 			      int *bufsiz,
     9         kx 			      const void *s390_high_gprs,
     9         kx 			      int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_HIGH_GPRS,
     9         kx 			     s390_high_gprs, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_timer (bfd *abfd,
     9         kx 			  char *buf,
     9         kx 			  int *bufsiz,
     9         kx 			  const void *s390_timer,
     9         kx 			  int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_TIMER, s390_timer, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_todcmp (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *s390_todcmp,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_TODCMP, s390_todcmp, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_todpreg (bfd *abfd,
     9         kx 			    char *buf,
     9         kx 			    int *bufsiz,
     9         kx 			    const void *s390_todpreg,
     9         kx 			    int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_TODPREG, s390_todpreg, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_ctrs (bfd *abfd,
     9         kx 			 char *buf,
     9         kx 			 int *bufsiz,
     9         kx 			 const void *s390_ctrs,
     9         kx 			 int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_CTRS, s390_ctrs, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_prefix (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *s390_prefix,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_PREFIX, s390_prefix, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_last_break (bfd *abfd,
     9         kx 			       char *buf,
     9         kx 			       int *bufsiz,
     9         kx 			       const void *s390_last_break,
     9         kx 			       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_LAST_BREAK,
     9         kx 			     s390_last_break, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_system_call (bfd *abfd,
     9         kx 				char *buf,
     9         kx 				int *bufsiz,
     9         kx 				const void *s390_system_call,
     9         kx 				int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_SYSTEM_CALL,
     9         kx 			     s390_system_call, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_tdb (bfd *abfd,
     9         kx 			char *buf,
     9         kx 			int *bufsiz,
     9         kx 			const void *s390_tdb,
     9         kx 			int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_TDB, s390_tdb, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_vxrs_low (bfd *abfd,
     9         kx 			     char *buf,
     9         kx 			     int *bufsiz,
     9         kx 			     const void *s390_vxrs_low,
     9         kx 			     int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_VXRS_LOW, s390_vxrs_low, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_vxrs_high (bfd *abfd,
     9         kx 			     char *buf,
     9         kx 			     int *bufsiz,
     9         kx 			     const void *s390_vxrs_high,
     9         kx 			     int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_VXRS_HIGH,
     9         kx 			     s390_vxrs_high, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_gs_cb (bfd *abfd,
     9         kx 			  char *buf,
     9         kx 			  int *bufsiz,
     9         kx 			  const void *s390_gs_cb,
     9         kx 			  int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_GS_CB,
     9         kx 			     s390_gs_cb, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_s390_gs_bc (bfd *abfd,
     9         kx 			  char *buf,
     9         kx 			  int *bufsiz,
     9         kx 			  const void *s390_gs_bc,
     9         kx 			  int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_S390_GS_BC,
     9         kx 			     s390_gs_bc, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_arm_vfp (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *arm_vfp,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_VFP, arm_vfp, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_aarch_tls (bfd *abfd,
     9         kx 		       char *buf,
     9         kx 		       int *bufsiz,
     9         kx 		       const void *aarch_tls,
     9         kx 		       int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_TLS, aarch_tls, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_aarch_hw_break (bfd *abfd,
     9         kx 			    char *buf,
     9         kx 			    int *bufsiz,
     9         kx 			    const void *aarch_hw_break,
     9         kx 			    int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_HW_BREAK, aarch_hw_break, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_aarch_hw_watch (bfd *abfd,
     9         kx 			    char *buf,
     9         kx 			    int *bufsiz,
     9         kx 			    const void *aarch_hw_watch,
     9         kx 			    int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_aarch_sve (bfd *abfd,
     9         kx 			 char *buf,
     9         kx 			 int *bufsiz,
     9         kx 			 const void *aarch_sve,
     9         kx 			 int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_SVE, aarch_sve, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_aarch_pauth (bfd *abfd,
     9         kx 			   char *buf,
     9         kx 			   int *bufsiz,
     9         kx 			   const void *aarch_pauth,
     9         kx 			   int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_PAC_MASK, aarch_pauth, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_aarch_mte (bfd *abfd,
     9         kx 				      char *buf,
     9         kx 				      int *bufsiz,
     9         kx 				      const void *aarch_mte,
     9         kx 				      int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARM_TAGGED_ADDR_CTRL,
     9         kx 			     aarch_mte,
     9         kx 			     size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_arc_v2 (bfd *abfd,
     9         kx 		      char *buf,
     9         kx 		      int *bufsiz,
     9         kx 		      const void *arc_v2,
     9         kx 		      int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_ARC_V2, arc_v2, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_loongarch_cpucfg (bfd *abfd,
     9         kx 				char *buf,
     9         kx 				int *bufsiz,
     9         kx 				const void *loongarch_cpucfg,
     9         kx 				int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_LARCH_CPUCFG,
     9         kx 			     loongarch_cpucfg, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_loongarch_lbt (bfd *abfd,
     9         kx 			     char *buf,
     9         kx 			     int *bufsiz,
     9         kx 			     const void *loongarch_lbt,
     9         kx 			     int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_LARCH_LBT, loongarch_lbt, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_loongarch_lsx (bfd *abfd,
     9         kx 			     char *buf,
     9         kx 			     int *bufsiz,
     9         kx 			     const void *loongarch_lsx,
     9         kx 			     int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_LARCH_LSX, loongarch_lsx, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_loongarch_lasx (bfd *abfd,
     9         kx 			      char *buf,
     9         kx 			      int *bufsiz,
     9         kx 			      const void *loongarch_lasx,
     9         kx 			      int size)
     9         kx {
     9         kx   char *note_name = "LINUX";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_LARCH_LASX, loongarch_lasx, size);
     9         kx }
     9         kx 
     9         kx /* Write the buffer of csr values in CSRS (length SIZE) into the note
     9         kx    buffer BUF and update *BUFSIZ.  ABFD is the bfd the note is being
     9         kx    written into.  Return a pointer to the new start of the note buffer, to
     9         kx    replace BUF which may no longer be valid.  */
     9         kx 
     9         kx char *
     9         kx elfcore_write_riscv_csr (bfd *abfd,
     9         kx 			 char *buf,
     9         kx 			 int *bufsiz,
     9         kx 			 const void *csrs,
     9         kx 			 int size)
     9         kx {
     9         kx   const char *note_name = "GDB";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_RISCV_CSR, csrs, size);
     9         kx }
     9         kx 
     9         kx /* Write the target description (a string) pointed to by TDESC, length
     9         kx    SIZE, into the note buffer BUF, and update *BUFSIZ.  ABFD is the bfd the
     9         kx    note is being written into.  Return a pointer to the new start of the
     9         kx    note buffer, to replace BUF which may no longer be valid.  */
     9         kx 
     9         kx char *
     9         kx elfcore_write_gdb_tdesc (bfd *abfd,
     9         kx 			 char *buf,
     9         kx 			 int *bufsiz,
     9         kx 			 const void *tdesc,
     9         kx 			 int size)
     9         kx {
     9         kx   const char *note_name = "GDB";
     9         kx   return elfcore_write_note (abfd, buf, bufsiz,
     9         kx 			     note_name, NT_GDB_TDESC, tdesc, size);
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_register_note (bfd *abfd,
     9         kx 			     char *buf,
     9         kx 			     int *bufsiz,
     9         kx 			     const char *section,
     9         kx 			     const void *data,
     9         kx 			     int size)
     9         kx {
     9         kx   if (strcmp (section, ".reg2") == 0)
     9         kx     return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-xfp") == 0)
     9         kx     return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-xstate") == 0)
     9         kx     return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-x86-segbases") == 0)
     9         kx     return elfcore_write_x86_segbases (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-vmx") == 0)
     9         kx     return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-vsx") == 0)
     9         kx     return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tar") == 0)
     9         kx     return elfcore_write_ppc_tar (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-ppr") == 0)
     9         kx     return elfcore_write_ppc_ppr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-dscr") == 0)
     9         kx     return elfcore_write_ppc_dscr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-ebb") == 0)
     9         kx     return elfcore_write_ppc_ebb (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-pmu") == 0)
     9         kx     return elfcore_write_ppc_pmu (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-cgpr") == 0)
     9         kx     return elfcore_write_ppc_tm_cgpr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-cfpr") == 0)
     9         kx     return elfcore_write_ppc_tm_cfpr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-cvmx") == 0)
     9         kx     return elfcore_write_ppc_tm_cvmx (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-cvsx") == 0)
     9         kx     return elfcore_write_ppc_tm_cvsx (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-spr") == 0)
     9         kx     return elfcore_write_ppc_tm_spr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-ctar") == 0)
     9         kx     return elfcore_write_ppc_tm_ctar (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-cppr") == 0)
     9         kx     return elfcore_write_ppc_tm_cppr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-ppc-tm-cdscr") == 0)
     9         kx     return elfcore_write_ppc_tm_cdscr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-high-gprs") == 0)
     9         kx     return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-timer") == 0)
     9         kx     return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-todcmp") == 0)
     9         kx     return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-todpreg") == 0)
     9         kx     return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-ctrs") == 0)
     9         kx     return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-prefix") == 0)
     9         kx     return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-last-break") == 0)
     9         kx     return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-system-call") == 0)
     9         kx     return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-tdb") == 0)
     9         kx     return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-vxrs-low") == 0)
     9         kx     return elfcore_write_s390_vxrs_low (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-vxrs-high") == 0)
     9         kx     return elfcore_write_s390_vxrs_high (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-gs-cb") == 0)
     9         kx     return elfcore_write_s390_gs_cb (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-s390-gs-bc") == 0)
     9         kx     return elfcore_write_s390_gs_bc (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-arm-vfp") == 0)
     9         kx     return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-aarch-tls") == 0)
     9         kx     return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-aarch-hw-break") == 0)
     9         kx     return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-aarch-hw-watch") == 0)
     9         kx     return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-aarch-sve") == 0)
     9         kx     return elfcore_write_aarch_sve (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-aarch-pauth") == 0)
     9         kx     return elfcore_write_aarch_pauth (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-aarch-mte") == 0)
     9         kx     return elfcore_write_aarch_mte (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-arc-v2") == 0)
     9         kx     return elfcore_write_arc_v2 (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".gdb-tdesc") == 0)
     9         kx     return elfcore_write_gdb_tdesc (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-riscv-csr") == 0)
     9         kx     return elfcore_write_riscv_csr (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-loongarch-cpucfg") == 0)
     9         kx     return elfcore_write_loongarch_cpucfg (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-loongarch-lbt") == 0)
     9         kx     return elfcore_write_loongarch_lbt (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-loongarch-lsx") == 0)
     9         kx     return elfcore_write_loongarch_lsx (abfd, buf, bufsiz, data, size);
     9         kx   if (strcmp (section, ".reg-loongarch-lasx") == 0)
     9         kx     return elfcore_write_loongarch_lasx (abfd, buf, bufsiz, data, size);
     9         kx   return NULL;
     9         kx }
     9         kx 
     9         kx char *
     9         kx elfcore_write_file_note (bfd *obfd, char *note_data, int *note_size,
     9         kx 			 const void *buf, int bufsiz)
     9         kx {
     9         kx   return elfcore_write_note (obfd, note_data, note_size,
     9         kx 			     "CORE", NT_FILE, buf, bufsiz);
     9         kx }
     9         kx 
     9         kx static bool
     9         kx elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset,
     9         kx 		 size_t align)
     9         kx {
     9         kx   char *p;
     9         kx 
     9         kx   /* NB: CORE PT_NOTE segments may have p_align values of 0 or 1.
     9         kx      gABI specifies that PT_NOTE alignment should be aligned to 4
     9         kx      bytes for 32-bit objects and to 8 bytes for 64-bit objects.  If
     9         kx      align is less than 4, we use 4 byte alignment.   */
     9         kx   if (align < 4)
     9         kx     align = 4;
     9         kx   if (align != 4 && align != 8)
     9         kx     return false;
     9         kx 
     9         kx   p = buf;
     9         kx   while (p < buf + size)
     9         kx     {
     9         kx       Elf_External_Note *xnp = (Elf_External_Note *) p;
     9         kx       Elf_Internal_Note in;
     9         kx 
     9         kx       if (offsetof (Elf_External_Note, name) > buf - p + size)
     9         kx 	return false;
     9         kx 
     9         kx       in.type = H_GET_32 (abfd, xnp->type);
     9         kx 
     9         kx       in.namesz = H_GET_32 (abfd, xnp->namesz);
     9         kx       in.namedata = xnp->name;
     9         kx       if (in.namesz > buf - in.namedata + size)
     9         kx 	return false;
     9         kx 
     9         kx       in.descsz = H_GET_32 (abfd, xnp->descsz);
     9         kx       in.descdata = p + ELF_NOTE_DESC_OFFSET (in.namesz, align);
     9         kx       in.descpos = offset + (in.descdata - buf);
     9         kx       if (in.descsz != 0
     9         kx 	  && (in.descdata >= buf + size
     9         kx 	      || in.descsz > buf - in.descdata + size))
     9         kx 	return false;
     9         kx 
     9         kx       switch (bfd_get_format (abfd))
     9         kx 	{
     9         kx 	default:
     9         kx 	  return true;
     9         kx 
     9         kx 	case bfd_core:
     9         kx 	  {
     9         kx #define GROKER_ELEMENT(S,F) {S, sizeof (S) - 1, F}
     9         kx 	    struct
     9         kx 	    {
     9         kx 	      const char * string;
     9         kx 	      size_t len;
     9         kx 	      bool (*func) (bfd *, Elf_Internal_Note *);
     9         kx 	    }
     9         kx 	    grokers[] =
     9         kx 	    {
     9         kx 	      GROKER_ELEMENT ("", elfcore_grok_note),
     9         kx 	      GROKER_ELEMENT ("FreeBSD", elfcore_grok_freebsd_note),
     9         kx 	      GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note),
     9         kx 	      GROKER_ELEMENT ("OpenBSD", elfcore_grok_openbsd_note),
     9         kx 	      GROKER_ELEMENT ("QNX", elfcore_grok_nto_note),
     9         kx 	      GROKER_ELEMENT ("SPU/", elfcore_grok_spu_note),
     9         kx 	      GROKER_ELEMENT ("GNU", elfobj_grok_gnu_note),
     9         kx 	      GROKER_ELEMENT ("CORE", elfcore_grok_solaris_note)
     9         kx 	    };
     9         kx #undef GROKER_ELEMENT
     9         kx 	    int i;
     9         kx 
     9         kx 	    for (i = ARRAY_SIZE (grokers); i--;)
     9         kx 	      {
     9         kx 		if (in.namesz >= grokers[i].len
     9         kx 		    && strncmp (in.namedata, grokers[i].string,
     9         kx 				grokers[i].len) == 0)
     9         kx 		  {
     9         kx 		    if (! grokers[i].func (abfd, & in))
     9         kx 		      return false;
     9         kx 		    break;
     9         kx 		  }
     9         kx 	      }
     9         kx 	    break;
     9         kx 	  }
     9         kx 
     9         kx 	case bfd_object:
     9         kx 	  if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
     9         kx 	    {
     9         kx 	      if (! elfobj_grok_gnu_note (abfd, &in))
     9         kx 		return false;
     9         kx 	    }
     9         kx 	  else if (in.namesz == sizeof "stapsdt"
     9         kx 		   && strcmp (in.namedata, "stapsdt") == 0)
     9         kx 	    {
     9         kx 	      if (! elfobj_grok_stapsdt_note (abfd, &in))
     9         kx 		return false;
     9         kx 	    }
     9         kx 	  break;
     9         kx 	}
     9         kx 
     9         kx       p += ELF_NOTE_NEXT_OFFSET (in.namesz, in.descsz, align);
     9         kx     }
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx bool
     9         kx elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size,
     9         kx 		size_t align)
     9         kx {
     9         kx   char *buf;
     9         kx 
     9         kx   if (size == 0 || (size + 1) == 0)
     9         kx     return true;
     9         kx 
     9         kx   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
     9         kx     return false;
     9         kx 
     9         kx   buf = (char *) _bfd_malloc_and_read (abfd, size + 1, size);
     9         kx   if (buf == NULL)
     9         kx     return false;
     9         kx 
     9         kx   /* PR 17512: file: ec08f814
     9         kx      0-termintate the buffer so that string searches will not overflow.  */
     9         kx   buf[size] = 0;
     9         kx 
     9         kx   if (!elf_parse_notes (abfd, buf, size, offset, align))
     9         kx     {
     9         kx       free (buf);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   free (buf);
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Providing external access to the ELF program header table.  */
     9         kx 
     9         kx /* Return an upper bound on the number of bytes required to store a
     9         kx    copy of ABFD's program header table entries.  Return -1 if an error
     9         kx    occurs; bfd_get_error will return an appropriate code.  */
     9         kx 
     9         kx long
     9         kx bfd_get_elf_phdr_upper_bound (bfd *abfd)
     9         kx {
     9         kx   if (abfd->xvec->flavour != bfd_target_elf_flavour)
     9         kx     {
     9         kx       bfd_set_error (bfd_error_wrong_format);
     9         kx       return -1;
     9         kx     }
     9         kx 
     9         kx   return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
     9         kx }
     9         kx 
     9         kx /* Copy ABFD's program header table entries to *PHDRS.  The entries
     9         kx    will be stored as an array of Elf_Internal_Phdr structures, as
     9         kx    defined in include/elf/internal.h.  To find out how large the
     9         kx    buffer needs to be, call bfd_get_elf_phdr_upper_bound.
     9         kx 
     9         kx    Return the number of program header table entries read, or -1 if an
     9         kx    error occurs; bfd_get_error will return an appropriate code.  */
     9         kx 
     9         kx int
     9         kx bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
     9         kx {
     9         kx   int num_phdrs;
     9         kx 
     9         kx   if (abfd->xvec->flavour != bfd_target_elf_flavour)
     9         kx     {
     9         kx       bfd_set_error (bfd_error_wrong_format);
     9         kx       return -1;
     9         kx     }
     9         kx 
     9         kx   num_phdrs = elf_elfheader (abfd)->e_phnum;
     9         kx   if (num_phdrs != 0)
     9         kx     memcpy (phdrs, elf_tdata (abfd)->phdr,
     9         kx 	    num_phdrs * sizeof (Elf_Internal_Phdr));
     9         kx 
     9         kx   return num_phdrs;
     9         kx }
     9         kx 
     9         kx enum elf_reloc_type_class
     9         kx _bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
     9         kx 			   const asection *rel_sec ATTRIBUTE_UNUSED,
     9         kx 			   const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
     9         kx {
     9         kx   return reloc_class_normal;
     9         kx }
     9         kx 
     9         kx /* For RELA architectures, return the relocation value for a
     9         kx    relocation against a local symbol.  */
     9         kx 
     9         kx bfd_vma
     9         kx _bfd_elf_rela_local_sym (bfd *abfd,
     9         kx 			 Elf_Internal_Sym *sym,
     9         kx 			 asection **psec,
     9         kx 			 Elf_Internal_Rela *rel)
     9         kx {
     9         kx   asection *sec = *psec;
     9         kx   bfd_vma relocation;
     9         kx 
     9         kx   relocation = (sec->output_section->vma
     9         kx 		+ sec->output_offset
     9         kx 		+ sym->st_value);
     9         kx   if ((sec->flags & SEC_MERGE)
     9         kx       && ELF_ST_TYPE (sym->st_info) == STT_SECTION
     9         kx       && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
     9         kx     {
     9         kx       rel->r_addend =
     9         kx 	_bfd_merged_section_offset (abfd, psec,
     9         kx 				    elf_section_data (sec)->sec_info,
     9         kx 				    sym->st_value + rel->r_addend);
     9         kx       if (sec != *psec)
     9         kx 	{
     9         kx 	  /* If we have changed the section, and our original section is
     9         kx 	     marked with SEC_EXCLUDE, it means that the original
     9         kx 	     SEC_MERGE section has been completely subsumed in some
     9         kx 	     other SEC_MERGE section.  In this case, we need to leave
     9         kx 	     some info around for --emit-relocs.  */
     9         kx 	  if ((sec->flags & SEC_EXCLUDE) != 0)
     9         kx 	    sec->kept_section = *psec;
     9         kx 	  sec = *psec;
     9         kx 	}
     9         kx       rel->r_addend -= relocation;
     9         kx       rel->r_addend += sec->output_section->vma + sec->output_offset;
     9         kx     }
     9         kx   return relocation;
     9         kx }
     9         kx 
     9         kx bfd_vma
     9         kx _bfd_elf_rel_local_sym (bfd *abfd,
     9         kx 			Elf_Internal_Sym *sym,
     9         kx 			asection **psec,
     9         kx 			bfd_vma addend)
     9         kx {
     9         kx   asection *sec = *psec;
     9         kx 
     9         kx   if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
     9         kx     return sym->st_value + addend;
     9         kx 
     9         kx   return _bfd_merged_section_offset (abfd, psec,
     9         kx 				     elf_section_data (sec)->sec_info,
     9         kx 				     sym->st_value + addend);
     9         kx }
     9         kx 
     9         kx /* Adjust an address within a section.  Given OFFSET within SEC, return
     9         kx    the new offset within the section, based upon changes made to the
     9         kx    section.  Returns -1 if the offset is now invalid.
     9         kx    The offset (in abnd out) is in target sized bytes, however big a
     9         kx    byte may be.  */
     9         kx 
     9         kx bfd_vma
     9         kx _bfd_elf_section_offset (bfd *abfd,
     9         kx 			 struct bfd_link_info *info,
     9         kx 			 asection *sec,
     9         kx 			 bfd_vma offset)
     9         kx {
     9         kx   switch (sec->sec_info_type)
     9         kx     {
     9         kx     case SEC_INFO_TYPE_STABS:
     9         kx       return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
     9         kx 				       offset);
     9         kx     case SEC_INFO_TYPE_EH_FRAME:
     9         kx       return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
     9         kx 
     9         kx     default:
     9         kx       if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
     9         kx 	{
     9         kx 	  /* Reverse the offset.  */
     9         kx 	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx 	  bfd_size_type address_size = bed->s->arch_size / 8;
     9         kx 
     9         kx 	  /* address_size and sec->size are in octets.  Convert
     9         kx 	     to bytes before subtracting the original offset.  */
     9         kx 	  offset = ((sec->size - address_size)
     9         kx 		    / bfd_octets_per_byte (abfd, sec) - offset);
     9         kx 	}
     9         kx       return offset;
     9         kx     }
     9         kx }
     9         kx 
     9         kx /* Create a new BFD as if by bfd_openr.  Rather than opening a file,
     9         kx    reconstruct an ELF file by reading the segments out of remote memory
     9         kx    based on the ELF file header at EHDR_VMA and the ELF program headers it
     9         kx    points to.  If not null, *LOADBASEP is filled in with the difference
     9         kx    between the VMAs from which the segments were read, and the VMAs the
     9         kx    file headers (and hence BFD's idea of each section's VMA) put them at.
     9         kx 
     9         kx    The function TARGET_READ_MEMORY is called to copy LEN bytes from the
     9         kx    remote memory at target address VMA into the local buffer at MYADDR; it
     9         kx    should return zero on success or an `errno' code on failure.  TEMPL must
     9         kx    be a BFD for an ELF target with the word size and byte order found in
     9         kx    the remote memory.  */
     9         kx 
     9         kx bfd *
     9         kx bfd_elf_bfd_from_remote_memory
     9         kx   (bfd *templ,
     9         kx    bfd_vma ehdr_vma,
     9         kx    bfd_size_type size,
     9         kx    bfd_vma *loadbasep,
     9         kx    int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
     9         kx {
     9         kx   return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
     9         kx     (templ, ehdr_vma, size, loadbasep, target_read_memory);
     9         kx }
     9         kx 
     9         kx long
     9         kx _bfd_elf_get_synthetic_symtab (bfd *abfd,
     9         kx 			       long symcount ATTRIBUTE_UNUSED,
     9         kx 			       asymbol **syms ATTRIBUTE_UNUSED,
     9         kx 			       long dynsymcount,
     9         kx 			       asymbol **dynsyms,
     9         kx 			       asymbol **ret)
     9         kx {
     9         kx   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     9         kx   asection *relplt;
     9         kx   asymbol *s;
     9         kx   const char *relplt_name;
     9         kx   bool (*slurp_relocs) (bfd *, asection *, asymbol **, bool);
     9         kx   arelent *p;
     9         kx   long count, i, n;
     9         kx   size_t size;
     9         kx   Elf_Internal_Shdr *hdr;
     9         kx   char *names;
     9         kx   asection *plt;
     9         kx 
     9         kx   *ret = NULL;
     9         kx 
     9         kx   if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
     9         kx     return 0;
     9         kx 
     9         kx   if (dynsymcount <= 0)
     9         kx     return 0;
     9         kx 
     9         kx   if (!bed->plt_sym_val)
     9         kx     return 0;
     9         kx 
     9         kx   relplt_name = bed->relplt_name;
     9         kx   if (relplt_name == NULL)
     9         kx     relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
     9         kx   relplt = bfd_get_section_by_name (abfd, relplt_name);
     9         kx   if (relplt == NULL)
     9         kx     return 0;
     9         kx 
     9         kx   hdr = &elf_section_data (relplt)->this_hdr;
     9         kx   if (hdr->sh_link != elf_dynsymtab (abfd)
     9         kx       || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
     9         kx     return 0;
     9         kx 
     9         kx   plt = bfd_get_section_by_name (abfd, ".plt");
     9         kx   if (plt == NULL)
     9         kx     return 0;
     9         kx 
     9         kx   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
     9         kx   if (! (*slurp_relocs) (abfd, relplt, dynsyms, true))
     9         kx     return -1;
     9         kx 
     9         kx   count = relplt->size / hdr->sh_entsize;
     9         kx   size = count * sizeof (asymbol);
     9         kx   p = relplt->relocation;
     9         kx   for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
     9         kx     {
     9         kx       size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
     9         kx       if (p->addend != 0)
     9         kx 	{
     9         kx #ifdef BFD64
     9         kx 	  size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
     9         kx #else
     9         kx 	  size += sizeof ("+0x") - 1 + 8;
     9         kx #endif
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   s = *ret = (asymbol *) bfd_malloc (size);
     9         kx   if (s == NULL)
     9         kx     return -1;
     9         kx 
     9         kx   names = (char *) (s + count);
     9         kx   p = relplt->relocation;
     9         kx   n = 0;
     9         kx   for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
     9         kx     {
     9         kx       size_t len;
     9         kx       bfd_vma addr;
     9         kx 
     9         kx       addr = bed->plt_sym_val (i, plt, p);
     9         kx       if (addr == (bfd_vma) -1)
     9         kx 	continue;
     9         kx 
     9         kx       *s = **p->sym_ptr_ptr;
     9         kx       /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
     9         kx 	 we are defining a symbol, ensure one of them is set.  */
     9         kx       if ((s->flags & BSF_LOCAL) == 0)
     9         kx 	s->flags |= BSF_GLOBAL;
     9         kx       s->flags |= BSF_SYNTHETIC;
     9         kx       s->section = plt;
     9         kx       s->value = addr - plt->vma;
     9         kx       s->name = names;
     9         kx       s->udata.p = NULL;
     9         kx       len = strlen ((*p->sym_ptr_ptr)->name);
     9         kx       memcpy (names, (*p->sym_ptr_ptr)->name, len);
     9         kx       names += len;
     9         kx       if (p->addend != 0)
     9         kx 	{
     9         kx 	  char buf[30], *a;
     9         kx 
     9         kx 	  memcpy (names, "+0x", sizeof ("+0x") - 1);
     9         kx 	  names += sizeof ("+0x") - 1;
     9         kx 	  bfd_sprintf_vma (abfd, buf, p->addend);
     9         kx 	  for (a = buf; *a == '0'; ++a)
     9         kx 	    ;
     9         kx 	  len = strlen (a);
     9         kx 	  memcpy (names, a, len);
     9         kx 	  names += len;
     9         kx 	}
     9         kx       memcpy (names, "@plt", sizeof ("@plt"));
     9         kx       names += sizeof ("@plt");
     9         kx       ++s, ++n;
     9         kx     }
     9         kx 
     9         kx   return n;
     9         kx }
     9         kx 
     9         kx /* It is only used by x86-64 so far.
     9         kx    ??? This repeats *COM* id of zero.  sec->id is supposed to be unique,
     9         kx    but current usage would allow all of _bfd_std_section to be zero.  */
     9         kx static const asymbol lcomm_sym
     9         kx   = GLOBAL_SYM_INIT ("LARGE_COMMON", &_bfd_elf_large_com_section);
     9         kx asection _bfd_elf_large_com_section
     9         kx   = BFD_FAKE_SECTION (_bfd_elf_large_com_section, &lcomm_sym,
     9         kx 		      "LARGE_COMMON", 0, SEC_IS_COMMON);
     9         kx 
     9         kx bool
     9         kx _bfd_elf_final_write_processing (bfd *abfd)
     9         kx {
     9         kx   Elf_Internal_Ehdr *i_ehdrp;	/* ELF file header, internal form.  */
     9         kx 
     9         kx   i_ehdrp = elf_elfheader (abfd);
     9         kx 
     9         kx   if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
     9         kx     i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
     9         kx 
     9         kx   /* Set the osabi field to ELFOSABI_GNU if the binary contains
     9         kx      SHF_GNU_MBIND or SHF_GNU_RETAIN sections or symbols of STT_GNU_IFUNC type
     9         kx      or STB_GNU_UNIQUE binding.  */
     9         kx   if (elf_tdata (abfd)->has_gnu_osabi != 0)
     9         kx     {
     9         kx       if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
     9         kx 	i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
     9         kx       else if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU
     9         kx 	       && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
     9         kx 	{
     9         kx 	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind)
     9         kx 	    _bfd_error_handler (_("GNU_MBIND section is supported only by GNU "
     9         kx 				  "and FreeBSD targets"));
     9         kx 	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_ifunc)
     9         kx 	    _bfd_error_handler (_("symbol type STT_GNU_IFUNC is supported "
     9         kx 				  "only by GNU and FreeBSD targets"));
     9         kx 	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique)
     9         kx 	    _bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is supported "
     9         kx 				  "only by GNU and FreeBSD targets"));
     9         kx 	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_retain)
     9         kx 	    _bfd_error_handler (_("GNU_RETAIN section is supported "
     9         kx 				  "only by GNU and FreeBSD targets"));
     9         kx 	  bfd_set_error (bfd_error_sorry);
     9         kx 	  return false;
     9         kx 	}
     9         kx     }
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx 
     9         kx /* Return TRUE for ELF symbol types that represent functions.
     9         kx    This is the default version of this function, which is sufficient for
     9         kx    most targets.  It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_is_function_type (unsigned int type)
     9         kx {
     9         kx   return (type == STT_FUNC
     9         kx 	  || type == STT_GNU_IFUNC);
     9         kx }
     9         kx 
     9         kx /* If the ELF symbol SYM might be a function in SEC, return the
     9         kx    function size and set *CODE_OFF to the function's entry point,
     9         kx    otherwise return zero.  */
     9         kx 
     9         kx bfd_size_type
     9         kx _bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
     9         kx 			     bfd_vma *code_off)
     9         kx {
     9         kx   bfd_size_type size;
     9         kx   elf_symbol_type * elf_sym = (elf_symbol_type *) sym;
     9         kx 
     9         kx   if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
     9         kx 		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
     9         kx       || sym->section != sec)
     9         kx     return 0;
     9         kx 
     9         kx   size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;
     9         kx 
     9         kx   /* In theory we should check that the symbol's type satisfies
     9         kx      _bfd_elf_is_function_type(), but there are some function-like
     9         kx      symbols which would fail this test.  (eg _start).  Instead
     9         kx      we check for hidden, local, notype symbols with zero size.
     9         kx      This type of symbol is generated by the annobin plugin for gcc
     9         kx      and clang, and should not be considered to be a function symbol.  */
     9         kx   if (size == 0
     9         kx       && ((sym->flags & (BSF_SYNTHETIC | BSF_LOCAL)) == BSF_LOCAL)
     9         kx       && ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info) == STT_NOTYPE
     9         kx       && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
     9         kx     return 0;
     9         kx 
     9         kx   *code_off = sym->value;
     9         kx   /* Do not return 0 for the function's size.  */
     9         kx   return size ? size : 1;
     9         kx }
     9         kx 
     9         kx /* Set to non-zero to enable some debug messages.  */
     9         kx #define DEBUG_SECONDARY_RELOCS	 0
     9         kx 
     9         kx /* An internal-to-the-bfd-library only section type
     9         kx    used to indicate a cached secondary reloc section.  */
     9         kx #define SHT_SECONDARY_RELOC	 (SHT_LOOS + SHT_RELA)
     9         kx 
     9         kx /* Create a BFD section to hold a secondary reloc section.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_init_secondary_reloc_section (bfd * abfd,
     9         kx 				       Elf_Internal_Shdr *hdr,
     9         kx 				       const char * name,
     9         kx 				       unsigned int shindex)
     9         kx {
     9         kx   /* We only support RELA secondary relocs.  */
     9         kx   if (hdr->sh_type != SHT_RELA)
     9         kx     return false;
     9         kx 
     9         kx #if DEBUG_SECONDARY_RELOCS
     9         kx   fprintf (stderr, "secondary reloc section %s encountered\n", name);
     9         kx #endif
     9         kx   hdr->sh_type = SHT_SECONDARY_RELOC;
     9         kx   return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
     9         kx }
     9         kx 
     9         kx /* Read in any secondary relocs associated with SEC.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
     9         kx 					asection *  sec,
     9         kx 					asymbol **  symbols,
     9         kx 					bool dynamic)
     9         kx {
     9         kx   const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
     9         kx   asection * relsec;
     9         kx   bool result = true;
     9         kx   bfd_vma (*r_sym) (bfd_vma);
     9         kx   ufile_ptr filesize;
     9         kx 
     9         kx #if BFD_DEFAULT_TARGET_SIZE > 32
     9         kx   if (bfd_arch_bits_per_address (abfd) != 32)
     9         kx     r_sym = elf64_r_sym;
     9         kx   else
     9         kx #endif
     9         kx     r_sym = elf32_r_sym;
     9         kx 
     9         kx   if (!elf_section_data (sec)->has_secondary_relocs)
     9         kx     return true;
     9         kx 
     9         kx   /* Discover if there are any secondary reloc sections
     9         kx      associated with SEC.  */
     9         kx   filesize = bfd_get_file_size (abfd);
     9         kx   for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
     9         kx     {
     9         kx       Elf_Internal_Shdr * hdr = & elf_section_data (relsec)->this_hdr;
     9         kx 
     9         kx       if (hdr->sh_type == SHT_SECONDARY_RELOC
     9         kx 	  && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx
     9         kx 	  && (hdr->sh_entsize == ebd->s->sizeof_rel
     9         kx 	      || hdr->sh_entsize == ebd->s->sizeof_rela))
     9         kx 	{
     9         kx 	  bfd_byte * native_relocs;
     9         kx 	  bfd_byte * native_reloc;
     9         kx 	  arelent * internal_relocs;
     9         kx 	  arelent * internal_reloc;
     9         kx 	  size_t i;
     9         kx 	  unsigned int entsize;
     9         kx 	  unsigned int symcount;
     9         kx 	  bfd_size_type reloc_count;
     9         kx 	  size_t amt;
     9         kx 
     9         kx 	  if (ebd->elf_info_to_howto == NULL)
     9         kx 	    return false;
     9         kx 
     9         kx #if DEBUG_SECONDARY_RELOCS
     9         kx 	  fprintf (stderr, "read secondary relocs for %s from %s\n",
     9         kx 		   sec->name, relsec->name);
     9         kx #endif
     9         kx 	  entsize = hdr->sh_entsize;
     9         kx 
     9         kx 	  if (filesize != 0
     9         kx 	      && ((ufile_ptr) hdr->sh_offset > filesize
     9         kx 		  || hdr->sh_size > filesize - hdr->sh_offset))
     9         kx 	    {
     9         kx 	      bfd_set_error (bfd_error_file_truncated);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  native_relocs = bfd_malloc (hdr->sh_size);
     9         kx 	  if (native_relocs == NULL)
     9         kx 	    {
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  reloc_count = NUM_SHDR_ENTRIES (hdr);
     9         kx 	  if (_bfd_mul_overflow (reloc_count, sizeof (arelent), & amt))
     9         kx 	    {
     9         kx 	      free (native_relocs);
     9         kx 	      bfd_set_error (bfd_error_file_too_big);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  internal_relocs = (arelent *) bfd_alloc (abfd, amt);
     9         kx 	  if (internal_relocs == NULL)
     9         kx 	    {
     9         kx 	      free (native_relocs);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
     9         kx 	      || (bfd_bread (native_relocs, hdr->sh_size, abfd)
     9         kx 		  != hdr->sh_size))
     9         kx 	    {
     9         kx 	      free (native_relocs);
     9         kx 	      /* The internal_relocs will be freed when
     9         kx 		 the memory for the bfd is released.  */
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  if (dynamic)
     9         kx 	    symcount = bfd_get_dynamic_symcount (abfd);
     9         kx 	  else
     9         kx 	    symcount = bfd_get_symcount (abfd);
     9         kx 
     9         kx 	  for (i = 0, internal_reloc = internal_relocs,
     9         kx 		 native_reloc = native_relocs;
     9         kx 	       i < reloc_count;
     9         kx 	       i++, internal_reloc++, native_reloc += entsize)
     9         kx 	    {
     9         kx 	      bool res;
     9         kx 	      Elf_Internal_Rela rela;
     9         kx 
     9         kx 	      if (entsize == ebd->s->sizeof_rel)
     9         kx 		ebd->s->swap_reloc_in (abfd, native_reloc, & rela);
     9         kx 	      else /* entsize == ebd->s->sizeof_rela */
     9         kx 		ebd->s->swap_reloca_in (abfd, native_reloc, & rela);
     9         kx 
     9         kx 	      /* The address of an ELF reloc is section relative for an object
     9         kx 		 file, and absolute for an executable file or shared library.
     9         kx 		 The address of a normal BFD reloc is always section relative,
     9         kx 		 and the address of a dynamic reloc is absolute..  */
     9         kx 	      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
     9         kx 		internal_reloc->address = rela.r_offset;
     9         kx 	      else
     9         kx 		internal_reloc->address = rela.r_offset - sec->vma;
     9         kx 
     9         kx 	      if (r_sym (rela.r_info) == STN_UNDEF)
     9         kx 		{
     9         kx 		  /* FIXME: This and the error case below mean that we
     9         kx 		     have a symbol on relocs that is not elf_symbol_type.  */
     9         kx 		  internal_reloc->sym_ptr_ptr =
     9         kx 		    bfd_abs_section_ptr->symbol_ptr_ptr;
     9         kx 		}
     9         kx 	      else if (r_sym (rela.r_info) > symcount)
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB(%pA): relocation %zu has invalid symbol index %lu"),
     9         kx 		     abfd, sec, i, (long) r_sym (rela.r_info));
     9         kx 		  bfd_set_error (bfd_error_bad_value);
     9         kx 		  internal_reloc->sym_ptr_ptr =
     9         kx 		    bfd_abs_section_ptr->symbol_ptr_ptr;
     9         kx 		  result = false;
     9         kx 		}
     9         kx 	      else
     9         kx 		{
     9         kx 		  asymbol **ps;
     9         kx 
     9         kx 		  ps = symbols + r_sym (rela.r_info) - 1;
     9         kx 		  internal_reloc->sym_ptr_ptr = ps;
     9         kx 		  /* Make sure that this symbol is not removed by strip.  */
     9         kx 		  (*ps)->flags |= BSF_KEEP;
     9         kx 		}
     9         kx 
     9         kx 	      internal_reloc->addend = rela.r_addend;
     9         kx 
     9         kx 	      res = ebd->elf_info_to_howto (abfd, internal_reloc, & rela);
     9         kx 	      if (! res || internal_reloc->howto == NULL)
     9         kx 		{
     9         kx #if DEBUG_SECONDARY_RELOCS
     9         kx 		  fprintf (stderr,
     9         kx 			   "there is no howto associated with reloc %lx\n",
     9         kx 			   rela.r_info);
     9         kx #endif
     9         kx 		  result = false;
     9         kx 		}
     9         kx 	    }
     9         kx 
     9         kx 	  free (native_relocs);
     9         kx 	  /* Store the internal relocs.  */
     9         kx 	  elf_section_data (relsec)->sec_info = internal_relocs;
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return result;
     9         kx }
     9         kx 
     9         kx /* Set the ELF section header fields of an output secondary reloc section.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
     9         kx 				      bfd *obfd ATTRIBUTE_UNUSED,
     9         kx 				      const Elf_Internal_Shdr *isection,
     9         kx 				      Elf_Internal_Shdr *osection)
     9         kx {
     9         kx   asection * isec;
     9         kx   asection * osec;
     9         kx   struct bfd_elf_section_data * esd;
     9         kx 
     9         kx   if (isection == NULL)
     9         kx     return false;
     9         kx 
     9         kx   if (isection->sh_type != SHT_SECONDARY_RELOC)
     9         kx     return true;
     9         kx 
     9         kx   isec = isection->bfd_section;
     9         kx   if (isec == NULL)
     9         kx     return false;
     9         kx 
     9         kx   osec = osection->bfd_section;
     9         kx   if (osec == NULL)
     9         kx     return false;
     9         kx 
     9         kx   esd = elf_section_data (osec);
     9         kx   BFD_ASSERT (esd->sec_info == NULL);
     9         kx   esd->sec_info = elf_section_data (isec)->sec_info;
     9         kx   osection->sh_type = SHT_RELA;
     9         kx   osection->sh_link = elf_onesymtab (obfd);
     9         kx   if (osection->sh_link == 0)
     9         kx     {
     9         kx       /* There is no symbol table - we are hosed...  */
     9         kx       _bfd_error_handler
     9         kx 	/* xgettext:c-format */
     9         kx 	(_("%pB(%pA): link section cannot be set"
     9         kx 	   " because the output file does not have a symbol table"),
     9         kx 	obfd, osec);
     9         kx       bfd_set_error (bfd_error_bad_value);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   /* Find the output section that corresponds to the isection's
     9         kx      sh_info link.  */
     9         kx   if (isection->sh_info == 0
     9         kx       || isection->sh_info >= elf_numsections (ibfd))
     9         kx     {
     9         kx       _bfd_error_handler
     9         kx 	/* xgettext:c-format */
     9         kx 	(_("%pB(%pA): info section index is invalid"),
     9         kx 	obfd, osec);
     9         kx       bfd_set_error (bfd_error_bad_value);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   isection = elf_elfsections (ibfd)[isection->sh_info];
     9         kx 
     9         kx   if (isection == NULL
     9         kx       || isection->bfd_section == NULL
     9         kx       || isection->bfd_section->output_section == NULL)
     9         kx     {
     9         kx       _bfd_error_handler
     9         kx 	/* xgettext:c-format */
     9         kx 	(_("%pB(%pA): info section index cannot be set"
     9         kx 	   " because the section is not in the output"),
     9         kx 	obfd, osec);
     9         kx       bfd_set_error (bfd_error_bad_value);
     9         kx       return false;
     9         kx     }
     9         kx 
     9         kx   esd = elf_section_data (isection->bfd_section->output_section);
     9         kx   BFD_ASSERT (esd != NULL);
     9         kx   osection->sh_info = esd->this_idx;
     9         kx   esd->has_secondary_relocs = true;
     9         kx #if DEBUG_SECONDARY_RELOCS
     9         kx   fprintf (stderr, "update header of %s, sh_link = %u, sh_info = %u\n",
     9         kx 	   osec->name, osection->sh_link, osection->sh_info);
     9         kx   fprintf (stderr, "mark section %s as having secondary relocs\n",
     9         kx 	   bfd_section_name (isection->bfd_section->output_section));
     9         kx #endif
     9         kx 
     9         kx   return true;
     9         kx }
     9         kx 
     9         kx /* Write out a secondary reloc section.
     9         kx 
     9         kx    FIXME: Currently this function can result in a serious performance penalty
     9         kx    for files with secondary relocs and lots of sections.  The proper way to
     9         kx    fix this is for _bfd_elf_copy_special_section_fields() to chain secondary
     9         kx    relocs together and then to have this function just walk that chain.  */
     9         kx 
     9         kx bool
     9         kx _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
     9         kx {
     9         kx   const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
     9         kx   bfd_vma addr_offset;
     9         kx   asection * relsec;
     9         kx   bfd_vma (*r_info) (bfd_vma, bfd_vma);
     9         kx   bool result = true;
     9         kx 
     9         kx   if (sec == NULL)
     9         kx     return false;
     9         kx 
     9         kx #if BFD_DEFAULT_TARGET_SIZE > 32
     9         kx   if (bfd_arch_bits_per_address (abfd) != 32)
     9         kx     r_info = elf64_r_info;
     9         kx   else
     9         kx #endif
     9         kx     r_info = elf32_r_info;
     9         kx 
     9         kx   /* The address of an ELF reloc is section relative for an object
     9         kx      file, and absolute for an executable file or shared library.
     9         kx      The address of a BFD reloc is always section relative.  */
     9         kx   addr_offset = 0;
     9         kx   if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
     9         kx     addr_offset = sec->vma;
     9         kx 
     9         kx   /* Discover if there are any secondary reloc sections
     9         kx      associated with SEC.  */
     9         kx   for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
     9         kx     {
     9         kx       const struct bfd_elf_section_data * const esd = elf_section_data (relsec);
     9         kx       Elf_Internal_Shdr * const hdr = (Elf_Internal_Shdr *) & esd->this_hdr;
     9         kx 
     9         kx       if (hdr->sh_type == SHT_RELA
     9         kx 	  && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx)
     9         kx 	{
     9         kx 	  asymbol *    last_sym;
     9         kx 	  int          last_sym_idx;
     9         kx 	  size_t       reloc_count;
     9         kx 	  size_t       idx;
     9         kx 	  bfd_size_type entsize;
     9         kx 	  arelent *    src_irel;
     9         kx 	  bfd_byte *   dst_rela;
     9         kx 
     9         kx 	  if (hdr->contents != NULL)
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB(%pA): error: secondary reloc section processed twice"),
     9         kx 		 abfd, relsec);
     9         kx 	      bfd_set_error (bfd_error_bad_value);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  entsize = hdr->sh_entsize;
     9         kx 	  if (entsize == 0)
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB(%pA): error: secondary reloc section"
     9         kx 		   " has zero sized entries"),
     9         kx 		 abfd, relsec);
     9         kx 	      bfd_set_error (bfd_error_bad_value);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 	  else if (entsize != ebd->s->sizeof_rel
     9         kx 		   && entsize != ebd->s->sizeof_rela)
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB(%pA): error: secondary reloc section"
     9         kx 		   " has non-standard sized entries"),
     9         kx 		 abfd, relsec);
     9         kx 	      bfd_set_error (bfd_error_bad_value);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  reloc_count = hdr->sh_size / entsize;
     9         kx 	  hdr->sh_size = entsize * reloc_count;
     9         kx 	  if (reloc_count == 0)
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB(%pA): error: secondary reloc section is empty!"),
     9         kx 		 abfd, relsec);
     9         kx 	      bfd_set_error (bfd_error_bad_value);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  hdr->contents = bfd_alloc (abfd, hdr->sh_size);
     9         kx 	  if (hdr->contents == NULL)
     9         kx 	    continue;
     9         kx 
     9         kx #if DEBUG_SECONDARY_RELOCS
     9         kx 	  fprintf (stderr, "write %u secondary relocs for %s from %s\n",
     9         kx 		   reloc_count, sec->name, relsec->name);
     9         kx #endif
     9         kx 	  last_sym = NULL;
     9         kx 	  last_sym_idx = 0;
     9         kx 	  dst_rela = hdr->contents;
     9         kx 	  src_irel = (arelent *) esd->sec_info;
     9         kx 	  if (src_irel == NULL)
     9         kx 	    {
     9         kx 	      _bfd_error_handler
     9         kx 		/* xgettext:c-format */
     9         kx 		(_("%pB(%pA): error: internal relocs missing"
     9         kx 		   " for secondary reloc section"),
     9         kx 		 abfd, relsec);
     9         kx 	      bfd_set_error (bfd_error_bad_value);
     9         kx 	      result = false;
     9         kx 	      continue;
     9         kx 	    }
     9         kx 
     9         kx 	  for (idx = 0; idx < reloc_count; idx++, dst_rela += entsize)
     9         kx 	    {
     9         kx 	      Elf_Internal_Rela src_rela;
     9         kx 	      arelent *ptr;
     9         kx 	      asymbol *sym;
     9         kx 	      int n;
     9         kx 
     9         kx 	      ptr = src_irel + idx;
     9         kx 	      if (ptr == NULL)
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB(%pA): error: reloc table entry %zu is empty"),
     9         kx 		     abfd, relsec, idx);
     9         kx 		  bfd_set_error (bfd_error_bad_value);
     9         kx 		  result = false;
     9         kx 		  break;
     9         kx 		}
     9         kx 
     9         kx 	      if (ptr->sym_ptr_ptr == NULL)
     9         kx 		{
     9         kx 		  /* FIXME: Is this an error ? */
     9         kx 		  n = 0;
     9         kx 		}
     9         kx 	      else
     9         kx 		{
     9         kx 		  sym = *ptr->sym_ptr_ptr;
     9         kx 
     9         kx 		  if (sym == last_sym)
     9         kx 		    n = last_sym_idx;
     9         kx 		  else
     9         kx 		    {
     9         kx 		      n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
     9         kx 		      if (n < 0)
     9         kx 			{
     9         kx 			  _bfd_error_handler
     9         kx 			    /* xgettext:c-format */
     9         kx 			    (_("%pB(%pA): error: secondary reloc %zu"
     9         kx 			       " references a missing symbol"),
     9         kx 			     abfd, relsec, idx);
     9         kx 			  bfd_set_error (bfd_error_bad_value);
     9         kx 			  result = false;
     9         kx 			  n = 0;
     9         kx 			}
     9         kx 
     9         kx 		      last_sym = sym;
     9         kx 		      last_sym_idx = n;
     9         kx 		    }
     9         kx 
     9         kx 		  if (sym->the_bfd != NULL
     9         kx 		      && sym->the_bfd->xvec != abfd->xvec
     9         kx 		      && ! _bfd_elf_validate_reloc (abfd, ptr))
     9         kx 		    {
     9         kx 		      _bfd_error_handler
     9         kx 			/* xgettext:c-format */
     9         kx 			(_("%pB(%pA): error: secondary reloc %zu"
     9         kx 			   " references a deleted symbol"),
     9         kx 			 abfd, relsec, idx);
     9         kx 		      bfd_set_error (bfd_error_bad_value);
     9         kx 		      result = false;
     9         kx 		      n = 0;
     9         kx 		    }
     9         kx 		}
     9         kx 
     9         kx 	      src_rela.r_offset = ptr->address + addr_offset;
     9         kx 	      if (ptr->howto == NULL)
     9         kx 		{
     9         kx 		  _bfd_error_handler
     9         kx 		    /* xgettext:c-format */
     9         kx 		    (_("%pB(%pA): error: secondary reloc %zu"
     9         kx 		       " is of an unknown type"),
     9         kx 		     abfd, relsec, idx);
     9         kx 		  bfd_set_error (bfd_error_bad_value);
     9         kx 		  result = false;
     9         kx 		  src_rela.r_info = r_info (0, 0);
     9         kx 		}
     9         kx 	      else
     9         kx 		src_rela.r_info = r_info (n, ptr->howto->type);
     9         kx 	      src_rela.r_addend = ptr->addend;
     9         kx 
     9         kx 	      if (entsize == ebd->s->sizeof_rel)
     9         kx 		ebd->s->swap_reloc_out (abfd, &src_rela, dst_rela);
     9         kx 	      else /* entsize == ebd->s->sizeof_rela */
     9         kx 		ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
     9         kx 	    }
     9         kx 	}
     9         kx     }
     9         kx 
     9         kx   return result;
     9         kx }