/* ELF executable support for BFD.

   Copyright (C) 1993-2025 Free Software Foundation, Inc.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */


/*
SECTION
	ELF backends

	BFD support for ELF formats is being worked on.
	Currently, the best supported back ends are for sparc and i386
	(running svr4 or Solaris 2).

	Documentation of the internals of the support code still needs
	to be written.  The code is changing quickly enough that we
	haven't bothered yet.  */

/* For sparc64-cross-sparc32.  */
#define _SYSCALL32
#include "sysdep.h"
#include <limits.h>
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"
#include "libiberty.h"
#include "safe-ctype.h"
#include "elf-linux-core.h"

#ifdef CORE_HEADER
#include CORE_HEADER
#endif

/* Utility macro to make testing for string equality easier to read.  */
#ifndef streq
#define streq(A,B) (strcmp ((A), (B)) == 0)
#endif

/* Core note names.  */
#define NOTE_NAME_CORE     "CORE"
#define NOTE_NAME_FREEBSD  "FreeBSD"
#define NOTE_NAME_GDB      "GDB"
#define NOTE_NAME_LINUX    "LINUX"

/* Names of a pseudo-section which represent core notes.  */
#define NOTE_PSEUDO_SECTION_AARCH_FPMR		".reg-aarch-fpmr"
#define NOTE_PSEUDO_SECTION_AARCH_GCS		".reg-aarch-gcs"
#define NOTE_PSEUDO_SECTION_AARCH_HW_BREAK	".reg-aarch-hw-break"
#define NOTE_PSEUDO_SECTION_AARCH_HW_WATCH	".reg-aarch-hw-watch"
#define NOTE_PSEUDO_SECTION_AARCH_MTE		".reg-aarch-mte"
#define NOTE_PSEUDO_SECTION_AARCH_PAUTH		".reg-aarch-pauth"
#define NOTE_PSEUDO_SECTION_AARCH_SSVE		".reg-aarch-ssve"
#define NOTE_PSEUDO_SECTION_AARCH_SVE		".reg-aarch-sve"
#define NOTE_PSEUDO_SECTION_AARCH_TLS		".reg-aarch-tls"
#define NOTE_PSEUDO_SECTION_AARCH_ZA		".reg-aarch-za"
#define NOTE_PSEUDO_SECTION_AARCH_ZT		".reg-aarch-zt"
#define NOTE_PSEUDO_SECTION_ARC_V2		".reg-arc-v2"
#define NOTE_PSEUDO_SECTION_ARM_VFP		".reg-arm-vfp"
#define NOTE_PSEUDO_SECTION_I386_TLS	 	".reg-i386-tls"
#define NOTE_PSEUDO_SECTION_LOONGARCH_CPUCFG	".reg-loongarch-cpucfg"
#define NOTE_PSEUDO_SECTION_LOONGARCH_LASX	".reg-loongarch-lasx"
#define NOTE_PSEUDO_SECTION_LOONGARCH_LBT	".reg-loongarch-lbt"
#define NOTE_PSEUDO_SECTION_LOONGARCH_LSX	".reg-loongarch-lsx"
#define NOTE_PSEUDO_SECTION_PPC_DSCR		".reg-ppc-dscr"
#define NOTE_PSEUDO_SECTION_PPC_EBB		".reg-ppc-ebb"
#define NOTE_PSEUDO_SECTION_PPC_PMU		".reg-ppc-pmu"
#define NOTE_PSEUDO_SECTION_PPC_PPR		".reg-ppc-ppr"
#define NOTE_PSEUDO_SECTION_PPC_TAR		".reg-ppc-tar"
#define NOTE_PSEUDO_SECTION_PPC_TM_CDSCR	".reg-ppc-tm-cdscr"
#define NOTE_PSEUDO_SECTION_PPC_TM_CFPR		".reg-ppc-tm-cfpr"
#define NOTE_PSEUDO_SECTION_PPC_TM_CGPR		".reg-ppc-tm-cgpr"
#define NOTE_PSEUDO_SECTION_PPC_TM_CPPR		".reg-ppc-tm-cppr"
#define NOTE_PSEUDO_SECTION_PPC_TM_CTAR		".reg-ppc-tm-ctar"
#define NOTE_PSEUDO_SECTION_PPC_TM_CVMX		".reg-ppc-tm-cvmx"
#define NOTE_PSEUDO_SECTION_PPC_TM_CVSX		".reg-ppc-tm-cvsx"
#define NOTE_PSEUDO_SECTION_PPC_TM_SPR		".reg-ppc-tm-spr"
#define NOTE_PSEUDO_SECTION_PPC_VSX		".reg-ppc-vsx"
#define NOTE_PSEUDO_SECTION_PPC_VMX		".reg-ppc-vmx"
#define NOTE_PSEUDO_SECTION_REG		 	".reg"
#define NOTE_PSEUDO_SECTION_REG2	 	".reg2"
#define NOTE_PSEUDO_SECTION_RISCV_CSR		".reg-riscv-csr"
#define NOTE_PSEUDO_SECTION_S390_CTRS		".reg-s390-ctrs"
#define NOTE_PSEUDO_SECTION_S390_GS_BC		".reg-s390-gs-bc"
#define NOTE_PSEUDO_SECTION_S390_GS_CB		".reg-s390-gs-cb"
#define NOTE_PSEUDO_SECTION_S390_HIGH_GPRS	".reg-s390-high-gprs"
#define NOTE_PSEUDO_SECTION_S390_LAST_BREAK	".reg-s390-last-break"
#define NOTE_PSEUDO_SECTION_S390_PREFIX		".reg-s390-prefix"
#define NOTE_PSEUDO_SECTION_S390_SYSTEM_CALL	".reg-s390-system-call"
#define NOTE_PSEUDO_SECTION_S390_TDB		".reg-s390-tdb"
#define NOTE_PSEUDO_SECTION_S390_TIMER		".reg-s390-timer"
#define NOTE_PSEUDO_SECTION_S390_TODCMP		".reg-s390-todcmp"
#define NOTE_PSEUDO_SECTION_S390_TODPREG	".reg-s390-todpreg"
#define NOTE_PSEUDO_SECTION_S390_VXRS_HIGH	".reg-s390-vxrs-high"
#define NOTE_PSEUDO_SECTION_S390_VXRS_LOW	".reg-s390-vxrs-low"
#define NOTE_PSEUDO_SECTION_SSP		 	".reg-ssp"
#define NOTE_PSEUDO_SECTION_TDESC		".gdb-tdesc"
#define NOTE_PSEUDO_SECTION_X86_SEGBASES 	".reg-x86-segbases"
#define NOTE_PSEUDO_SECTION_XFP          	".reg-xfp"
#define NOTE_PSEUDO_SECTION_XSTATE       	".reg-xstate"

static int elf_sort_sections (const void *, const void *);
static bool assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
static bool swap_out_syms (bfd *, struct elf_strtab_hash **, int,
			   struct bfd_link_info *);
static bool elf_parse_notes (bfd *abfd, char *buf, size_t size,
			     file_ptr offset, size_t align);

/* Swap version information in and out.  The version information is
   currently size independent.  If that ever changes, this code will
   need to move into elfcode.h.  */

/* Swap in a Verdef structure.  */

void
_bfd_elf_swap_verdef_in (bfd *abfd,
			 const Elf_External_Verdef *src,
			 Elf_Internal_Verdef *dst)
{
  dst->vd_version = H_GET_16 (abfd, src->vd_version);
  dst->vd_flags   = H_GET_16 (abfd, src->vd_flags);
  dst->vd_ndx     = H_GET_16 (abfd, src->vd_ndx);
  dst->vd_cnt     = H_GET_16 (abfd, src->vd_cnt);
  dst->vd_hash    = H_GET_32 (abfd, src->vd_hash);
  dst->vd_aux     = H_GET_32 (abfd, src->vd_aux);
  dst->vd_next    = H_GET_32 (abfd, src->vd_next);
}

/* Swap out a Verdef structure.  */

void
_bfd_elf_swap_verdef_out (bfd *abfd,
			  const Elf_Internal_Verdef *src,
			  Elf_External_Verdef *dst)
{
  H_PUT_16 (abfd, src->vd_version, dst->vd_version);
  H_PUT_16 (abfd, src->vd_flags, dst->vd_flags);
  H_PUT_16 (abfd, src->vd_ndx, dst->vd_ndx);
  H_PUT_16 (abfd, src->vd_cnt, dst->vd_cnt);
  H_PUT_32 (abfd, src->vd_hash, dst->vd_hash);
  H_PUT_32 (abfd, src->vd_aux, dst->vd_aux);
  H_PUT_32 (abfd, src->vd_next, dst->vd_next);
}

/* Swap in a Verdaux structure.  */

void
_bfd_elf_swap_verdaux_in (bfd *abfd,
			  const Elf_External_Verdaux *src,
			  Elf_Internal_Verdaux *dst)
{
  dst->vda_name = H_GET_32 (abfd, src->vda_name);
  dst->vda_next = H_GET_32 (abfd, src->vda_next);
}

/* Swap out a Verdaux structure.  */

void
_bfd_elf_swap_verdaux_out (bfd *abfd,
			   const Elf_Internal_Verdaux *src,
			   Elf_External_Verdaux *dst)
{
  H_PUT_32 (abfd, src->vda_name, dst->vda_name);
  H_PUT_32 (abfd, src->vda_next, dst->vda_next);
}

/* Swap in a Verneed structure.  */

void
_bfd_elf_swap_verneed_in (bfd *abfd,
			  const Elf_External_Verneed *src,
			  Elf_Internal_Verneed *dst)
{
  dst->vn_version = H_GET_16 (abfd, src->vn_version);
  dst->vn_cnt     = H_GET_16 (abfd, src->vn_cnt);
  dst->vn_file    = H_GET_32 (abfd, src->vn_file);
  dst->vn_aux     = H_GET_32 (abfd, src->vn_aux);
  dst->vn_next    = H_GET_32 (abfd, src->vn_next);
}

/* Swap out a Verneed structure.  */

void
_bfd_elf_swap_verneed_out (bfd *abfd,
			   const Elf_Internal_Verneed *src,
			   Elf_External_Verneed *dst)
{
  H_PUT_16 (abfd, src->vn_version, dst->vn_version);
  H_PUT_16 (abfd, src->vn_cnt, dst->vn_cnt);
  H_PUT_32 (abfd, src->vn_file, dst->vn_file);
  H_PUT_32 (abfd, src->vn_aux, dst->vn_aux);
  H_PUT_32 (abfd, src->vn_next, dst->vn_next);
}

/* Swap in a Vernaux structure.  */

void
_bfd_elf_swap_vernaux_in (bfd *abfd,
			  const Elf_External_Vernaux *src,
			  Elf_Internal_Vernaux *dst)
{
  dst->vna_hash  = H_GET_32 (abfd, src->vna_hash);
  dst->vna_flags = H_GET_16 (abfd, src->vna_flags);
  dst->vna_other = H_GET_16 (abfd, src->vna_other);
  dst->vna_name  = H_GET_32 (abfd, src->vna_name);
  dst->vna_next  = H_GET_32 (abfd, src->vna_next);
}

/* Swap out a Vernaux structure.  */

void
_bfd_elf_swap_vernaux_out (bfd *abfd,
			   const Elf_Internal_Vernaux *src,
			   Elf_External_Vernaux *dst)
{
  H_PUT_32 (abfd, src->vna_hash, dst->vna_hash);
  H_PUT_16 (abfd, src->vna_flags, dst->vna_flags);
  H_PUT_16 (abfd, src->vna_other, dst->vna_other);
  H_PUT_32 (abfd, src->vna_name, dst->vna_name);
  H_PUT_32 (abfd, src->vna_next, dst->vna_next);
}

/* Swap in a Versym structure.  */

void
_bfd_elf_swap_versym_in (bfd *abfd,
			 const Elf_External_Versym *src,
			 Elf_Internal_Versym *dst)
{
  dst->vs_vers = H_GET_16 (abfd, src->vs_vers);
}

/* Swap out a Versym structure.  */

void
_bfd_elf_swap_versym_out (bfd *abfd,
			  const Elf_Internal_Versym *src,
			  Elf_External_Versym *dst)
{
  H_PUT_16 (abfd, src->vs_vers, dst->vs_vers);
}

/* Standard ELF hash function.  Do not change this function; you will
   cause invalid hash tables to be generated.  */

unsigned long
bfd_elf_hash (const char *namearg)
{
  uint32_t h = 0;

  for (const unsigned char *name = (const unsigned char *) namearg;
       *name; name++)
    {
      h = (h << 4) + *name;
      h ^= (h >> 24) & 0xf0;
    }
  return h & 0x0fffffff;
}

/* DT_GNU_HASH hash function.  Do not change this function; you will
   cause invalid hash tables to be generated.  */

unsigned long
bfd_elf_gnu_hash (const char *namearg)
{
  uint32_t h = 5381;

  for (const unsigned char *name = (const unsigned char *) namearg;
       *name; name++)
    h = (h << 5) + h + *name;
  return h;
}

/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
   the object_id field of an elf_obj_tdata field set.  */
bool
bfd_elf_allocate_object (bfd *abfd,
			 size_t object_size)
{
  BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
  abfd->tdata.any = bfd_zalloc (abfd, object_size);
  if (abfd->tdata.any == NULL)
    return false;

  elf_object_id (abfd) = get_elf_backend_data (abfd)->target_id;
  if (abfd->direction != read_direction)
    {
      struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
      if (o == NULL)
	return false;
      elf_tdata (abfd)->o = o;
      elf_program_header_size (abfd) = (bfd_size_type) -1;
    }
  return true;
}


bool
bfd_elf_make_object (bfd *abfd)
{
  return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata));
}

bool
bfd_elf_mkcorefile (bfd *abfd)
{
  /* I think this can be done just like an object file.  */
  if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
    return false;
  elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
  return elf_tdata (abfd)->core != NULL;
}

char *
bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
{
  Elf_Internal_Shdr **i_shdrp;
  bfd_byte *shstrtab = NULL;
  file_ptr offset;
  bfd_size_type shstrtabsize;

  i_shdrp = elf_elfsections (abfd);
  if (i_shdrp == 0
      || shindex >= elf_numsections (abfd)
      || i_shdrp[shindex] == 0)
    return NULL;

  shstrtab = i_shdrp[shindex]->contents;
  if (shstrtab == NULL)
    {
      /* No cached one, attempt to read, and cache what we read.  */
      offset = i_shdrp[shindex]->sh_offset;
      shstrtabsize = i_shdrp[shindex]->sh_size;

      if (shstrtabsize == 0
	  || bfd_seek (abfd, offset, SEEK_SET) != 0
	  || (shstrtab = _bfd_mmap_persistent (abfd, shstrtabsize)) == NULL)
	{
	  /* Once we've failed to read it, make sure we don't keep
	     trying.  Otherwise, we'll keep allocating space for
	     the string table over and over.  */
	  i_shdrp[shindex]->sh_size = 0;
	}
      else if (shstrtab[shstrtabsize - 1] != 0)
	{
	  /* It is an error if a string table isn't terminated.  */
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: string table [%u] is corrupt"), abfd, shindex);
	  shstrtab[shstrtabsize - 1] = 0;
	}
      i_shdrp[shindex]->contents = shstrtab;
    }
  return (char *) shstrtab;
}

char *
bfd_elf_string_from_elf_section (bfd *abfd,
				 unsigned int shindex,
				 unsigned int strindex)
{
  Elf_Internal_Shdr *hdr;

  if (strindex == 0)
    return "";

  if (elf_elfsections (abfd) == NULL || shindex >= elf_numsections (abfd))
    return NULL;

  hdr = elf_elfsections (abfd)[shindex];

  if (hdr->contents == NULL)
    {
      if (hdr->sh_type != SHT_STRTAB && hdr->sh_type < SHT_LOOS)
	{
	  /* PR 17512: file: f057ec89.  */
	  /* xgettext:c-format */
	  _bfd_error_handler (_("%pB: attempt to load strings from"
				" a non-string section (number %d)"),
			      abfd, shindex);
	  return NULL;
	}

      if (bfd_elf_get_str_section (abfd, shindex) == NULL)
	return NULL;
    }
  else
    {
      /* PR 24273: The string section's contents may have already
	 been loaded elsewhere, eg because a corrupt file has the
	 string section index in the ELF header pointing at a group
	 section.  So be paranoid, and test that the last byte of
	 the section is zero.  */
      if (hdr->sh_size == 0 || hdr->contents[hdr->sh_size - 1] != 0)
	return NULL;
    }

  if (strindex >= hdr->sh_size)
    {
      unsigned int shstrndx = elf_elfheader(abfd)->e_shstrndx;
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: invalid string offset %u >= %" PRIu64 " for section `%s'"),
	 abfd, strindex, (uint64_t) hdr->sh_size,
	 (shindex == shstrndx && strindex == hdr->sh_name
	  ? ".shstrtab"
	  : bfd_elf_string_from_elf_section (abfd, shstrndx, hdr->sh_name)));
      return NULL;
    }

  return ((char *) hdr->contents) + strindex;
}

/* Read and convert symbols to internal format.
   SYMCOUNT specifies the number of symbols to read, starting from
   symbol SYMOFFSET.  If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
   are non-NULL, they are used to store the internal symbols, external
   symbols, and symbol section index extensions, respectively.
   Returns a pointer to the internal symbol buffer (malloced if necessary)
   or NULL if there were no symbols or some kind of problem.  */

Elf_Internal_Sym *
bfd_elf_get_elf_syms (bfd *ibfd,
		      Elf_Internal_Shdr *symtab_hdr,
		      size_t symcount,
		      size_t symoffset,
		      Elf_Internal_Sym *intsym_buf,
		      void *extsym_buf,
		      Elf_External_Sym_Shndx *extshndx_buf)
{
  Elf_Internal_Shdr *shndx_hdr;
  void *alloc_ext;
  const bfd_byte *esym;
  Elf_External_Sym_Shndx *alloc_extshndx;
  Elf_External_Sym_Shndx *shndx;
  Elf_Internal_Sym *alloc_intsym;
  Elf_Internal_Sym *isym;
  Elf_Internal_Sym *isymend;
  const struct elf_backend_data *bed;
  size_t extsym_size;
  size_t amt;
  file_ptr pos;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
    abort ();

  if (symcount == 0)
    return intsym_buf;

  if (elf_use_dt_symtab_p (ibfd))
    {
      /* Use dynamic symbol table.  */
      if (elf_tdata (ibfd)->dt_symtab_count != symcount + symoffset)
	{
	  bfd_set_error (bfd_error_invalid_operation);
	  return NULL;
	}
      return elf_tdata (ibfd)->dt_symtab + symoffset;
    }

  /* Normal syms might have section extension entries.  */
  shndx_hdr = NULL;
  if (elf_symtab_shndx_list (ibfd) != NULL)
    {
      elf_section_list * entry;
      Elf_Internal_Shdr **sections = elf_elfsections (ibfd);

      /* Find an index section that is linked to this symtab section.  */
      for (entry = elf_symtab_shndx_list (ibfd); entry != NULL; entry = entry->next)
	{
	  /* PR 20063.  */
	  if (entry->hdr.sh_link >= elf_numsections (ibfd))
	    continue;

	  if (sections[entry->hdr.sh_link] == symtab_hdr)
	    {
	      shndx_hdr = & entry->hdr;
	      break;
	    };
	}

      if (shndx_hdr == NULL)
	{
	  if (symtab_hdr == &elf_symtab_hdr (ibfd))
	    /* Not really accurate, but this was how the old code used
	       to work.  */
	    shndx_hdr = &elf_symtab_shndx_list (ibfd)->hdr;
	  /* Otherwise we do nothing.  The assumption is that
	     the index table will not be needed.  */
	}
    }

  /* Read the symbols.  */
  alloc_ext = NULL;
  alloc_extshndx = NULL;
  alloc_intsym = NULL;
  bed = get_elf_backend_data (ibfd);
  extsym_size = bed->s->sizeof_sym;
  if (_bfd_mul_overflow (symcount, extsym_size, &amt))
    {
      bfd_set_error (bfd_error_file_too_big);
      return NULL;
    }
  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
  size_t alloc_ext_size = amt;
  if (bfd_seek (ibfd, pos, SEEK_SET) != 0
      || !_bfd_mmap_read_temporary (&extsym_buf, &alloc_ext_size,
				    &alloc_ext, ibfd, false))
    {
      intsym_buf = NULL;
      goto out2;
    }

  size_t alloc_extshndx_size = 0;
  if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
    extshndx_buf = NULL;
  else
    {
      if (_bfd_mul_overflow (symcount, sizeof (Elf_External_Sym_Shndx), &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  intsym_buf = NULL;
	  goto out1;
	}
      alloc_extshndx_size = amt;
      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
      if (bfd_seek (ibfd, pos, SEEK_SET) != 0
	  || !_bfd_mmap_read_temporary ((void **) &extshndx_buf,
					&alloc_extshndx_size,
					(void **) &alloc_extshndx,
					ibfd, false))
	{
	  intsym_buf = NULL;
	  goto out1;
	}
    }

  if (intsym_buf == NULL)
    {
      if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  goto out1;
	}
      alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt);
      intsym_buf = alloc_intsym;
      if (intsym_buf == NULL)
	goto out1;
    }

  /* Convert the symbols to internal form.  */
  isymend = intsym_buf + symcount;
  for (esym = (const bfd_byte *) extsym_buf, isym = intsym_buf,
	   shndx = extshndx_buf;
       isym < isymend;
       esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
    {
      if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
	{
	  symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
	  /* xgettext:c-format */
	  _bfd_error_handler (_("%pB symbol number %lu references"
				" nonexistent SHT_SYMTAB_SHNDX section"),
			      ibfd, (unsigned long) symoffset);
	  free (alloc_intsym);
	  intsym_buf = NULL;
	  goto out1;
	}

      /* PR 33019: Do not accept unsupported binding values - they will
	 likely cause problems later on.  */
      int bind = ELF_ST_BIND (isym->st_info);
      if (bind > STB_WEAK && bind < STB_LOOS)
	{	
	  /* xgettext:c-format */
	  _bfd_error_handler (_("%pB symbol number %lu uses unsupported binding of %u"),
			      ibfd, (unsigned long) (isym - intsym_buf), bind);
	  free (alloc_intsym);
	  intsym_buf = NULL;
	  goto out1;
	}

      /* Paranoia: Also refuse to accept the only undefined symbol type: 7.  */
      int t = ELF_ST_TYPE (isym->st_info);
      if (t == 7)
	{
	  /* xgettext:c-format */
	  _bfd_error_handler (_("%pB symbol number %lu uses unsupported type of %u"),
			      ibfd, (unsigned long) (isym - intsym_buf), t);
	  free (alloc_intsym);
	  intsym_buf = NULL;
	  goto out1;
	}
    }

 out1:
  _bfd_munmap_temporary (alloc_extshndx, alloc_extshndx_size);
 out2:
  _bfd_munmap_temporary (alloc_ext, alloc_ext_size);

  return intsym_buf;
}

/* Look up a symbol name.  */
static const char *
bfd_elf_sym_name_raw (bfd *abfd,
		      Elf_Internal_Shdr *symtab_hdr,
		      Elf_Internal_Sym *isym)
{
  unsigned int iname = isym->st_name;
  unsigned int shindex = symtab_hdr->sh_link;

  if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
      /* Check for a bogus st_shndx to avoid crashing.  */
      && isym->st_shndx < elf_numsections (abfd))
    {
      iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
      shindex = elf_elfheader (abfd)->e_shstrndx;
    }

  return bfd_elf_string_from_elf_section (abfd, shindex, iname);
}

const char *
bfd_elf_sym_name (bfd *abfd,
		  Elf_Internal_Shdr *symtab_hdr,
		  Elf_Internal_Sym *isym,
		  asection *sym_sec)
{
  const char *name = bfd_elf_sym_name_raw (abfd, symtab_hdr, isym);
  if (name == NULL)
    name = bfd_symbol_error_name;
  else if (sym_sec && *name == '\0')
    name = bfd_section_name (sym_sec);

  return name;
}

/* Return the name of the group signature symbol.  Why isn't the
   signature just a string?  */

static const char *
group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
{
  Elf_Internal_Shdr *hdr;
  unsigned char esym[sizeof (Elf64_External_Sym)];
  Elf_External_Sym_Shndx eshndx;
  Elf_Internal_Sym isym;

  /* First we need to ensure the symbol table is available.  Make sure
     that it is a symbol table section.  */
  if (ghdr->sh_link >= elf_numsections (abfd))
    return NULL;
  hdr = elf_elfsections (abfd) [ghdr->sh_link];
  if (hdr->sh_type != SHT_SYMTAB
      || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
    return NULL;

  /* Go read the symbol.  */
  hdr = &elf_tdata (abfd)->symtab_hdr;
  if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
			    &isym, esym, &eshndx) == NULL)
    return NULL;

  return bfd_elf_sym_name_raw (abfd, hdr, &isym);
}

static bool
is_valid_group_section_header (Elf_Internal_Shdr *shdr, size_t minsize)
{
  return (shdr->sh_size >= minsize
	  && shdr->sh_entsize == GRP_ENTRY_SIZE
	  && shdr->sh_size % GRP_ENTRY_SIZE == 0
	  && shdr->bfd_section != NULL);
}


/* Set next_in_group, sec_group list pointers, and group names.  */

static bool
process_sht_group_entries (bfd *abfd,
			   Elf_Internal_Shdr *ghdr, unsigned int gidx)
{
  unsigned char *contents;

  /* Read the raw contents.  */
  if (!bfd_malloc_and_get_section (abfd, ghdr->bfd_section, &contents))
    {
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: could not read contents of group [%u]"), abfd, gidx);
      return false;
    }

  asection *last_elt = NULL;
  const char *gname = NULL;
  unsigned char *p = contents + ghdr->sh_size;
  while (1)
    {
      unsigned int idx;
      Elf_Internal_Shdr *shdr;
      asection *elt;

      p -= 4;
      idx = H_GET_32 (abfd, p);
      if (p == contents)
	{
	  if ((idx & GRP_COMDAT) != 0)
	    ghdr->bfd_section->flags
	      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
	  break;
	}

      if (idx == 0
	  || idx >= elf_numsections (abfd)
	  || (shdr = elf_elfsections (abfd)[idx])->sh_type == SHT_GROUP
	  || ((elt = shdr->bfd_section) != NULL
	      && elf_sec_group (elt) != NULL
	      && elf_sec_group (elt) != ghdr->bfd_section))
	{
	  _bfd_error_handler
	    (_("%pB: invalid entry (%#x) in group [%u]"),
	     abfd, idx, gidx);
	  continue;
	}

      /* PR binutils/23199: According to the ELF gABI all sections in
	 a group must be marked with SHF_GROUP, but some tools
	 generate broken objects.  Fix them up here.  */
      shdr->sh_flags |= SHF_GROUP;

      if (elt == NULL)
	{
	  if (shdr->sh_type != SHT_RELA && shdr->sh_type != SHT_REL)
	    {
	      const char *name = bfd_elf_string_from_elf_section
		(abfd, elf_elfheader (abfd)->e_shstrndx, shdr->sh_name);

	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unexpected type (%#x) section `%s' in group [%u]"),
		 abfd, shdr->sh_type, name, gidx);
	    }
	  continue;
	}

      /* Don't try to add a section to elf_next_in_group list twice.  */
      if (elf_sec_group (elt) != NULL)
	continue;

      if (last_elt == NULL)
	{
	  /* Start a circular list with one element.
	     It will be in reverse order to match what gas does.  */
	  elf_next_in_group (elt) = elt;
	  /* Point the group section to it.  */
	  elf_next_in_group (ghdr->bfd_section) = elt;
	  gname = group_signature (abfd, ghdr);
	  if (gname == NULL)
	    {
	      free (contents);
	      return false;
	    }
	}
      else
	{
	  elf_next_in_group (elt) = elf_next_in_group (last_elt);
	  elf_next_in_group (last_elt) = elt;
	}
      last_elt = elt;
      elf_group_name (elt) = gname;
      elf_sec_group (elt) = ghdr->bfd_section;
    }

  free (contents);
  return last_elt != NULL;
}

bool
_bfd_elf_setup_sections (bfd *abfd)
{
  bool result = true;

  /* Process SHF_LINK_ORDER.  */
  for (asection *s = abfd->sections; s != NULL; s = s->next)
    {
      Elf_Internal_Shdr *this_hdr = &elf_section_data (s)->this_hdr;
      if ((this_hdr->sh_flags & SHF_LINK_ORDER) != 0)
	{
	  unsigned int elfsec = this_hdr->sh_link;
	  /* An sh_link value of 0 is now allowed.  It indicates that linked
	     to section has already been discarded, but that the current
	     section has been retained for some other reason.  This linking
	     section is still a candidate for later garbage collection
	     however.  */
	  if (elfsec == 0)
	    {
	      elf_linked_to_section (s) = NULL;
	    }
	  else
	    {
	      asection *linksec = NULL;

	      if (elfsec < elf_numsections (abfd))
		{
		  this_hdr = elf_elfsections (abfd)[elfsec];
		  linksec = this_hdr->bfd_section;
		}

	      /* PR 1991, 2008:
		 Some strip/objcopy may leave an incorrect value in
		 sh_link.  We don't want to proceed.  */
	      if (linksec == NULL)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: sh_link [%d] in section `%pA' is incorrect"),
		     s->owner, elfsec, s);
		  result = false;
		}

	      elf_linked_to_section (s) = linksec;
	    }
	}
    }

  /* Process section groups.  */
  for (unsigned int i = 1; i < elf_numsections (abfd); i++)
    {
      Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];

      if (shdr && shdr->sh_type == SHT_GROUP)
	{
	  if (is_valid_group_section_header (shdr, GRP_ENTRY_SIZE))
	    {
	      if (shdr->sh_size >= 2 * GRP_ENTRY_SIZE
		  && !process_sht_group_entries (abfd, shdr, i))
		result = false;
	    }
	  else
	    {
	      /* PR binutils/18758: Beware of corrupt binaries with
		 invalid group data.  */
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: section group entry number %u is corrupt"), abfd, i);
	      result = false;
	    }
	}
    }

  return result;
}

bool
bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
{
  return elf_next_in_group (sec) != NULL;
}

const char *
bfd_elf_group_name (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
{
  if (elf_sec_group (sec) != NULL)
    return elf_group_name (sec);
  return NULL;
}

/* Make a BFD section from an ELF section.  We store a pointer to the
   BFD section in the bfd_section field of the header.  */

bool
_bfd_elf_make_section_from_shdr (bfd *abfd,
				 Elf_Internal_Shdr *hdr,
				 const char *name,
				 int shindex)
{
  asection *newsect;
  flagword flags;
  const struct elf_backend_data *bed;
  unsigned int opb = bfd_octets_per_byte (abfd, NULL);

  if (hdr->bfd_section != NULL)
    return true;

  newsect = bfd_make_section_anyway (abfd, name);
  if (newsect == NULL)
    return false;

  hdr->bfd_section = newsect;
  elf_section_data (newsect)->this_hdr = *hdr;
  elf_section_data (newsect)->this_idx = shindex;

  /* Always use the real type/flags.  */
  elf_section_type (newsect) = hdr->sh_type;
  elf_section_flags (newsect) = hdr->sh_flags;

  newsect->filepos = hdr->sh_offset;

  flags = SEC_NO_FLAGS;
  if (hdr->sh_type != SHT_NOBITS)
    flags |= SEC_HAS_CONTENTS;
  if (hdr->sh_type == SHT_GROUP)
    flags |= SEC_GROUP;
  if ((hdr->sh_flags & SHF_ALLOC) != 0)
    {
      flags |= SEC_ALLOC;
      if (hdr->sh_type != SHT_NOBITS)
	flags |= SEC_LOAD;
    }
  if ((hdr->sh_flags & SHF_WRITE) == 0)
    flags |= SEC_READONLY;
  if ((hdr->sh_flags & SHF_EXECINSTR) != 0)
    flags |= SEC_CODE;
  else if ((flags & SEC_LOAD) != 0)
    flags |= SEC_DATA;
  if ((hdr->sh_flags & SHF_MERGE) != 0)
    flags |= SEC_MERGE;
  if ((hdr->sh_flags & SHF_STRINGS) != 0)
    flags |= SEC_STRINGS;
  if ((hdr->sh_flags & SHF_TLS) != 0)
    flags |= SEC_THREAD_LOCAL;
  if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
    flags |= SEC_EXCLUDE;

  newsect->entsize = hdr->sh_entsize;

  switch (elf_elfheader (abfd)->e_ident[EI_OSABI])
    {
      /* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
	 but binutils as of 2019-07-23 did not set the EI_OSABI header
	 byte.  */
    case ELFOSABI_GNU:
    case ELFOSABI_FREEBSD:
      if ((hdr->sh_flags & SHF_GNU_RETAIN) != 0)
	elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_retain;
      /* Fall through */
    case ELFOSABI_NONE:
      if ((hdr->sh_flags & SHF_GNU_MBIND) != 0)
	elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
      break;
    }

  if ((flags & (SEC_ALLOC | SEC_GROUP)) == 0)
    {
      /* The debugging sections appear to be recognized only by name,
	 not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
      if (name [0] == '.')
	{
	  if (startswith (name, ".debug")
	      || startswith (name, ".gnu.debuglto_.debug_")
	      || startswith (name, ".gnu.linkonce.wi.")
	      || startswith (name, ".zdebug"))
	    flags |= SEC_DEBUGGING | SEC_ELF_OCTETS;
	  else if (startswith (name, GNU_BUILD_ATTRS_SECTION_NAME)
		   || startswith (name, ".note.gnu"))
	    {
	      flags |= SEC_ELF_OCTETS;
	      opb = 1;
	    }
	  else if (startswith (name, ".line")
		   || startswith (name, ".stab")
		   || streq (name, ".gdb_index"))
	    flags |= SEC_DEBUGGING;
	}
    }

  if (!bfd_set_section_vma (newsect, hdr->sh_addr / opb)
      || !bfd_set_section_size (newsect, hdr->sh_size)
      || !bfd_set_section_alignment (newsect, bfd_log2 (hdr->sh_addralign
							& -hdr->sh_addralign)))
    return false;

  /* As a GNU extension, if the name begins with .gnu.linkonce, we
     only link a single copy of the section.  This is used to support
     g++.  g++ will emit each template expansion in its own section.
     The symbols will be defined as weak, so that multiple definitions
     are permitted.  The GNU linker extension is to actually discard
     all but one of the sections.  */
  if (startswith (name, ".gnu.linkonce")
      && elf_next_in_group (newsect) == NULL)
    flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;

  if (!bfd_set_section_flags (newsect, flags))
    return false;

  bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_section_flags)
    if (!bed->elf_backend_section_flags (hdr))
      return false;

  /* We do not parse the PT_NOTE segments as we are interested even in the
     separate debug info files which may have the segments offsets corrupted.
     PT_NOTEs from the core files are currently not parsed using BFD.  */
  if (hdr->sh_type == SHT_NOTE && hdr->sh_size != 0)
    {
      bfd_byte *contents;

      if (!_bfd_elf_mmap_section_contents (abfd, newsect, &contents))
	return false;

      elf_parse_notes (abfd, (char *) contents, hdr->sh_size,
		       hdr->sh_offset, hdr->sh_addralign);
      _bfd_elf_munmap_section_contents (newsect, contents);
    }

  if ((newsect->flags & SEC_ALLOC) != 0)
    {
      Elf_Internal_Phdr *phdr;
      unsigned int i, nload;

      /* Some ELF linkers produce binaries with all the program header
	 p_paddr fields zero.  If we have such a binary with more than
	 one PT_LOAD header, then leave the section lma equal to vma
	 so that we don't create sections with overlapping lma.  */
      phdr = elf_tdata (abfd)->phdr;
      for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
	if (phdr->p_paddr != 0)
	  break;
	else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
	  ++nload;
      if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
	return true;

      phdr = elf_tdata (abfd)->phdr;
      for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
	{
	  if (((phdr->p_type == PT_LOAD
		&& (hdr->sh_flags & SHF_TLS) == 0)
	       || phdr->p_type == PT_TLS)
	      && ELF_SECTION_IN_SEGMENT (hdr, phdr))
	    {
	      if ((newsect->flags & SEC_LOAD) == 0)
		newsect->lma = (phdr->p_paddr
				+ hdr->sh_addr - phdr->p_vaddr) / opb;
	      else
		/* We used to use the same adjustment for SEC_LOAD
		   sections, but that doesn't work if the segment
		   is packed with code from multiple VMAs.
		   Instead we calculate the section LMA based on
		   the segment LMA.  It is assumed that the
		   segment will contain sections with contiguous
		   LMAs, even if the VMAs are not.  */
		newsect->lma = (phdr->p_paddr
				+ hdr->sh_offset - phdr->p_offset) / opb;

	      /* With contiguous segments, we can't tell from file
		 offsets whether a section with zero size should
		 be placed at the end of one segment or the
		 beginning of the next.  Decide based on vaddr.  */
	      if (hdr->sh_addr >= phdr->p_vaddr
		  && (hdr->sh_addr + hdr->sh_size
		      <= phdr->p_vaddr + phdr->p_memsz))
		break;
	    }
	}
    }

  /* Compress/decompress DWARF debug sections with names: .debug_*,
     .zdebug_*, .gnu.debuglto_.debug_, after the section flags is set.  */
  if ((newsect->flags & SEC_DEBUGGING) != 0
      && (newsect->flags & SEC_HAS_CONTENTS) != 0
      && (newsect->flags & SEC_ELF_OCTETS) != 0)
    {
      enum { nothing, compress, decompress } action = nothing;
      int compression_header_size;
      bfd_size_type uncompressed_size;
      unsigned int uncompressed_align_power;
      enum compression_type ch_type = ch_none;
      bool compressed
	= bfd_is_section_compressed_info (abfd, newsect,
					  &compression_header_size,
					  &uncompressed_size,
					  &uncompressed_align_power,
					  &ch_type);

      /* Should we decompress?  */
      if ((abfd->flags & BFD_DECOMPRESS) != 0 && compressed)
	action = decompress;

      /* Should we compress?  Or convert to a different compression?  */
      else if ((abfd->flags & BFD_COMPRESS) != 0
	       && newsect->size != 0
	       && compression_header_size >= 0
	       && uncompressed_size > 0)
	{
	  if (!compressed)
	    action = compress;
	  else
	    {
	      enum compression_type new_ch_type = ch_none;
	      if ((abfd->flags & BFD_COMPRESS_GABI) != 0)
		new_ch_type = ((abfd->flags & BFD_COMPRESS_ZSTD) != 0
			       ? ch_compress_zstd : ch_compress_zlib);
	      if (new_ch_type != ch_type)
		action = compress;
	    }
	}

      if (action == compress)
	{
	  if (!bfd_init_section_compress_status (abfd, newsect))
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unable to compress section %s"), abfd, name);
	      return false;
	    }
	}
      else if (action == decompress)
	{
	  if (!bfd_init_section_decompress_status (abfd, newsect))
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unable to decompress section %s"), abfd, name);
	      return false;
	    }
#ifndef HAVE_ZSTD
	  if (newsect->compress_status == DECOMPRESS_SECTION_ZSTD)
	    {
	      _bfd_error_handler
		  /* xgettext:c-format */
		  (_ ("%pB: section %s is compressed with zstd, but BFD "
		      "is not built with zstd support"),
		   abfd, name);
	      newsect->compress_status = COMPRESS_SECTION_NONE;
	      return false;
	    }
#endif
	  if (abfd->is_linker_input
	      && name[1] == 'z')
	    {
	      /* Rename section from .zdebug_* to .debug_* so that ld
		 scripts will see this section as a debug section.  */
	      char *new_name = bfd_zdebug_name_to_debug (abfd, name);
	      if (new_name == NULL)
		return false;
	      bfd_rename_section (newsect, new_name);
	    }
	}
    }

  return true;
}

const char *const bfd_elf_section_type_names[] =
{
  "SHT_NULL", "SHT_PROGBITS", "SHT_SYMTAB", "SHT_STRTAB",
  "SHT_RELA", "SHT_HASH", "SHT_DYNAMIC", "SHT_NOTE",
  "SHT_NOBITS", "SHT_REL", "SHT_SHLIB", "SHT_DYNSYM",
};

/* ELF relocs are against symbols.  If we are producing relocatable
   output, and the reloc is against an external symbol, and nothing
   has given us any additional addend, the resulting reloc will also
   be against the same symbol.  In such a case, we don't want to
   change anything about the way the reloc is handled, since it will
   all be done at final link time.  Rather than put special case code
   into bfd_perform_relocation, all the reloc types use this howto
   function, or should call this function for relocatable output.  */

bfd_reloc_status_type
bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED,
		       arelent *reloc_entry,
		       asymbol *symbol,
		       void *data ATTRIBUTE_UNUSED,
		       asection *input_section,
		       bfd *output_bfd,
		       char **error_message ATTRIBUTE_UNUSED)
{
  if (output_bfd != NULL
      && (symbol->flags & BSF_SECTION_SYM) == 0
      && (! reloc_entry->howto->partial_inplace
	  || reloc_entry->addend == 0))
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  /* In some cases the relocation should be treated as output section
     relative, as when linking ELF DWARF into PE COFF.  Many ELF
     targets lack section relative relocations and instead use
     ordinary absolute relocations for references between DWARF
     sections.  That is arguably a bug in those targets but it happens
     to work for the usual case of linking to non-loaded ELF debug
     sections with VMAs forced to zero.  PE COFF on the other hand
     doesn't allow a section VMA of zero.  */
  if (output_bfd == NULL
      && !reloc_entry->howto->pc_relative
      && (symbol->section->flags & SEC_DEBUGGING) != 0
      && (input_section->flags & SEC_DEBUGGING) != 0)
    reloc_entry->addend -= symbol->section->output_section->vma;

  return bfd_reloc_continue;
}

/* Returns TRUE if section A matches section B.
   Names, addresses and links may be different, but everything else
   should be the same.  */

static bool
section_match (const Elf_Internal_Shdr * a,
	       const Elf_Internal_Shdr * b)
{
  if (a->sh_type != b->sh_type
      || ((a->sh_flags ^ b->sh_flags) & ~SHF_INFO_LINK) != 0
      || a->sh_addralign != b->sh_addralign
      || a->sh_entsize != b->sh_entsize)
    return false;
  if (a->sh_type == SHT_SYMTAB
      || a->sh_type == SHT_STRTAB)
    return true;
  return a->sh_size == b->sh_size;
}

/* Find a section in OBFD that has the same characteristics
   as IHEADER.  Return the index of this section or SHN_UNDEF if
   none can be found.  Check's section HINT first, as this is likely
   to be the correct section.  */

static unsigned int
find_link (const bfd *obfd, const Elf_Internal_Shdr *iheader,
	   const unsigned int hint)
{
  Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd);
  unsigned int i;

  BFD_ASSERT (iheader != NULL);

  /* See PR 20922 for a reproducer of the NULL test.  */
  if (hint < elf_numsections (obfd)
      && oheaders[hint] != NULL
      && section_match (oheaders[hint], iheader))
    return hint;

  for (i = 1; i < elf_numsections (obfd); i++)
    {
      Elf_Internal_Shdr * oheader = oheaders[i];

      if (oheader == NULL)
	continue;
      if (section_match (oheader, iheader))
	/* FIXME: Do we care if there is a potential for
	   multiple matches ?  */
	return i;
    }

  return SHN_UNDEF;
}

/* PR 19938: Attempt to set the ELF section header fields of an OS or
   Processor specific section, based upon a matching input section.
   Returns TRUE upon success, FALSE otherwise.  */

static bool
copy_special_section_fields (const bfd *ibfd,
			     bfd *obfd,
			     const Elf_Internal_Shdr *iheader,
			     Elf_Internal_Shdr *oheader,
			     const unsigned int secnum)
{
  const struct elf_backend_data *bed = get_elf_backend_data (obfd);
  const Elf_Internal_Shdr **iheaders
    = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
  bool changed = false;
  unsigned int sh_link;

  if (oheader->sh_type == SHT_NOBITS)
    {
      /* This is a feature for objcopy --only-keep-debug:
	 When a section's type is changed to NOBITS, we preserve
	 the sh_link and sh_info fields so that they can be
	 matched up with the original.

	 Note: Strictly speaking these assignments are wrong.
	 The sh_link and sh_info fields should point to the
	 relevent sections in the output BFD, which may not be in
	 the same location as they were in the input BFD.  But
	 the whole point of this action is to preserve the
	 original values of the sh_link and sh_info fields, so
	 that they can be matched up with the section headers in
	 the original file.  So strictly speaking we may be
	 creating an invalid ELF file, but it is only for a file
	 that just contains debug info and only for sections
	 without any contents.  */
      if (oheader->sh_link == 0)
	oheader->sh_link = iheader->sh_link;
      if (oheader->sh_info == 0)
	oheader->sh_info = iheader->sh_info;
      return true;
    }

  /* Allow the target a chance to decide how these fields should be set.  */
  if (bed->elf_backend_copy_special_section_fields (ibfd, obfd,
						    iheader, oheader))
    return true;

  /* We have an iheader which might match oheader, and which has non-zero
     sh_info and/or sh_link fields.  Attempt to follow those links and find
     the section in the output bfd which corresponds to the linked section
     in the input bfd.  */
  if (iheader->sh_link != SHN_UNDEF)
    {
      /* See PR 20931 for a reproducer.  */
      if (iheader->sh_link >= elf_numsections (ibfd))
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: invalid sh_link field (%d) in section number %d"),
	     ibfd, iheader->sh_link, secnum);
	  return false;
	}

      sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link);
      if (sh_link != SHN_UNDEF)
	{
	  oheader->sh_link = sh_link;
	  changed = true;
	}
      else
	/* FIXME: Should we install iheader->sh_link
	   if we could not find a match ?  */
	_bfd_error_handler
	  /* xgettext:c-format */
	  (_("%pB: failed to find link section for section %d"), obfd, secnum);
    }

  if (iheader->sh_info)
    {
      /* The sh_info field can hold arbitrary information, but if the
	 SHF_LINK_INFO flag is set then it should be interpreted as a
	 section index.  */
      if (iheader->sh_flags & SHF_INFO_LINK)
	{
	  sh_link = find_link (obfd, iheaders[iheader->sh_info],
			       iheader->sh_info);
	  if (sh_link != SHN_UNDEF)
	    oheader->sh_flags |= SHF_INFO_LINK;
	}
      else
	/* No idea what it means - just copy it.  */
	sh_link = iheader->sh_info;

      if (sh_link != SHN_UNDEF)
	{
	  oheader->sh_info = sh_link;
	  changed = true;
	}
      else
	_bfd_error_handler
	  /* xgettext:c-format */
	  (_("%pB: failed to find info section for section %d"), obfd, secnum);
    }

  return changed;
}

/* Copy the program header and other data from one object module to
   another.  */

bool
_bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  const Elf_Internal_Shdr **iheaders;
  Elf_Internal_Shdr **oheaders;
  const struct elf_backend_data *bed;
  unsigned int i;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
    return true;

  if (!elf_flags_init (obfd))
    {
      elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
      elf_flags_init (obfd) = true;
    }

  elf_gp (obfd) = elf_gp (ibfd);

  /* Also copy the EI_OSABI field.  */
  elf_elfheader (obfd)->e_ident[EI_OSABI] =
    elf_elfheader (ibfd)->e_ident[EI_OSABI];

  /* If set, copy the EI_ABIVERSION field.  */
  if (elf_elfheader (ibfd)->e_ident[EI_ABIVERSION])
    elf_elfheader (obfd)->e_ident[EI_ABIVERSION]
      = elf_elfheader (ibfd)->e_ident[EI_ABIVERSION];

  /* Copy object attributes.  */
  _bfd_elf_copy_obj_attributes (ibfd, obfd);

  iheaders = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
  oheaders = elf_elfsections (obfd);
  if (iheaders == NULL || oheaders == NULL)
    return true;

  bed = get_elf_backend_data (obfd);

  /* Possibly copy other fields in the section header.  */
  for (i = 1; i < elf_numsections (obfd); i++)
    {
      unsigned int j;
      Elf_Internal_Shdr * oheader = oheaders[i];

      /* Ignore ordinary sections.  SHT_NOBITS sections are considered however
	 because of a special case need for generating separate debug info
	 files.  See below for more details.  */
      if (oheader == NULL
	  || (oheader->sh_type != SHT_NOBITS
	      && oheader->sh_type < SHT_LOOS))
	continue;

      /* Ignore empty sections, and sections whose
	 fields have already been initialised.  */
      if (oheader->sh_size == 0
	  || (oheader->sh_info != 0 && oheader->sh_link != 0))
	continue;

      /* Scan for the matching section in the input bfd.
	 First we try for a direct mapping between the input and
	 output sections.  */
      for (j = 1; j < elf_numsections (ibfd); j++)
	{
	  const Elf_Internal_Shdr * iheader = iheaders[j];

	  if (iheader == NULL)
	    continue;

	  if (oheader->bfd_section != NULL
	      && iheader->bfd_section != NULL
	      && iheader->bfd_section->output_section != NULL
	      && iheader->bfd_section->output_section == oheader->bfd_section)
	    {
	      /* We have found a connection from the input section to
		 the output section.  Attempt to copy the header fields.
		 If this fails then do not try any further sections -
		 there should only be a one-to-one mapping between
		 input and output.  */
	      if (!copy_special_section_fields (ibfd, obfd,
						iheader, oheader, i))
		j = elf_numsections (ibfd);
	      break;
	    }
	}

      if (j < elf_numsections (ibfd))
	continue;

      /* That failed.  So try to deduce the corresponding input section.
	 Unfortunately we cannot compare names as the output string table
	 is empty, so instead we check size, address and type.  */
      for (j = 1; j < elf_numsections (ibfd); j++)
	{
	  const Elf_Internal_Shdr * iheader = iheaders[j];

	  if (iheader == NULL)
	    continue;

	  /* Try matching fields in the input section's header.
	     Since --only-keep-debug turns all non-debug sections into
	     SHT_NOBITS sections, the output SHT_NOBITS type matches any
	     input type.  */
	  if ((oheader->sh_type == SHT_NOBITS
	       || iheader->sh_type == oheader->sh_type)
	      && (iheader->sh_flags & ~ SHF_INFO_LINK)
	      == (oheader->sh_flags & ~ SHF_INFO_LINK)
	      && iheader->sh_addralign == oheader->sh_addralign
	      && iheader->sh_entsize == oheader->sh_entsize
	      && iheader->sh_size == oheader->sh_size
	      && iheader->sh_addr == oheader->sh_addr
	      && (iheader->sh_info != oheader->sh_info
		  || iheader->sh_link != oheader->sh_link))
	    {
	      if (copy_special_section_fields (ibfd, obfd, iheader, oheader, i))
		break;
	    }
	}

      if (j == elf_numsections (ibfd) && oheader->sh_type >= SHT_LOOS)
	{
	  /* Final attempt.  Call the backend copy function
	     with a NULL input section.  */
	  (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd,
							       NULL, oheader);
	}
    }

  return true;
}

static const char *
get_segment_type (unsigned int p_type)
{
  const char *pt;
  switch (p_type)
    {
    case PT_NULL: pt = "NULL"; break;
    case PT_LOAD: pt = "LOAD"; break;
    case PT_DYNAMIC: pt = "DYNAMIC"; break;
    case PT_INTERP: pt = "INTERP"; break;
    case PT_NOTE: pt = "NOTE"; break;
    case PT_SHLIB: pt = "SHLIB"; break;
    case PT_PHDR: pt = "PHDR"; break;
    case PT_TLS: pt = "TLS"; break;
    case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break;
    case PT_GNU_STACK: pt = "STACK"; break;
    case PT_GNU_RELRO: pt = "RELRO"; break;
    case PT_GNU_SFRAME: pt = "SFRAME"; break;
    default: pt = NULL; break;
    }
  return pt;
}

/* Print out the program headers.  */

bool
_bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
{
  FILE *f = (FILE *) farg;
  Elf_Internal_Phdr *p;
  asection *s;
  bfd_byte *dynbuf = NULL;

  p = elf_tdata (abfd)->phdr;
  if (p != NULL)
    {
      unsigned int i, c;

      fprintf (f, _("\nProgram Header:\n"));
      c = elf_elfheader (abfd)->e_phnum;
      for (i = 0; i < c; i++, p++)
	{
	  const char *pt = get_segment_type (p->p_type);
	  char buf[20];

	  if (pt == NULL)
	    {
	      sprintf (buf, "0x%lx", p->p_type);
	      pt = buf;
	    }
	  fprintf (f, "%8s off    0x", pt);
	  bfd_fprintf_vma (abfd, f, p->p_offset);
	  fprintf (f, " vaddr 0x");
	  bfd_fprintf_vma (abfd, f, p->p_vaddr);
	  fprintf (f, " paddr 0x");
	  bfd_fprintf_vma (abfd, f, p->p_paddr);
	  fprintf (f, " align 2**%u\n", bfd_log2 (p->p_align));
	  fprintf (f, "         filesz 0x");
	  bfd_fprintf_vma (abfd, f, p->p_filesz);
	  fprintf (f, " memsz 0x");
	  bfd_fprintf_vma (abfd, f, p->p_memsz);
	  fprintf (f, " flags %c%c%c",
		   (p->p_flags & PF_R) != 0 ? 'r' : '-',
		   (p->p_flags & PF_W) != 0 ? 'w' : '-',
		   (p->p_flags & PF_X) != 0 ? 'x' : '-');
	  if ((p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X)) != 0)
	    fprintf (f, " %lx", p->p_flags &~ (unsigned) (PF_R | PF_W | PF_X));
	  fprintf (f, "\n");
	}
    }

  s = bfd_get_section_by_name (abfd, ".dynamic");
  if (s != NULL && (s->flags & SEC_HAS_CONTENTS) != 0)
    {
      unsigned int elfsec;
      unsigned long shlink;
      bfd_byte *extdyn, *extdynend;
      size_t extdynsize;
      void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);

      fprintf (f, _("\nDynamic Section:\n"));

      if (!_bfd_elf_mmap_section_contents (abfd, s, &dynbuf))
	goto error_return;

      elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
      if (elfsec == SHN_BAD)
	goto error_return;
      shlink = elf_elfsections (abfd)[elfsec]->sh_link;

      extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
      swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;

      for (extdyn = dynbuf, extdynend = dynbuf + s->size;
	   (size_t) (extdynend - extdyn) >= extdynsize;
	   extdyn += extdynsize)
	{
	  Elf_Internal_Dyn dyn;
	  const char *name = "";
	  char ab[20];
	  bool stringp;
	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

	  (*swap_dyn_in) (abfd, extdyn, &dyn);

	  if (dyn.d_tag == DT_NULL)
	    break;

	  stringp = false;
	  switch (dyn.d_tag)
	    {
	    default:
	      if (bed->elf_backend_get_target_dtag)
		name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);

	      if (streq (name, ""))
		{
		  sprintf (ab, "%#" PRIx64, (uint64_t) dyn.d_tag);
		  name = ab;
		}
	      break;

	    case DT_NEEDED: name = "NEEDED"; stringp = true; break;
	    case DT_PLTRELSZ: name = "PLTRELSZ"; break;
	    case DT_PLTGOT: name = "PLTGOT"; break;
	    case DT_HASH: name = "HASH"; break;
	    case DT_STRTAB: name = "STRTAB"; break;
	    case DT_SYMTAB: name = "SYMTAB"; break;
	    case DT_RELA: name = "RELA"; break;
	    case DT_RELASZ: name = "RELASZ"; break;
	    case DT_RELAENT: name = "RELAENT"; break;
	    case DT_STRSZ: name = "STRSZ"; break;
	    case DT_SYMENT: name = "SYMENT"; break;
	    case DT_INIT: name = "INIT"; break;
	    case DT_FINI: name = "FINI"; break;
	    case DT_SONAME: name = "SONAME"; stringp = true; break;
	    case DT_RPATH: name = "RPATH"; stringp = true; break;
	    case DT_SYMBOLIC: name = "SYMBOLIC"; break;
	    case DT_REL: name = "REL"; break;
	    case DT_RELSZ: name = "RELSZ"; break;
	    case DT_RELENT: name = "RELENT"; break;
	    case DT_RELR: name = "RELR"; break;
	    case DT_RELRSZ: name = "RELRSZ"; break;
	    case DT_RELRENT: name = "RELRENT"; break;
	    case DT_PLTREL: name = "PLTREL"; break;
	    case DT_DEBUG: name = "DEBUG"; break;
	    case DT_TEXTREL: name = "TEXTREL"; break;
	    case DT_JMPREL: name = "JMPREL"; break;
	    case DT_BIND_NOW: name = "BIND_NOW"; break;
	    case DT_INIT_ARRAY: name = "INIT_ARRAY"; break;
	    case DT_FINI_ARRAY: name = "FINI_ARRAY"; break;
	    case DT_INIT_ARRAYSZ: name = "INIT_ARRAYSZ"; break;
	    case DT_FINI_ARRAYSZ: name = "FINI_ARRAYSZ"; break;
	    case DT_RUNPATH: name = "RUNPATH"; stringp = true; break;
	    case DT_FLAGS: name = "FLAGS"; break;
	    case DT_PREINIT_ARRAY: name = "PREINIT_ARRAY"; break;
	    case DT_PREINIT_ARRAYSZ: name = "PREINIT_ARRAYSZ"; break;
	    case DT_CHECKSUM: name = "CHECKSUM"; break;
	    case DT_PLTPADSZ: name = "PLTPADSZ"; break;
	    case DT_MOVEENT: name = "MOVEENT"; break;
	    case DT_MOVESZ: name = "MOVESZ"; break;
	    case DT_FEATURE: name = "FEATURE"; break;
	    case DT_POSFLAG_1: name = "POSFLAG_1"; break;
	    case DT_SYMINSZ: name = "SYMINSZ"; break;
	    case DT_SYMINENT: name = "SYMINENT"; break;
	    case DT_CONFIG: name = "CONFIG"; stringp = true; break;
	    case DT_DEPAUDIT: name = "DEPAUDIT"; stringp = true; break;
	    case DT_AUDIT: name = "AUDIT"; stringp = true; break;
	    case DT_PLTPAD: name = "PLTPAD"; break;
	    case DT_MOVETAB: name = "MOVETAB"; break;
	    case DT_SYMINFO: name = "SYMINFO"; break;
	    case DT_RELACOUNT: name = "RELACOUNT"; break;
	    case DT_RELCOUNT: name = "RELCOUNT"; break;
	    case DT_FLAGS_1: name = "FLAGS_1"; break;
	    case DT_VERSYM: name = "VERSYM"; break;
	    case DT_VERDEF: name = "VERDEF"; break;
	    case DT_VERDEFNUM: name = "VERDEFNUM"; break;
	    case DT_VERNEED: name = "VERNEED"; break;
	    case DT_VERNEEDNUM: name = "VERNEEDNUM"; break;
	    case DT_AUXILIARY: name = "AUXILIARY"; stringp = true; break;
	    case DT_USED: name = "USED"; break;
	    case DT_FILTER: name = "FILTER"; stringp = true; break;
	    case DT_GNU_HASH: name = "GNU_HASH"; break;
	    }

	  fprintf (f, "  %-20s ", name);
	  if (! stringp)
	    {
	      fprintf (f, "0x");
	      bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
	    }
	  else
	    {
	      const char *string;
	      unsigned int tagv = dyn.d_un.d_val;

	      string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
	      if (string == NULL)
		goto error_return;
	      fprintf (f, "%s", string);
	    }
	  fprintf (f, "\n");
	}

      _bfd_elf_munmap_section_contents (s, dynbuf);
      dynbuf = NULL;
    }

  if ((elf_dynverdef (abfd) != 0 && elf_tdata (abfd)->verdef == NULL)
      || (elf_dynverref (abfd) != 0 && elf_tdata (abfd)->verref == NULL))
    {
      if (! _bfd_elf_slurp_version_tables (abfd, false))
	return false;
    }

  if (elf_dynverdef (abfd) != 0)
    {
      Elf_Internal_Verdef *t;

      fprintf (f, _("\nVersion definitions:\n"));
      for (t = elf_tdata (abfd)->verdef; t != NULL; t = t->vd_nextdef)
	{
	  fprintf (f, "%d 0x%2.2x 0x%8.8lx %s\n", t->vd_ndx,
		   t->vd_flags, t->vd_hash,
		   t->vd_nodename ? t->vd_nodename : "<corrupt>");
	  if (t->vd_auxptr != NULL && t->vd_auxptr->vda_nextptr != NULL)
	    {
	      Elf_Internal_Verdaux *a;

	      fprintf (f, "\t");
	      for (a = t->vd_auxptr->vda_nextptr;
		   a != NULL;
		   a = a->vda_nextptr)
		fprintf (f, "%s ",
			 a->vda_nodename ? a->vda_nodename : "<corrupt>");
	      fprintf (f, "\n");
	    }
	}
    }

  if (elf_dynverref (abfd) != 0)
    {
      Elf_Internal_Verneed *t;

      fprintf (f, _("\nVersion References:\n"));
      for (t = elf_tdata (abfd)->verref; t != NULL; t = t->vn_nextref)
	{
	  Elf_Internal_Vernaux *a;

	  fprintf (f, _("  required from %s:\n"),
		   t->vn_filename ? t->vn_filename : "<corrupt>");
	  for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
	    fprintf (f, "    0x%8.8lx 0x%2.2x %2.2d %s\n", a->vna_hash,
		     a->vna_flags, a->vna_other,
		     a->vna_nodename ? a->vna_nodename : "<corrupt>");
	}
    }

  return true;

 error_return:
  _bfd_elf_munmap_section_contents (s, dynbuf);
  return false;
}

/* Find the file offset corresponding to VMA by using the program
   headers.  */

static file_ptr
offset_from_vma (Elf_Internal_Phdr *phdrs, size_t phnum, bfd_vma vma,
		 size_t size, size_t *max_size_p)
{
  Elf_Internal_Phdr *seg;
  size_t i;

  for (seg = phdrs, i = 0; i < phnum; ++seg, ++i)
    if (seg->p_type == PT_LOAD
	&& vma >= (seg->p_vaddr & -seg->p_align)
	&& vma + size <= seg->p_vaddr + seg->p_filesz)
      {
	if (max_size_p)
	  *max_size_p = seg->p_vaddr + seg->p_filesz - vma;
	return vma - seg->p_vaddr + seg->p_offset;
      }

  if (max_size_p)
    *max_size_p = 0;
  bfd_set_error (bfd_error_invalid_operation);
  return (file_ptr) -1;
}

/* Convert hash table to internal form.  */

static bfd_vma *
get_hash_table_data (bfd *abfd, bfd_size_type number,
		     unsigned int ent_size, bfd_size_type filesize)
{
  unsigned char *e_data = NULL;
  bfd_vma *i_data = NULL;
  bfd_size_type size;
  void *e_data_addr;
  size_t e_data_size ATTRIBUTE_UNUSED;

  if (ent_size != 4 && ent_size != 8)
    return NULL;

  if ((size_t) number != number)
    {
      bfd_set_error (bfd_error_file_too_big);
      return NULL;
    }

  size = ent_size * number;
  /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
     attempting to allocate memory when the read is bound to fail.  */
  if (size > filesize
      || number >= ~(size_t) 0 / ent_size
      || number >= ~(size_t) 0 / sizeof (*i_data))
    {
      bfd_set_error (bfd_error_file_too_big);
      return NULL;
    }

  e_data = _bfd_mmap_temporary (abfd, size, &e_data_addr, &e_data_size);
  if (e_data == NULL)
    return NULL;

  i_data = (bfd_vma *) bfd_malloc (number * sizeof (*i_data));
  if (i_data == NULL)
    {
      _bfd_munmap_temporary (e_data_addr, e_data_size);
      return NULL;
    }

  if (ent_size == 4)
    while (number--)
      i_data[number] = bfd_get_32 (abfd, e_data + number * ent_size);
  else
    while (number--)
      i_data[number] = bfd_get_64 (abfd, e_data + number * ent_size);

  _bfd_munmap_temporary (e_data_addr, e_data_size);
  return i_data;
}

/* Address of .MIPS.xhash section.  FIXME: What is the best way to
   support DT_MIPS_XHASH?  */
#define DT_MIPS_XHASH	       0x70000036

/* Reconstruct dynamic symbol table from PT_DYNAMIC segment.  */

bool
_bfd_elf_get_dynamic_symbols (bfd *abfd, Elf_Internal_Phdr *phdr,
			      Elf_Internal_Phdr *phdrs, size_t phnum,
			      bfd_size_type filesize)
{
  bfd_byte *extdyn, *extdynend;
  size_t extdynsize;
  void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
  bool (*swap_symbol_in) (bfd *, const void *, const void *,
			  Elf_Internal_Sym *);
  Elf_Internal_Dyn dyn;
  bfd_vma dt_hash = 0;
  bfd_vma dt_gnu_hash = 0;
  bfd_vma dt_mips_xhash = 0;
  bfd_vma dt_strtab = 0;
  bfd_vma dt_symtab = 0;
  size_t dt_strsz = 0;
  bfd_vma dt_versym = 0;
  bfd_vma dt_verdef = 0;
  bfd_vma dt_verneed = 0;
  bfd_byte *dynbuf = NULL;
  char *strbuf = NULL;
  bfd_vma *gnubuckets = NULL;
  bfd_vma *gnuchains = NULL;
  bfd_vma *mipsxlat = NULL;
  file_ptr saved_filepos, filepos;
  bool res = false;
  size_t amt;
  bfd_byte *esymbuf = NULL, *esym;
  bfd_size_type symcount;
  Elf_Internal_Sym *isymbuf = NULL;
  Elf_Internal_Sym *isym, *isymend;
  bfd_byte *versym = NULL;
  bfd_byte *verdef = NULL;
  bfd_byte *verneed = NULL;
  size_t verdef_size = 0;
  size_t verneed_size = 0;
  size_t extsym_size;
  const struct elf_backend_data *bed;
  void *dynbuf_addr = NULL;
  void *esymbuf_addr = NULL;
  size_t dynbuf_size = 0;
  size_t esymbuf_size = 0;

  /* Return TRUE if symbol table is bad.  */
  if (elf_bad_symtab (abfd))
    return true;

  /* Return TRUE if DT_HASH/DT_GNU_HASH have bee processed before.  */
  if (elf_tdata (abfd)->dt_strtab != NULL)
    return true;

  bed = get_elf_backend_data (abfd);

  /* Save file position for elf_object_p.  */
  saved_filepos = bfd_tell (abfd);

  if (bfd_seek (abfd, phdr->p_offset, SEEK_SET) != 0)
    goto error_return;

  dynbuf_size = phdr->p_filesz;
  dynbuf = _bfd_mmap_temporary (abfd, dynbuf_size, &dynbuf_addr, &dynbuf_size);
  if (dynbuf == NULL)
    goto error_return;

  extsym_size = bed->s->sizeof_sym;
  extdynsize = bed->s->sizeof_dyn;
  swap_dyn_in = bed->s->swap_dyn_in;

  extdyn = dynbuf;
  if (phdr->p_filesz < extdynsize)
    goto error_return;
  extdynend = extdyn + phdr->p_filesz;
  for (; extdyn <= (extdynend - extdynsize); extdyn += extdynsize)
    {
      swap_dyn_in (abfd, extdyn, &dyn);

      if (dyn.d_tag == DT_NULL)
	break;

      switch (dyn.d_tag)
	{
	case DT_HASH:
	  dt_hash = dyn.d_un.d_val;
	  break;
	case DT_GNU_HASH:
	  if (bed->elf_machine_code != EM_MIPS
	      && bed->elf_machine_code != EM_MIPS_RS3_LE)
	    dt_gnu_hash = dyn.d_un.d_val;
	  break;
	case DT_STRTAB:
	  dt_strtab = dyn.d_un.d_val;
	  break;
	case DT_SYMTAB:
	  dt_symtab = dyn.d_un.d_val;
	  break;
	case DT_STRSZ:
	  dt_strsz = dyn.d_un.d_val;
	  break;
	case DT_SYMENT:
	  if (dyn.d_un.d_val != extsym_size)
	    goto error_return;
	  break;
	case DT_VERSYM:
	  dt_versym = dyn.d_un.d_val;
	  break;
	case DT_VERDEF:
	  dt_verdef = dyn.d_un.d_val;
	  break;
	case DT_VERNEED:
	  dt_verneed = dyn.d_un.d_val;
	  break;
	default:
	  if (dyn.d_tag == DT_MIPS_XHASH
	      && (bed->elf_machine_code == EM_MIPS
		  || bed->elf_machine_code == EM_MIPS_RS3_LE))
	    {
	      dt_gnu_hash = dyn.d_un.d_val;
	      dt_mips_xhash = dyn.d_un.d_val;
	    }
	  break;
	}
    }

  /* Check if we can reconstruct dynamic symbol table from PT_DYNAMIC
     segment.  */
  if ((!dt_hash && !dt_gnu_hash)
      || !dt_strtab
      || !dt_symtab
      || !dt_strsz)
    goto error_return;

  /* Get dynamic string table.  */
  filepos = offset_from_vma (phdrs, phnum, dt_strtab, dt_strsz, NULL);
  if (filepos == (file_ptr) -1
      || bfd_seek (abfd, filepos, SEEK_SET) != 0)
    goto error_return;

  /* Dynamic string table must be valid until ABFD is closed.  */
  strbuf = (char *) _bfd_mmap_persistent (abfd, dt_strsz);
  if (strbuf == NULL)
    goto error_return;
  if (strbuf[dt_strsz - 1] != 0)
    {
      /* It is an error if a string table is't terminated.  */
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: DT_STRTAB table is corrupt"), abfd);
      strbuf[dt_strsz - 1] = 0;
    }

  /* Get the real symbol count from DT_HASH or DT_GNU_HASH.  Prefer
     DT_HASH since it is simpler than DT_GNU_HASH.  */
  if (dt_hash)
    {
      unsigned char nb[16];
      unsigned int hash_ent_size;

      switch (bed->elf_machine_code)
	{
	case EM_ALPHA:
	case EM_S390:
	case EM_S390_OLD:
	  if (bed->s->elfclass == ELFCLASS64)
	    {
	      hash_ent_size = 8;
	      break;
	    }
	  /* FALLTHROUGH */
	default:
	  hash_ent_size = 4;
	  break;
	}

      filepos = offset_from_vma (phdrs, phnum, dt_hash, 2 * hash_ent_size,
				 NULL);
      if (filepos == (file_ptr) -1
	  || bfd_seek (abfd, filepos, SEEK_SET) != 0
	  || bfd_read (nb, 2 * hash_ent_size, abfd) != 2 * hash_ent_size)
	goto error_return;

      /* The number of dynamic symbol table entries equals the number
	 of chains.  */
      if (hash_ent_size == 8)
	symcount = bfd_get_64 (abfd, nb + hash_ent_size);
      else
	symcount = bfd_get_32 (abfd, nb + hash_ent_size);
    }
  else
    {
      /* For DT_GNU_HASH, only defined symbols with non-STB_LOCAL
	 bindings are in hash table.  Since in dynamic symbol table,
	 all symbols with STB_LOCAL binding are placed before symbols
	 with other bindings and all undefined symbols are placed
	 before defined ones, the highest symbol index in DT_GNU_HASH
	 is the highest dynamic symbol table index.  */
      unsigned char nb[16];
      bfd_vma ngnubuckets;
      bfd_vma gnusymidx;
      size_t i, ngnuchains;
      bfd_vma maxchain = 0xffffffff, bitmaskwords;
      bfd_vma buckets_vma;

      filepos = offset_from_vma (phdrs, phnum, dt_gnu_hash,
				 sizeof (nb), NULL);
      if (filepos == (file_ptr) -1
	  || bfd_seek (abfd, filepos, SEEK_SET) != 0
	  || bfd_read (nb, sizeof (nb), abfd) != sizeof (nb))
	goto error_return;

      ngnubuckets = bfd_get_32 (abfd, nb);
      gnusymidx = bfd_get_32 (abfd, nb + 4);
      bitmaskwords = bfd_get_32 (abfd, nb + 8);
      buckets_vma = dt_gnu_hash + 16;
      if (bed->s->elfclass == ELFCLASS32)
	buckets_vma += bitmaskwords * 4;
      else
	buckets_vma += bitmaskwords * 8;
      filepos = offset_from_vma (phdrs, phnum, buckets_vma, 4, NULL);
      if (filepos == (file_ptr) -1
	  || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	goto error_return;

      gnubuckets = get_hash_table_data (abfd, ngnubuckets, 4, filesize);
      if (gnubuckets == NULL)
	goto error_return;

      for (i = 0; i < ngnubuckets; i++)
	if (gnubuckets[i] != 0)
	  {
	    if (gnubuckets[i] < gnusymidx)
	      goto error_return;

	    if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
	      maxchain = gnubuckets[i];
	  }

      if (maxchain == 0xffffffff)
	{
	  symcount = 0;
	  goto empty_gnu_hash;
	}

      maxchain -= gnusymidx;
      filepos = offset_from_vma (phdrs, phnum,
				 buckets_vma + 4 * (ngnubuckets + maxchain),
				 4, NULL);
      if (filepos == (file_ptr) -1
	  || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	goto error_return;

      do
	{
	  if (bfd_read (nb, 4, abfd) != 4)
	    goto error_return;
	  ++maxchain;
	  if (maxchain == 0)
	    goto error_return;
	}
      while ((bfd_get_32 (abfd, nb) & 1) == 0);

      filepos = offset_from_vma (phdrs, phnum,
				 buckets_vma + 4 * ngnubuckets,
				 4, NULL);
      if (filepos == (file_ptr) -1
	  || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	goto error_return;

      gnuchains = get_hash_table_data (abfd, maxchain, 4, filesize);
      if (gnuchains == NULL)
	goto error_return;
      ngnuchains = maxchain;

      if (dt_mips_xhash)
	{
	  filepos = offset_from_vma (phdrs, phnum,
				     buckets_vma + 4 * (ngnubuckets + maxchain),
				     4, NULL);
	  if (filepos == (file_ptr) -1
	      || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	    goto error_return;

	  mipsxlat = get_hash_table_data (abfd, maxchain, 4, filesize);
	  if (mipsxlat == NULL)
	    goto error_return;
	}

      symcount = 0;
      for (i = 0; i < ngnubuckets; ++i)
	if (gnubuckets[i] != 0)
	  {
	    bfd_vma si = gnubuckets[i];
	    bfd_vma off = si - gnusymidx;
	    do
	      {
		if (mipsxlat)
		  {
		    if (mipsxlat[off] >= symcount)
		      symcount = mipsxlat[off] + 1;
		  }
		else
		  {
		    if (si >= symcount)
		      symcount = si + 1;
		  }
		si++;
	      }
	    while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
	  }
    }

  /* Swap in dynamic symbol table.  */
  if (_bfd_mul_overflow (symcount, extsym_size, &amt))
    {
      bfd_set_error (bfd_error_file_too_big);
      goto error_return;
    }

  filepos = offset_from_vma (phdrs, phnum, dt_symtab, amt, NULL);
  if (filepos == (file_ptr) -1
      || bfd_seek (abfd, filepos, SEEK_SET) != 0)
    goto error_return;
  esymbuf_size = amt;
  esymbuf = _bfd_mmap_temporary (abfd, esymbuf_size,
				 &esymbuf_addr, &esymbuf_size);
  if (esymbuf == NULL)
    goto error_return;

  if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt))
    {
      bfd_set_error (bfd_error_file_too_big);
      goto error_return;
    }

  /* Dynamic symbol table must be valid until ABFD is closed.  */
  isymbuf = (Elf_Internal_Sym *) bfd_alloc (abfd, amt);
  if (isymbuf == NULL)
    goto error_return;

  swap_symbol_in = bed->s->swap_symbol_in;

  /* Convert the symbols to internal form.  */
  isymend = isymbuf + symcount;
  for (esym = esymbuf, isym = isymbuf;
       isym < isymend;
       esym += extsym_size, isym++)
    if (!swap_symbol_in (abfd, esym, NULL, isym)
	|| isym->st_name >= dt_strsz)
      {
	bfd_set_error (bfd_error_invalid_operation);
	goto error_return;
      }

  if (dt_versym)
    {
      /* Swap in DT_VERSYM.  */
      if (_bfd_mul_overflow (symcount, 2, &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  goto error_return;
	}

      filepos = offset_from_vma (phdrs, phnum, dt_versym, amt, NULL);
      if (filepos == (file_ptr) -1
	  || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	goto error_return;

      /* DT_VERSYM info must be valid until ABFD is closed.  */
      versym = _bfd_mmap_persistent (abfd, amt);

      if (dt_verdef)
	{
	  /* Read in DT_VERDEF.  */
	  filepos = offset_from_vma (phdrs, phnum, dt_verdef,
				     0, &verdef_size);
	  if (filepos == (file_ptr) -1
	      || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	    goto error_return;

	  /* DT_VERDEF info must be valid until ABFD is closed.  */
	  verdef = _bfd_mmap_persistent (abfd, verdef_size);
	}

      if (dt_verneed)
	{
	  /* Read in DT_VERNEED.  */
	  filepos = offset_from_vma (phdrs, phnum, dt_verneed,
				     0, &verneed_size);
	  if (filepos == (file_ptr) -1
	      || bfd_seek (abfd, filepos, SEEK_SET) != 0)
	    goto error_return;

	  /* DT_VERNEED info must be valid until ABFD is closed.  */
	  verneed = _bfd_mmap_persistent (abfd, verneed_size);
	}
    }

 empty_gnu_hash:
  elf_tdata (abfd)->dt_strtab = strbuf;
  elf_tdata (abfd)->dt_strsz = dt_strsz;
  elf_tdata (abfd)->dt_symtab = isymbuf;
  elf_tdata (abfd)->dt_symtab_count = symcount;
  elf_tdata (abfd)->dt_versym = versym;
  elf_tdata (abfd)->dt_verdef = verdef;
  elf_tdata (abfd)->dt_verneed = verneed;
  elf_tdata (abfd)->dt_verdef_count
    = verdef_size / sizeof (Elf_External_Verdef);
  elf_tdata (abfd)->dt_verneed_count
    = verneed_size / sizeof (Elf_External_Verneed);

  res = true;

 error_return:
  /* Restore file position for elf_object_p.  */
  if (bfd_seek (abfd, saved_filepos, SEEK_SET) != 0)
    res = false;
  _bfd_munmap_temporary (dynbuf_addr, dynbuf_size);
  _bfd_munmap_temporary (esymbuf_addr, esymbuf_size);
  free (gnubuckets);
  free (gnuchains);
  free (mipsxlat);
  return res;
}

/* Reconstruct section from dynamic symbol.  */

asection *
_bfd_elf_get_section_from_dynamic_symbol (bfd *abfd,
					  Elf_Internal_Sym *isym)
{
  asection *sec;
  flagword flags;

  if (!elf_use_dt_symtab_p (abfd))
    return NULL;

  flags = SEC_ALLOC | SEC_LOAD;
  switch (ELF_ST_TYPE (isym->st_info))
    {
    case STT_FUNC:
    case STT_GNU_IFUNC:
      sec = bfd_get_section_by_name (abfd, ".text");
      if (sec == NULL)
	sec = bfd_make_section_with_flags (abfd,
					   ".text",
					   flags | SEC_CODE);
      break;
    case STT_COMMON:
      sec = bfd_com_section_ptr;
      break;
    case STT_OBJECT:
      sec = bfd_get_section_by_name (abfd, ".data");
      if (sec == NULL)
	sec = bfd_make_section_with_flags (abfd,
					   ".data",
					   flags | SEC_DATA);
      break;
    case STT_TLS:
      sec = bfd_get_section_by_name (abfd, ".tdata");
      if (sec == NULL)
	sec = bfd_make_section_with_flags (abfd,
					   ".tdata",
					   (flags
					    | SEC_DATA
					    | SEC_THREAD_LOCAL));
      break;
    default:
      sec = bfd_abs_section_ptr;
      break;
    }

  return sec;
}

/* Get version name.  If BASE_P is TRUE, return "Base" for VER_FLG_BASE
   and return symbol version for symbol version itself.   */

const char *
_bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
				    bool base_p,
				    bool *hidden)
{
  const char *version_string = NULL;
  if ((elf_dynversym (abfd) != 0
       && (elf_dynverdef (abfd) != 0 || elf_dynverref (abfd) != 0))
      || (elf_tdata (abfd)->dt_versym != NULL
	  && (elf_tdata (abfd)->dt_verdef != NULL
	      || elf_tdata (abfd)->dt_verneed != NULL)))
    {
      unsigned int vernum = ((elf_symbol_type *) symbol)->version;

      *hidden = (vernum & VERSYM_HIDDEN) != 0;
      vernum &= VERSYM_VERSION;

      if (vernum == 0)
	version_string = "";
      else if (vernum == 1
	       && (vernum > elf_tdata (abfd)->cverdefs
		   || (elf_tdata (abfd)->verdef[0].vd_flags
		       == VER_FLG_BASE)))
	version_string = base_p ? "Base" : "";
      else if (vernum <= elf_tdata (abfd)->cverdefs)
	{
	  const char *nodename
	    = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
	  version_string = "";
	  if (base_p
	      || nodename == NULL
	      || symbol->name == NULL
	      || ! streq (symbol->name, nodename))
	    version_string = nodename;
	}
      else
	{
	  Elf_Internal_Verneed *t;

	  version_string = _("<corrupt>");
	  for (t = elf_tdata (abfd)->verref;
	       t != NULL;
	       t = t->vn_nextref)
	    {
	      Elf_Internal_Vernaux *a;

	      for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
		{
		  if (a->vna_other == vernum)
		    {
		      *hidden = true;
		      version_string = a->vna_nodename;
		      break;
		    }
		}
	    }
	}
    }
  return version_string;
}

/* Display ELF-specific fields of a symbol.  */

void
_bfd_elf_print_symbol (bfd *abfd,
		       void *filep,
		       asymbol *symbol,
		       bfd_print_symbol_type how)
{
  FILE *file = (FILE *) filep;
  const char *symname = (symbol->name != bfd_symbol_error_name
			 ? symbol->name : _("<corrupt>"));

  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symname);
      break;
    case bfd_print_symbol_more:
      fprintf (file, "elf ");
      bfd_fprintf_vma (abfd, file, symbol->value);
      fprintf (file, " %x", symbol->flags);
      break;
    case bfd_print_symbol_all:
      {
	const char *section_name;
	const char *name = NULL;
	const struct elf_backend_data *bed;
	unsigned char st_other;
	bfd_vma val;
	const char *version_string;
	bool hidden;

	section_name = symbol->section ? symbol->section->name : "(*none*)";

	bed = get_elf_backend_data (abfd);
	if (bed->elf_backend_print_symbol_all)
	  name = (*bed->elf_backend_print_symbol_all) (abfd, filep, symbol);

	if (name != NULL)
	  symname = name;
	else
	  bfd_print_symbol_vandf (abfd, file, symbol);

	fprintf (file, " %s\t", section_name);
	/* Print the "other" value for a symbol.  For common symbols,
	   we've already printed the size; now print the alignment.
	   For other symbols, we have no specified alignment, and
	   we've printed the address; now print the size.  */
	if (symbol->section && bfd_is_com_section (symbol->section))
	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_value;
	else
	  val = ((elf_symbol_type *) symbol)->internal_elf_sym.st_size;
	bfd_fprintf_vma (abfd, file, val);

	/* If we have version information, print it.  */
	version_string = _bfd_elf_get_symbol_version_string (abfd,
							     symbol,
							     true,
							     &hidden);
	if (version_string)
	  {
	    if (!hidden)
	      fprintf (file, "  %-11s", version_string);
	    else
	      {
		int i;

		fprintf (file, " (%s)", version_string);
		for (i = 10 - strlen (version_string); i > 0; --i)
		  putc (' ', file);
	      }
	  }

	/* If the st_other field is not zero, print it.  */
	st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;

	switch (st_other)
	  {
	  case 0: break;
	  case STV_INTERNAL:  fprintf (file, " .internal");  break;
	  case STV_HIDDEN:    fprintf (file, " .hidden");    break;
	  case STV_PROTECTED: fprintf (file, " .protected"); break;
	  default:
	    /* Some other non-defined flags are also present, so print
	       everything hex.  */
	    fprintf (file, " 0x%02x", (unsigned int) st_other);
	  }

	fprintf (file, " %s", symname);
      }
      break;
    }
}

/* ELF .o/exec file reading */

/* Create a new bfd section from an ELF section header.  */

bool
bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
{
  Elf_Internal_Shdr *hdr;
  Elf_Internal_Ehdr *ehdr;
  const struct elf_backend_data *bed;
  const char *name;
  bool ret = true;

  if (shindex >= elf_numsections (abfd))
    return false;

  /* PR17512: A corrupt ELF binary might contain a loop of sections via
     sh_link or sh_info.  Detect this here, by refusing to load a
     section that we are already in the process of loading.  */
  if (elf_tdata (abfd)->being_created[shindex])
    {
      _bfd_error_handler
	(_("%pB: warning: loop in section dependencies detected"), abfd);
      return false;
    }
  elf_tdata (abfd)->being_created[shindex] = true;

  hdr = elf_elfsections (abfd)[shindex];
  ehdr = elf_elfheader (abfd);
  name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
					  hdr->sh_name);
  if (name == NULL)
    goto fail;

  bed = get_elf_backend_data (abfd);
  switch (hdr->sh_type)
    {
    case SHT_NULL:
      /* Inactive section. Throw it away.  */
      goto success;

    case SHT_PROGBITS:		/* Normal section with contents.  */
    case SHT_NOBITS:		/* .bss section.  */
    case SHT_HASH:		/* .hash section.  */
    case SHT_NOTE:		/* .note section.  */
    case SHT_INIT_ARRAY:	/* .init_array section.  */
    case SHT_FINI_ARRAY:	/* .fini_array section.  */
    case SHT_PREINIT_ARRAY:	/* .preinit_array section.  */
    case SHT_GNU_LIBLIST:	/* .gnu.liblist section.  */
    case SHT_GNU_HASH:		/* .gnu.hash section.  */
    case SHT_GNU_SFRAME:	/* .sframe section.  */
      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      goto success;

    case SHT_DYNAMIC:	/* Dynamic linking information.  */
      if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
	goto fail;

      if (hdr->sh_link > elf_numsections (abfd))
	{
	  /* PR 10478: Accept Solaris binaries with a sh_link field
	     set to SHN_BEFORE (LORESERVE) or SHN_AFTER (LORESERVE+1).  */
	  switch (bfd_get_arch (abfd))
	    {
	    case bfd_arch_i386:
	    case bfd_arch_sparc:
	      if (hdr->sh_link == (SHN_LORESERVE & 0xffff)
		  || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff))
		break;
	      /* Otherwise fall through.  */
	    default:
	      goto fail;
	    }
	}
      else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
	goto fail;
      else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
	{
	  Elf_Internal_Shdr *dynsymhdr;

	  /* The shared libraries distributed with hpux11 have a bogus
	     sh_link field for the ".dynamic" section.  Find the
	     string table for the ".dynsym" section instead.  */
	  if (elf_dynsymtab (abfd) != 0)
	    {
	      dynsymhdr = elf_elfsections (abfd)[elf_dynsymtab (abfd)];
	      hdr->sh_link = dynsymhdr->sh_link;
	    }
	  else
	    {
	      unsigned int i, num_sec;

	      num_sec = elf_numsections (abfd);
	      for (i = 1; i < num_sec; i++)
		{
		  dynsymhdr = elf_elfsections (abfd)[i];
		  if (dynsymhdr->sh_type == SHT_DYNSYM)
		    {
		      hdr->sh_link = dynsymhdr->sh_link;
		      break;
		    }
		}
	    }
	}
      goto success;

    case SHT_SYMTAB:		/* A symbol table.  */
      if (elf_onesymtab (abfd) == shindex)
	goto success;

      if (hdr->sh_entsize != bed->s->sizeof_sym)
	goto fail;

      if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
	{
	  if (hdr->sh_size != 0)
	    goto fail;
	  /* Some assemblers erroneously set sh_info to one with a
	     zero sh_size.  ld sees this as a global symbol count
	     of (unsigned) -1.  Fix it here.  */
	  hdr->sh_info = 0;
	  goto success;
	}

      /* PR 18854: A binary might contain more than one symbol table.
	 Unusual, but possible.  Warn, but continue.  */
      if (elf_onesymtab (abfd) != 0)
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: warning: multiple symbol tables detected"
	       " - ignoring the table in section %u"),
	     abfd, shindex);
	  goto success;
	}
      elf_onesymtab (abfd) = shindex;
      elf_symtab_hdr (abfd) = *hdr;
      elf_elfsections (abfd)[shindex] = hdr = & elf_symtab_hdr (abfd);
      abfd->flags |= HAS_SYMS;

      /* Sometimes a shared object will map in the symbol table.  If
	 SHF_ALLOC is set, and this is a shared object, then we also
	 treat this section as a BFD section.  We can not base the
	 decision purely on SHF_ALLOC, because that flag is sometimes
	 set in a relocatable object file, which would confuse the
	 linker.  */
      if ((hdr->sh_flags & SHF_ALLOC) != 0
	  && (abfd->flags & DYNAMIC) != 0
	  && ! _bfd_elf_make_section_from_shdr (abfd, hdr, name,
						shindex))
	goto fail;

      /* Go looking for SHT_SYMTAB_SHNDX too, since if there is one we
	 can't read symbols without that section loaded as well.  It
	 is most likely specified by the next section header.  */
      {
	elf_section_list * entry;
	unsigned int i, num_sec;

	for (entry = elf_symtab_shndx_list (abfd); entry; entry = entry->next)
	  if (entry->hdr.sh_link == shindex)
	    goto success;

	num_sec = elf_numsections (abfd);
	for (i = shindex + 1; i < num_sec; i++)
	  {
	    Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];

	    if (hdr2->sh_type == SHT_SYMTAB_SHNDX
		&& hdr2->sh_link == shindex)
	      break;
	  }

	if (i == num_sec)
	  for (i = 1; i < shindex; i++)
	    {
	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];

	      if (hdr2->sh_type == SHT_SYMTAB_SHNDX
		  && hdr2->sh_link == shindex)
		break;
	    }

	if (i != shindex)
	  ret = bfd_section_from_shdr (abfd, i);
	/* else FIXME: we have failed to find the symbol table.
	   Should we issue an error?  */
	goto success;
      }

    case SHT_DYNSYM:		/* A dynamic symbol table.  */
      if (elf_dynsymtab (abfd) == shindex)
	goto success;

      if (hdr->sh_entsize != bed->s->sizeof_sym)
	goto fail;

      if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
	{
	  if (hdr->sh_size != 0)
	    goto fail;

	  /* Some linkers erroneously set sh_info to one with a
	     zero sh_size.  ld sees this as a global symbol count
	     of (unsigned) -1.  Fix it here.  */
	  hdr->sh_info = 0;
	  goto success;
	}

      /* PR 18854: A binary might contain more than one dynamic symbol table.
	 Unusual, but possible.  Warn, but continue.  */
      if (elf_dynsymtab (abfd) != 0)
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: warning: multiple dynamic symbol tables detected"
	       " - ignoring the table in section %u"),
	     abfd, shindex);
	  goto success;
	}
      elf_dynsymtab (abfd) = shindex;
      elf_tdata (abfd)->dynsymtab_hdr = *hdr;
      elf_elfsections (abfd)[shindex] = hdr = &elf_tdata (abfd)->dynsymtab_hdr;
      abfd->flags |= HAS_SYMS;

      /* Besides being a symbol table, we also treat this as a regular
	 section, so that objcopy can handle it.  */
      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      goto success;

    case SHT_SYMTAB_SHNDX: /* Symbol section indices when >64k sections.  */
      {
	elf_section_list * entry;

	for (entry = elf_symtab_shndx_list (abfd); entry; entry = entry->next)
	  if (entry->ndx == shindex)
	    goto success;

	entry = bfd_alloc (abfd, sizeof (*entry));
	if (entry == NULL)
	  goto fail;
	entry->ndx = shindex;
	entry->hdr = * hdr;
	entry->next = elf_symtab_shndx_list (abfd);
	elf_symtab_shndx_list (abfd) = entry;
	elf_elfsections (abfd)[shindex] = & entry->hdr;
	goto success;
      }

    case SHT_STRTAB:		/* A string table.  */
      if (hdr->bfd_section != NULL)
	goto success;

      if (ehdr->e_shstrndx == shindex)
	{
	  elf_tdata (abfd)->shstrtab_hdr = *hdr;
	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->shstrtab_hdr;
	  goto success;
	}

      if (elf_elfsections (abfd)[elf_onesymtab (abfd)]->sh_link == shindex)
	{
	symtab_strtab:
	  elf_tdata (abfd)->strtab_hdr = *hdr;
	  elf_elfsections (abfd)[shindex] = &elf_tdata (abfd)->strtab_hdr;
	  goto success;
	}

      if (elf_elfsections (abfd)[elf_dynsymtab (abfd)]->sh_link == shindex)
	{
	dynsymtab_strtab:
	  elf_tdata (abfd)->dynstrtab_hdr = *hdr;
	  hdr = &elf_tdata (abfd)->dynstrtab_hdr;
	  elf_elfsections (abfd)[shindex] = hdr;
	  /* We also treat this as a regular section, so that objcopy
	     can handle it.  */
	  ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name,
						 shindex);
	  goto success;
	}

      /* If the string table isn't one of the above, then treat it as a
	 regular section.  We need to scan all the headers to be sure,
	 just in case this strtab section appeared before the above.  */
      if (elf_onesymtab (abfd) == 0 || elf_dynsymtab (abfd) == 0)
	{
	  unsigned int i, num_sec;

	  num_sec = elf_numsections (abfd);
	  for (i = 1; i < num_sec; i++)
	    {
	      Elf_Internal_Shdr *hdr2 = elf_elfsections (abfd)[i];
	      if (hdr2->sh_link == shindex)
		{
		  /* Prevent endless recursion on broken objects.  */
		  if (i == shindex)
		    goto fail;
		  if (! bfd_section_from_shdr (abfd, i))
		    goto fail;
		  if (elf_onesymtab (abfd) == i)
		    goto symtab_strtab;
		  if (elf_dynsymtab (abfd) == i)
		    goto dynsymtab_strtab;
		}
	    }
	}
      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      goto success;

    case SHT_REL:
    case SHT_RELA:
    case SHT_RELR:
      /* *These* do a lot of work -- but build no sections!  */
      {
	asection *target_sect;
	Elf_Internal_Shdr *hdr2, **p_hdr;
	unsigned int num_sec = elf_numsections (abfd);
	struct bfd_elf_section_data *esdt;
	bfd_size_type size;

	if (hdr->sh_type == SHT_REL)
	  size = bed->s->sizeof_rel;
	else if (hdr->sh_type == SHT_RELA)
	  size = bed->s->sizeof_rela;
	else
	  size = bed->s->arch_size / 8;
	if (hdr->sh_entsize != size)
	  goto fail;

	/* Check for a bogus link to avoid crashing.  */
	if (hdr->sh_link >= num_sec)
	  {
	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: invalid link %u for reloc section %s (index %u)"),
	       abfd, hdr->sh_link, name, shindex);
	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
	    goto success;
	  }

	/* Get the symbol table.  */
	if ((elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_SYMTAB
	     || elf_elfsections (abfd)[hdr->sh_link]->sh_type == SHT_DYNSYM)
	    && ! bfd_section_from_shdr (abfd, hdr->sh_link))
	  goto fail;

	/* If this is an alloc section in an executable or shared
	   library, or the reloc section does not use the main symbol
	   table we don't treat it as a reloc section.  BFD can't
	   adequately represent such a section, so at least for now,
	   we don't try.  We just present it as a normal section.  We
	   also can't use it as a reloc section if it points to the
	   null section, an invalid section, another reloc section, or
	   its sh_link points to the null section.  */
	if (((abfd->flags & (DYNAMIC | EXEC_P)) != 0
	     && (hdr->sh_flags & SHF_ALLOC) != 0)
	    || (hdr->sh_flags & SHF_COMPRESSED) != 0
	    || hdr->sh_type == SHT_RELR
	    || hdr->sh_link == SHN_UNDEF
	    || hdr->sh_link != elf_onesymtab (abfd)
	    || hdr->sh_info == SHN_UNDEF
	    || hdr->sh_info >= num_sec
	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
	    || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
	  {
	    ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
	    goto success;
	  }

	if (! bfd_section_from_shdr (abfd, hdr->sh_info))
	  goto fail;

	target_sect = bfd_section_from_elf_index (abfd, hdr->sh_info);
	if (target_sect == NULL)
	  goto fail;

	esdt = elf_section_data (target_sect);
	if (hdr->sh_type == SHT_RELA)
	  p_hdr = &esdt->rela.hdr;
	else
	  p_hdr = &esdt->rel.hdr;

	/* PR 17512: file: 0b4f81b7.
	   Also see PR 24456, for a file which deliberately has two reloc
	   sections.  */
	if (*p_hdr != NULL)
	  {
	    if (!bed->init_secondary_reloc_section (abfd, hdr, name, shindex))
	      {
		_bfd_error_handler
		  /* xgettext:c-format */
		  (_("%pB: warning: secondary relocation section '%s' "
		     "for section %pA found - ignoring"),
		   abfd, name, target_sect);
	      }
	    else
	      esdt->has_secondary_relocs = true;
	    goto success;
	  }

	hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
	if (hdr2 == NULL)
	  goto fail;
	*hdr2 = *hdr;
	*p_hdr = hdr2;
	elf_elfsections (abfd)[shindex] = hdr2;
	target_sect->reloc_count += (NUM_SHDR_ENTRIES (hdr)
				     * bed->s->int_rels_per_ext_rel);
	target_sect->flags |= SEC_RELOC;
	target_sect->relocation = NULL;
	target_sect->rel_filepos = hdr->sh_offset;
	/* In the section to which the relocations apply, mark whether
	   its relocations are of the REL or RELA variety.  */
	if (hdr->sh_size != 0)
	  {
	    if (hdr->sh_type == SHT_RELA)
	      target_sect->use_rela_p = 1;
	  }
	abfd->flags |= HAS_RELOC;
	goto success;
      }

    case SHT_GNU_verdef:
      if (hdr->sh_info != 0)
	elf_dynverdef (abfd) = shindex;
      elf_tdata (abfd)->dynverdef_hdr = *hdr;
      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      goto success;

    case SHT_GNU_versym:
      if (hdr->sh_entsize != sizeof (Elf_External_Versym))
	goto fail;

      elf_dynversym (abfd) = shindex;
      elf_tdata (abfd)->dynversym_hdr = *hdr;
      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      goto success;

    case SHT_GNU_verneed:
      if (hdr->sh_info != 0)
	elf_dynverref (abfd) = shindex;
      elf_tdata (abfd)->dynverref_hdr = *hdr;
      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
      goto success;

    case SHT_SHLIB:
      goto success;

    case SHT_GROUP:
      if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
	goto fail;

      goto success;

    default:
      /* Possibly an attributes section.  */
      if (get_elf_backend_data (abfd)->target_os != is_solaris
	  /* PR 33153: Solaris defines SHT_SUNW_cap which collides with SHT_GNU_ATTRIBUTES.  */
	  && (hdr->sh_type == SHT_GNU_ATTRIBUTES
	      || hdr->sh_type == bed->obj_attrs_section_type))
	{
	  if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
	    goto fail;
	  _bfd_elf_parse_attributes (abfd, hdr);
	  goto success;
	}

      /* Check for any processor-specific section types.  */
      if (bed->elf_backend_section_from_shdr (abfd, hdr, name, shindex))
	goto success;

      if (hdr->sh_type >= SHT_LOUSER && hdr->sh_type <= SHT_HIUSER)
	{
	  if ((hdr->sh_flags & SHF_ALLOC) != 0)
	    /* FIXME: How to properly handle allocated section reserved
	       for applications?  */
	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: unknown type [%#x] section `%s'"),
	       abfd, hdr->sh_type, name);
	  else
	    {
	      /* Allow sections reserved for applications.  */
	      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
	      goto success;
	    }
	}
      else if (hdr->sh_type >= SHT_LOPROC
	       && hdr->sh_type <= SHT_HIPROC)
	/* FIXME: We should handle this section.  */
	_bfd_error_handler
	  /* xgettext:c-format */
	  (_("%pB: unknown type [%#x] section `%s'"),
	   abfd, hdr->sh_type, name);
      else if (hdr->sh_type >= SHT_LOOS && hdr->sh_type <= SHT_HIOS)
	{
	  /* Unrecognised OS-specific sections.  */
	  if ((hdr->sh_flags & SHF_OS_NONCONFORMING) != 0)
	    /* SHF_OS_NONCONFORMING indicates that special knowledge is
	       required to correctly process the section and the file should
	       be rejected with an error message.  */
	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: unknown type [%#x] section `%s'"),
	       abfd, hdr->sh_type, name);
	  else
	    {
	      /* Otherwise it should be processed.  */
	      ret = _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
	      goto success;
	    }
	}
      else
	/* FIXME: We should handle this section.  */
	_bfd_error_handler
	  /* xgettext:c-format */
	  (_("%pB: unknown type [%#x] section `%s'"),
	   abfd, hdr->sh_type, name);

      goto fail;
    }

 fail:
  ret = false;
 success:
  elf_tdata (abfd)->being_created[shindex] = false;
  return ret;
}

/* Return the local symbol specified by ABFD, R_SYMNDX.  */

Elf_Internal_Sym *
bfd_sym_from_r_symndx (struct sym_cache *cache,
		       bfd *abfd,
		       unsigned long r_symndx)
{
  unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;

  if (cache->abfd != abfd || cache->indx[ent] != r_symndx)
    {
      Elf_Internal_Shdr *symtab_hdr;
      unsigned char esym[sizeof (Elf64_External_Sym)];
      Elf_External_Sym_Shndx eshndx;

      symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
      if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
				&cache->sym[ent], esym, &eshndx) == NULL)
	return NULL;

      if (cache->abfd != abfd)
	{
	  memset (cache->indx, -1, sizeof (cache->indx));
	  cache->abfd = abfd;
	}
      cache->indx[ent] = r_symndx;
    }

  return &cache->sym[ent];
}

/* Given an ELF section number, retrieve the corresponding BFD
   section.  */

asection *
bfd_section_from_elf_index (bfd *abfd, unsigned int sec_index)
{
  if (sec_index >= elf_numsections (abfd))
    return NULL;
  return elf_elfsections (abfd)[sec_index]->bfd_section;
}

static const struct bfd_elf_special_section special_sections_b[] =
{
  { STRING_COMMA_LEN (".bss"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
  { NULL,		    0,	0, 0,		 0 }
};

static const struct bfd_elf_special_section special_sections_c[] =
{
  { STRING_COMMA_LEN (".comment"), 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".ctf"),	0, SHT_PROGBITS,    0 },
  { NULL,			0, 0, 0,	    0 }
};

static const struct bfd_elf_special_section special_sections_d[] =
{
  { STRING_COMMA_LEN (".data"),		-2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".data1"),	 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
  /* There are more DWARF sections than these, but they needn't be added here
     unless you have to cope with broken compilers that don't emit section
     attributes or you want to help the user writing assembler.  */
  { STRING_COMMA_LEN (".debug"),	 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".debug_line"),	 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".debug_info"),	 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".debug_abbrev"),	 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".debug_aranges"), 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".dynamic"),	 0, SHT_DYNAMIC,  SHF_ALLOC },
  { STRING_COMMA_LEN (".dynstr"),	 0, SHT_STRTAB,	  SHF_ALLOC },
  { STRING_COMMA_LEN (".dynsym"),	 0, SHT_DYNSYM,	  SHF_ALLOC },
  { NULL,		       0,	 0, 0,		  0 }
};

static const struct bfd_elf_special_section special_sections_f[] =
{
  { STRING_COMMA_LEN (".fini"),	       0, SHT_PROGBITS,	  SHF_ALLOC + SHF_EXECINSTR },
  { STRING_COMMA_LEN (".fini_array"), -2, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
  { NULL,			   0 , 0, 0,		  0 }
};

static const struct bfd_elf_special_section special_sections_g[] =
{
  { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".gnu.linkonce.n"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".gnu.linkonce.p"), -2, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".gnu.lto_"),	  -1, SHT_PROGBITS,    SHF_EXCLUDE },
  { STRING_COMMA_LEN (".got"),		   0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".gnu_object_only"), 0, SHT_GNU_OBJECT_ONLY, SHF_EXCLUDE },
  { STRING_COMMA_LEN (".gnu.version"),	   0, SHT_GNU_versym,  0 },
  { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
  { STRING_COMMA_LEN (".gnu.version_r"),   0, SHT_GNU_verneed, 0 },
  { STRING_COMMA_LEN (".gnu.liblist"),	   0, SHT_GNU_LIBLIST, SHF_ALLOC },
  { STRING_COMMA_LEN (".gnu.conflict"),	   0, SHT_RELA,	       SHF_ALLOC },
  { STRING_COMMA_LEN (".gnu.hash"),	   0, SHT_GNU_HASH,    SHF_ALLOC },
  { NULL,			 0,	   0, 0,	       0 }
};

static const struct bfd_elf_special_section special_sections_h[] =
{
  { STRING_COMMA_LEN (".hash"), 0, SHT_HASH,	 SHF_ALLOC },
  { NULL,		     0, 0, 0,		 0 }
};

static const struct bfd_elf_special_section special_sections_i[] =
{
  { STRING_COMMA_LEN (".init"),	       0, SHT_PROGBITS,	  SHF_ALLOC + SHF_EXECINSTR },
  { STRING_COMMA_LEN (".init_array"), -2, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".interp"),      0, SHT_PROGBITS,	  0 },
  { NULL,		       0,      0, 0,		  0 }
};

static const struct bfd_elf_special_section special_sections_l[] =
{
  { STRING_COMMA_LEN (".line"), 0, SHT_PROGBITS, 0 },
  { NULL,		     0, 0, 0,		 0 }
};

static const struct bfd_elf_special_section special_sections_n[] =
{
  { STRING_COMMA_LEN (".noinit"),	 -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".note"),		 -1, SHT_NOTE,	   0 },
  { NULL,		     0,		  0, 0,		   0 }
};

static const struct bfd_elf_special_section special_sections_p[] =
{
  { STRING_COMMA_LEN (".persistent.bss"), 0, SHT_NOBITS,	SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".persistent"),	 -2, SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".preinit_array"), -2, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
  { STRING_COMMA_LEN (".plt"),		  0, SHT_PROGBITS,	SHF_ALLOC + SHF_EXECINSTR },
  { NULL,		    0,		  0, 0,			0 }
};

static const struct bfd_elf_special_section special_sections_r[] =
{
  { STRING_COMMA_LEN (".rodata"), -2, SHT_PROGBITS, SHF_ALLOC },
  { STRING_COMMA_LEN (".rodata1"), 0, SHT_PROGBITS, SHF_ALLOC },
  { STRING_COMMA_LEN (".relr.dyn"), 0, SHT_RELR, SHF_ALLOC },
  { STRING_COMMA_LEN (".rela"),	  -1, SHT_RELA,	    0 },
  /* .relro_padding is generated by lld.  It should not be confused with a
     reloc containing section, because otherwise elf_fake_sections() will
     set the entsize to 8, which may not be an actual multiple of the
     section's size.
     Note - this entry must appear before the ".rel" entry below.  */
  { STRING_COMMA_LEN (".relro_padding"), 0, SHT_NOBITS, SHF_ALLOC | SHF_WRITE },
  { STRING_COMMA_LEN (".rel"),	  -1, SHT_REL,	    0 },
  { NULL,		    0,	   0, 0,	    0 }
};

static const struct bfd_elf_special_section special_sections_s[] =
{
  { STRING_COMMA_LEN (".shstrtab"), 0, SHT_STRTAB, 0 },
  { STRING_COMMA_LEN (".strtab"),   0, SHT_STRTAB, 0 },
  { STRING_COMMA_LEN (".symtab"),   0, SHT_SYMTAB, 0 },
  /* See struct bfd_elf_special_section declaration for the semantics of
     this special case where .prefix_length != strlen (.prefix).  */
  { ".stabstr",			5,  3, SHT_STRTAB, 0 },
  { NULL,			0,  0, 0,	   0 }
};

static const struct bfd_elf_special_section special_sections_t[] =
{
  { STRING_COMMA_LEN (".text"),	 -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
  { STRING_COMMA_LEN (".tbss"),	 -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
  { STRING_COMMA_LEN (".tdata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
  { NULL,		      0,  0, 0,		   0 }
};

static const struct bfd_elf_special_section special_sections_z[] =
{
  { STRING_COMMA_LEN (".zdebug_line"),	  0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".zdebug_info"),	  0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".zdebug_abbrev"),  0, SHT_PROGBITS, 0 },
  { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
  { NULL,		      0,  0, 0,		   0 }
};

static const struct bfd_elf_special_section * const special_sections[] =
{
  special_sections_b,		/* 'b' */
  special_sections_c,		/* 'c' */
  special_sections_d,		/* 'd' */
  NULL,				/* 'e' */
  special_sections_f,		/* 'f' */
  special_sections_g,		/* 'g' */
  special_sections_h,		/* 'h' */
  special_sections_i,		/* 'i' */
  NULL,				/* 'j' */
  NULL,				/* 'k' */
  special_sections_l,		/* 'l' */
  NULL,				/* 'm' */
  special_sections_n,		/* 'n' */
  NULL,				/* 'o' */
  special_sections_p,		/* 'p' */
  NULL,				/* 'q' */
  special_sections_r,		/* 'r' */
  special_sections_s,		/* 's' */
  special_sections_t,		/* 't' */
  NULL,				/* 'u' */
  NULL,				/* 'v' */
  NULL,				/* 'w' */
  NULL,				/* 'x' */
  NULL,				/* 'y' */
  special_sections_z		/* 'z' */
};

const struct bfd_elf_special_section *
_bfd_elf_get_special_section (const char *name,
			      const struct bfd_elf_special_section *spec,
			      unsigned int rela)
{
  int i;
  int len;

  len = strlen (name);

  for (i = 0; spec[i].prefix != NULL; i++)
    {
      int suffix_len;
      int prefix_len = spec[i].prefix_length;

      if (len < prefix_len)
	continue;
      if (memcmp (name, spec[i].prefix, prefix_len) != 0)
	continue;

      suffix_len = spec[i].suffix_length;
      if (suffix_len <= 0)
	{
	  if (name[prefix_len] != 0)
	    {
	      if (suffix_len == 0)
		continue;
	      if (name[prefix_len] != '.'
		  && (suffix_len == -2
		      || (rela && spec[i].type == SHT_REL)))
		continue;
	    }
	}
      else
	{
	  if (len < prefix_len + suffix_len)
	    continue;
	  if (memcmp (name + len - suffix_len,
		      spec[i].prefix + prefix_len,
		      suffix_len) != 0)
	    continue;
	}
      return &spec[i];
    }

  return NULL;
}

const struct bfd_elf_special_section *
_bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
{
  int i;
  const struct bfd_elf_special_section *spec;
  const struct elf_backend_data *bed;

  /* See if this is one of the special sections.  */
  if (sec->name == NULL)
    return NULL;

  bed = get_elf_backend_data (abfd);
  spec = bed->special_sections;
  if (spec)
    {
      spec = _bfd_elf_get_special_section (sec->name,
					   bed->special_sections,
					   sec->use_rela_p);
      if (spec != NULL)
	return spec;
    }

  if (sec->name[0] != '.')
    return NULL;

  i = sec->name[1] - 'b';
  if (i < 0 || i > 'z' - 'b')
    return NULL;

  spec = special_sections[i];

  if (spec == NULL)
    return NULL;

  return _bfd_elf_get_special_section (sec->name, spec, sec->use_rela_p);
}

bool
_bfd_elf_new_section_hook (bfd *abfd, asection *sec)
{
  struct bfd_elf_section_data *sdata;
  const struct elf_backend_data *bed;
  const struct bfd_elf_special_section *ssect;

  sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
  if (sdata == NULL)
    {
      sdata = (struct bfd_elf_section_data *) bfd_zalloc (abfd,
							  sizeof (*sdata));
      if (sdata == NULL)
	return false;
      sec->used_by_bfd = sdata;
    }

  /* Indicate whether or not this section should use RELA relocations.  */
  bed = get_elf_backend_data (abfd);
  sec->use_rela_p = bed->default_use_rela_p;

  /* Set up ELF section type and flags for newly created sections, if
     there is an ABI mandated section.  */
  ssect = (*bed->get_sec_type_attr) (abfd, sec);
  if (ssect != NULL)
    {
      elf_section_type (sec) = ssect->type;
      elf_section_flags (sec) = ssect->attr;
    }

  return _bfd_generic_new_section_hook (abfd, sec);
}

/* Create a new bfd section from an ELF program header.

   Since program segments have no names, we generate a synthetic name
   of the form segment<NUM>, where NUM is generally the index in the
   program header table.  For segments that are split (see below) we
   generate the names segment<NUM>a and segment<NUM>b.

   Note that some program segments may have a file size that is different than
   (less than) the memory size.  All this means is that at execution the
   system must allocate the amount of memory specified by the memory size,
   but only initialize it with the first "file size" bytes read from the
   file.  This would occur for example, with program segments consisting
   of combined data+bss.

   To handle the above situation, this routine generates TWO bfd sections
   for the single program segment.  The first has the length specified by
   the file size of the segment, and the second has the length specified
   by the difference between the two sizes.  In effect, the segment is split
   into its initialized and uninitialized parts.  */

bool
_bfd_elf_make_section_from_phdr (bfd *abfd,
				 Elf_Internal_Phdr *hdr,
				 int hdr_index,
				 const char *type_name)
{
  asection *newsect;
  char *name;
  char namebuf[64];
  size_t len;
  int split;
  unsigned int opb = bfd_octets_per_byte (abfd, NULL);

  split = ((hdr->p_memsz > 0)
	    && (hdr->p_filesz > 0)
	    && (hdr->p_memsz > hdr->p_filesz));

  if (hdr->p_filesz > 0)
    {
      sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "a" : "");
      len = strlen (namebuf) + 1;
      name = (char *) bfd_alloc (abfd, len);
      if (!name)
	return false;
      memcpy (name, namebuf, len);
      newsect = bfd_make_section (abfd, name);
      if (newsect == NULL)
	return false;
      newsect->vma = hdr->p_vaddr / opb;
      newsect->lma = hdr->p_paddr / opb;
      newsect->size = hdr->p_filesz;
      newsect->filepos = hdr->p_offset;
      newsect->flags |= SEC_HAS_CONTENTS;
      newsect->alignment_power = bfd_log2 (hdr->p_align);
      if (hdr->p_type == PT_LOAD)
	{
	  newsect->flags |= SEC_ALLOC;
	  newsect->flags |= SEC_LOAD;
	  if (hdr->p_flags & PF_X)
	    {
	      /* FIXME: all we known is that it has execute PERMISSION,
		 may be data.  */
	      newsect->flags |= SEC_CODE;
	    }
	}
      if (!(hdr->p_flags & PF_W))
	{
	  newsect->flags |= SEC_READONLY;
	}
    }

  if (hdr->p_memsz > hdr->p_filesz)
    {
      bfd_vma align;

      sprintf (namebuf, "%s%d%s", type_name, hdr_index, split ? "b" : "");
      len = strlen (namebuf) + 1;
      name = (char *) bfd_alloc (abfd, len);
      if (!name)
	return false;
      memcpy (name, namebuf, len);
      newsect = bfd_make_section (abfd, name);
      if (newsect == NULL)
	return false;
      newsect->vma = (hdr->p_vaddr + hdr->p_filesz) / opb;
      newsect->lma = (hdr->p_paddr + hdr->p_filesz) / opb;
      newsect->size = hdr->p_memsz - hdr->p_filesz;
      newsect->filepos = hdr->p_offset + hdr->p_filesz;
      align = newsect->vma & -newsect->vma;
      if (align == 0 || align > hdr->p_align)
	align = hdr->p_align;
      newsect->alignment_power = bfd_log2 (align);
      if (hdr->p_type == PT_LOAD)
	{
	  newsect->flags |= SEC_ALLOC;
	  if (hdr->p_flags & PF_X)
	    newsect->flags |= SEC_CODE;
	}
      if (!(hdr->p_flags & PF_W))
	newsect->flags |= SEC_READONLY;
    }

  return true;
}

static bool
_bfd_elf_core_find_build_id (bfd *templ, bfd_vma offset)
{
  /* The return value is ignored.  Build-ids are considered optional.  */
  if (templ->xvec->flavour == bfd_target_elf_flavour)
    return (*get_elf_backend_data (templ)->elf_backend_core_find_build_id)
      (templ, offset);
  return false;
}

bool
bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
{
  const struct elf_backend_data *bed;

  switch (hdr->p_type)
    {
    case PT_NULL:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "null");

    case PT_LOAD:
      if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "load"))
	return false;
      if (bfd_get_format (abfd) == bfd_core && abfd->build_id == NULL)
	_bfd_elf_core_find_build_id (abfd, hdr->p_offset);
      return true;

    case PT_DYNAMIC:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "dynamic");

    case PT_INTERP:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "interp");

    case PT_NOTE:
      if (! _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "note"))
	return false;
      if (! _bfd_elf_read_notes (abfd, hdr->p_offset, hdr->p_filesz,
				 hdr->p_align))
	return false;
      return true;

    case PT_SHLIB:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "shlib");

    case PT_PHDR:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "phdr");

    case PT_GNU_EH_FRAME:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
					      "eh_frame_hdr");

    case PT_GNU_STACK:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "stack");

    case PT_GNU_RELRO:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index, "relro");

    case PT_GNU_SFRAME:
      return _bfd_elf_make_section_from_phdr (abfd, hdr, hdr_index,
					      "sframe");

    default:
      /* Check for any processor-specific program segment types.  */
      bed = get_elf_backend_data (abfd);
      return bed->elf_backend_section_from_phdr (abfd, hdr, hdr_index, "proc");
    }
}

/* Return the REL_HDR for SEC, assuming there is only a single one, either
   REL or RELA.  */

Elf_Internal_Shdr *
_bfd_elf_single_rel_hdr (asection *sec)
{
  if (elf_section_data (sec)->rel.hdr)
    {
      BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
      return elf_section_data (sec)->rel.hdr;
    }
  else
    return elf_section_data (sec)->rela.hdr;
}

static bool
_bfd_elf_set_reloc_sh_name (bfd *abfd,
			    Elf_Internal_Shdr *rel_hdr,
			    const char *sec_name,
			    bool use_rela_p)
{
  char *name = (char *) bfd_alloc (abfd,
				   sizeof ".rela" + strlen (sec_name));
  if (name == NULL)
    return false;

  sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", sec_name);
  rel_hdr->sh_name =
    (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
					false);
  if (rel_hdr->sh_name == (unsigned int) -1)
    return false;

  return true;
}

/* Allocate and initialize a section-header for a new reloc section,
   containing relocations against ASECT.  It is stored in RELDATA.  If
   USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
   relocations.  */

static bool
_bfd_elf_init_reloc_shdr (bfd *abfd,
			  struct bfd_elf_section_reloc_data *reldata,
			  const char *sec_name,
			  bool use_rela_p,
			  bool delay_sh_name_p)
{
  Elf_Internal_Shdr *rel_hdr;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  BFD_ASSERT (reldata->hdr == NULL);
  rel_hdr = bfd_zalloc (abfd, sizeof (*rel_hdr));
  if (rel_hdr == NULL)
    return false;
  reldata->hdr = rel_hdr;

  if (delay_sh_name_p)
    rel_hdr->sh_name = (unsigned int) -1;
  else if (!_bfd_elf_set_reloc_sh_name (abfd, rel_hdr, sec_name,
					use_rela_p))
    return false;
  rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
  rel_hdr->sh_entsize = (use_rela_p
			 ? bed->s->sizeof_rela
			 : bed->s->sizeof_rel);
  rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
  rel_hdr->sh_flags = 0;
  rel_hdr->sh_addr = 0;
  rel_hdr->sh_size = 0;
  rel_hdr->sh_offset = 0;

  return true;
}

/* Return the default section type based on the passed in section flags.  */

int
bfd_elf_get_default_section_type (flagword flags)
{
  if ((flags & (SEC_ALLOC | SEC_IS_COMMON)) != 0
      && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
    return SHT_NOBITS;
  return SHT_PROGBITS;
}

struct fake_section_arg
{
  struct bfd_link_info *link_info;
  bool failed;
};

/* Set up an ELF internal section header for a section.  */

static void
elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
{
  struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct bfd_elf_section_data *esd = elf_section_data (asect);
  Elf_Internal_Shdr *this_hdr;
  unsigned int sh_type;
  const char *name = asect->name;
  bool delay_sh_name_p = false;
  bfd_vma mask;

  if (arg->failed)
    {
      /* We already failed; just get out of the bfd_map_over_sections
	 loop.  */
      return;
    }

  this_hdr = &esd->this_hdr;

  /* ld: compress DWARF debug sections with names: .debug_*.  */
  if (arg->link_info
      && (abfd->flags & BFD_COMPRESS) != 0
      && (asect->flags & SEC_DEBUGGING) != 0
      && (asect->flags & SEC_ALLOC) == 0
      && (asect->flags & SEC_HAS_CONTENTS) != 0
      && name[1] == 'd'
      && name[6] == '_')
    {
      /* If this section will be compressed, delay adding section
	 name to section name section after it is compressed in
	 _bfd_elf_assign_file_positions_for_non_load.  */
      delay_sh_name_p = true;
    }

  if (delay_sh_name_p)
    this_hdr->sh_name = (unsigned int) -1;
  else
    {
      this_hdr->sh_name
	= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
					      name, false);
      if (this_hdr->sh_name == (unsigned int) -1)
	{
	  arg->failed = true;
	  return;
	}
    }

  /* Don't clear sh_flags. Assembler may set additional bits.  */

  if ((asect->flags & SEC_ALLOC) != 0
      || asect->user_set_vma)
    this_hdr->sh_addr = asect->vma * bfd_octets_per_byte (abfd, asect);
  else
    this_hdr->sh_addr = 0;

  this_hdr->sh_offset = 0;
  this_hdr->sh_size = asect->size;
  this_hdr->sh_link = 0;
  /* PR 17512: file: 0eb809fe, 8b0535ee.  */
  if (asect->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
    {
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: error: alignment power %d of section `%pA' is too big"),
	 abfd, asect->alignment_power, asect);
      arg->failed = true;
      return;
    }
  /* Set sh_addralign to the highest power of two given by alignment
     consistent with the section VMA.  Linker scripts can force VMA.  */
  mask = ((bfd_vma) 1 << asect->alignment_power) | this_hdr->sh_addr;
  this_hdr->sh_addralign = mask & -mask;
  /* The sh_entsize and sh_info fields may have been set already by
     copy_private_section_data.  */

  this_hdr->bfd_section = asect;
  this_hdr->contents = NULL;

  /* If the section type is unspecified, we set it based on
     asect->flags.  */
  if (asect->type != 0)
    sh_type = asect->type;
  else if ((asect->flags & SEC_GROUP) != 0)
    sh_type = SHT_GROUP;
  else
    sh_type = bfd_elf_get_default_section_type (asect->flags);

  if (this_hdr->sh_type == SHT_NULL)
    this_hdr->sh_type = sh_type;
  else if (this_hdr->sh_type == SHT_NOBITS
	   && sh_type == SHT_PROGBITS
	   && (asect->flags & SEC_ALLOC) != 0)
    {
      /* Warn if we are changing a NOBITS section to PROGBITS, but
	 allow the link to proceed.  This can happen when users link
	 non-bss input sections to bss output sections, or emit data
	 to a bss output section via a linker script.  */
      _bfd_error_handler
	(_("warning: section `%pA' type changed to PROGBITS"), asect);
      this_hdr->sh_type = sh_type;
    }

  switch (this_hdr->sh_type)
    {
    default:
      break;

    case SHT_STRTAB:
    case SHT_NOTE:
    case SHT_NOBITS:
    case SHT_PROGBITS:
      break;

    case SHT_INIT_ARRAY:
    case SHT_FINI_ARRAY:
    case SHT_PREINIT_ARRAY:
      this_hdr->sh_entsize = bed->s->arch_size / 8;
      break;

    case SHT_HASH:
      this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
      break;

    case SHT_DYNSYM:
      this_hdr->sh_entsize = bed->s->sizeof_sym;
      break;

    case SHT_DYNAMIC:
      this_hdr->sh_entsize = bed->s->sizeof_dyn;
      break;

    case SHT_RELA:
      if (get_elf_backend_data (abfd)->may_use_rela_p)
	this_hdr->sh_entsize = bed->s->sizeof_rela;
      break;

     case SHT_REL:
      if (get_elf_backend_data (abfd)->may_use_rel_p)
	this_hdr->sh_entsize = bed->s->sizeof_rel;
      break;

     case SHT_GNU_versym:
      this_hdr->sh_entsize = sizeof (Elf_External_Versym);
      break;

     case SHT_GNU_verdef:
      this_hdr->sh_entsize = 0;
      /* objcopy or strip will copy over sh_info, but may not set
	 cverdefs.  The linker will set cverdefs, but sh_info will be
	 zero.  */
      if (this_hdr->sh_info == 0)
	this_hdr->sh_info = elf_tdata (abfd)->cverdefs;
      else
	BFD_ASSERT (elf_tdata (abfd)->cverdefs == 0
		    || this_hdr->sh_info == elf_tdata (abfd)->cverdefs);
      break;

    case SHT_GNU_verneed:
      this_hdr->sh_entsize = 0;
      /* objcopy or strip will copy over sh_info, but may not set
	 cverrefs.  The linker will set cverrefs, but sh_info will be
	 zero.  */
      if (this_hdr->sh_info == 0)
	this_hdr->sh_info = elf_tdata (abfd)->cverrefs;
      else
	BFD_ASSERT (elf_tdata (abfd)->cverrefs == 0
		    || this_hdr->sh_info == elf_tdata (abfd)->cverrefs);
      break;

    case SHT_GROUP:
      this_hdr->sh_entsize = GRP_ENTRY_SIZE;
      break;

    case SHT_GNU_HASH:
      this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
      break;
    }

  if ((asect->flags & SEC_ALLOC) != 0)
    this_hdr->sh_flags |= SHF_ALLOC;
  if ((asect->flags & SEC_READONLY) == 0)
    this_hdr->sh_flags |= SHF_WRITE;
  if ((asect->flags & SEC_CODE) != 0)
    this_hdr->sh_flags |= SHF_EXECINSTR;
  if ((asect->flags & SEC_MERGE) != 0)
    {
      this_hdr->sh_flags |= SHF_MERGE;
      this_hdr->sh_entsize = asect->entsize;
    }
  if ((asect->flags & SEC_STRINGS) != 0)
    {
      this_hdr->sh_flags |= SHF_STRINGS;
      this_hdr->sh_entsize = asect->entsize;
    }
  if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
    this_hdr->sh_flags |= SHF_GROUP;
  if ((asect->flags & SEC_THREAD_LOCAL) != 0)
    {
      this_hdr->sh_flags |= SHF_TLS;
      if (asect->size == 0
	  && (asect->flags & SEC_HAS_CONTENTS) == 0)
	{
	  struct bfd_link_order *o = asect->map_tail.link_order;

	  this_hdr->sh_size = 0;
	  if (o != NULL)
	    {
	      this_hdr->sh_size = o->offset + o->size;
	      if (this_hdr->sh_size != 0)
		this_hdr->sh_type = SHT_NOBITS;
	    }
	}
    }
  if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
    this_hdr->sh_flags |= SHF_EXCLUDE;

  if (this_hdr->sh_entsize == 0)
    this_hdr->sh_entsize = asect->entsize;

  /* If the section has relocs, set up a section header for the
     SHT_REL[A] section.  If two relocation sections are required for
     this section, it is up to the processor-specific back-end to
     create the other.  */
  if ((asect->flags & SEC_RELOC) != 0)
    {
      /* When doing a relocatable link, create both REL and RELA sections if
	 needed.  */
      if (arg->link_info
	  /* Do the normal setup if we wouldn't create any sections here.  */
	  && esd->rel.count + esd->rela.count > 0
	  && (bfd_link_relocatable (arg->link_info)
	      || arg->link_info->emitrelocations))
	{
	  if (esd->rel.count && esd->rel.hdr == NULL
	      && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, name,
					    false, delay_sh_name_p))
	    {
	      arg->failed = true;
	      return;
	    }
	  if (esd->rela.count && esd->rela.hdr == NULL
	      && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, name,
					    true, delay_sh_name_p))
	    {
	      arg->failed = true;
	      return;
	    }
	}
      else if (!_bfd_elf_init_reloc_shdr (abfd,
					  (asect->use_rela_p
					   ? &esd->rela : &esd->rel),
					  name,
					  asect->use_rela_p,
					  delay_sh_name_p))
	{
	  arg->failed = true;
	  return;
	}
    }

  /* Check for processor-specific section types.  */
  sh_type = this_hdr->sh_type;
  if (bed->elf_backend_fake_sections
      && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
    {
      arg->failed = true;
      return;
    }

  if (sh_type == SHT_NOBITS && asect->size != 0)
    {
      /* Don't change the header type from NOBITS if we are being
	 called for objcopy --only-keep-debug.  */
      this_hdr->sh_type = sh_type;
    }
}

/* Fill in the contents of a SHT_GROUP section.  Called from
   _bfd_elf_compute_section_file_positions for gas, objcopy, and
   when ELF targets use the generic linker, ld.  Called for ld -r
   from bfd_elf_final_link.  */

void
bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
{
  bool *failedptr = (bool *) failedptrarg;
  asection *elt, *first;
  unsigned char *loc;
  bool gas;

  /* Ignore linker created group section.  See elfNN_ia64_object_p in
     elfxx-ia64.c.  */
  if ((sec->flags & (SEC_GROUP | SEC_LINKER_CREATED)) != SEC_GROUP
      || sec->size == 0
      || *failedptr)
    return;

  if (elf_section_data (sec)->this_hdr.sh_info == 0)
    {
      unsigned long symindx = 0;

      /* elf_group_id will have been set up by objcopy and the
	 generic linker.  */
      if (elf_group_id (sec) != NULL)
	symindx = elf_group_id (sec)->udata.i;

      if (symindx == 0)
	{
	  /* If called from the assembler, swap_out_syms will have set up
	     elf_section_syms.
	     PR 25699: A corrupt input file could contain bogus group info.  */
	  if (sec->index >= elf_num_section_syms (abfd)
	      || elf_section_syms (abfd)[sec->index] == NULL)
	    {
	      *failedptr = true;
	      return;
	    }
	  symindx = elf_section_syms (abfd)[sec->index]->udata.i;
	}
      elf_section_data (sec)->this_hdr.sh_info = symindx;
    }
  else if (elf_section_data (sec)->this_hdr.sh_info == (unsigned int) -2)
    {
      /* The ELF backend linker sets sh_info to -2 when the group
	 signature symbol is global, and thus the index can't be
	 set until all local symbols are output.  */
      asection *igroup;
      struct bfd_elf_section_data *sec_data;
      unsigned long symndx;
      unsigned long extsymoff;
      struct elf_link_hash_entry *h;

      /* The point of this little dance to the first SHF_GROUP section
	 then back to the SHT_GROUP section is that this gets us to
	 the SHT_GROUP in the input object.  */
      igroup = elf_sec_group (elf_next_in_group (sec));
      sec_data = elf_section_data (igroup);
      symndx = sec_data->this_hdr.sh_info;
      extsymoff = 0;
      if (!elf_bad_symtab (igroup->owner))
	{
	  Elf_Internal_Shdr *symtab_hdr;

	  symtab_hdr = &elf_tdata (igroup->owner)->symtab_hdr;
	  extsymoff = symtab_hdr->sh_info;
	}
      h = elf_sym_hashes (igroup->owner)[symndx - extsymoff];
      while (h->root.type == bfd_link_hash_indirect
	     || h->root.type == bfd_link_hash_warning)
	h = (struct elf_link_hash_entry *) h->root.u.i.link;

      elf_section_data (sec)->this_hdr.sh_info = h->indx;
    }

  /* The contents won't be allocated for "ld -r" or objcopy.  */
  gas = true;
  if (sec->contents == NULL)
    {
      gas = false;
      sec->contents = (unsigned char *) bfd_alloc (abfd, sec->size);

      /* Arrange for the section to be written out.  */
      elf_section_data (sec)->this_hdr.contents = sec->contents;
      if (sec->contents == NULL)
	{
	  *failedptr = true;
	  return;
	}
      sec->alloced = 1;
    }

  loc = sec->contents + sec->size;

  /* Get the pointer to the first section in the group that gas
     squirreled away here.  objcopy arranges for this to be set to the
     start of the input section group.  */
  first = elt = elf_next_in_group (sec);

  /* First element is a flag word.  Rest of section is elf section
     indices for all the sections of the group.  Write them backwards
     just to keep the group in the same order as given in .section
     directives, not that it matters.  */
  while (elt != NULL)
    {
      asection *s;

      s = elt;
      if (!gas)
	s = s->output_section;
      if (s != NULL
	  && !bfd_is_abs_section (s))
	{
	  struct bfd_elf_section_data *elf_sec = elf_section_data (s);
	  struct bfd_elf_section_data *input_elf_sec = elf_section_data (elt);

	  if (elf_sec->rel.hdr != NULL
	      && (gas
		  || (input_elf_sec->rel.hdr != NULL
		      && input_elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0))
	    {
	      elf_sec->rel.hdr->sh_flags |= SHF_GROUP;
	      loc -= 4;
	      if (loc == sec->contents)
		break;
	      H_PUT_32 (abfd, elf_sec->rel.idx, loc);
	    }
	  if (elf_sec->rela.hdr != NULL
	      && (gas
		  || (input_elf_sec->rela.hdr != NULL
		      && input_elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0))
	    {
	      elf_sec->rela.hdr->sh_flags |= SHF_GROUP;
	      loc -= 4;
	      if (loc == sec->contents)
		break;
	      H_PUT_32 (abfd, elf_sec->rela.idx, loc);
	    }
	  loc -= 4;
	  if (loc == sec->contents)
	    break;
	  H_PUT_32 (abfd, elf_sec->this_idx, loc);
	}
      elt = elf_next_in_group (elt);
      if (elt == first)
	break;
    }

  /* We should always get here with loc == sec->contents + 4.  Return
     an error for bogus SHT_GROUP sections.  */
  loc -= 4;
  if (loc != sec->contents)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: corrupted group section: `%pA'"),
			  abfd, sec);
      bfd_set_error (bfd_error_bad_value);
      *failedptr = true;
      return;
    }

  H_PUT_32 (abfd, sec->flags & SEC_LINK_ONCE ? GRP_COMDAT : 0, loc);
}

/* Given NAME, the name of a relocation section stripped of its
   .rel/.rela prefix, return the section in ABFD to which the
   relocations apply.  */

asection *
_bfd_elf_plt_get_reloc_section (bfd *abfd, const char *name)
{
  /* If a target needs .got.plt section, relocations in rela.plt/rel.plt
     section likely apply to .got.plt or .got section.  */
  if (get_elf_backend_data (abfd)->want_got_plt
      && streq (name, ".plt"))
    {
      asection *sec;

      name = ".got.plt";
      sec = bfd_get_section_by_name (abfd, name);
      if (sec != NULL)
	return sec;
      name = ".got";
    }

  return bfd_get_section_by_name (abfd, name);
}

/* Return the section to which RELOC_SEC applies.  */

static asection *
elf_get_reloc_section (asection *reloc_sec)
{
  const char *name;
  unsigned int type;
  bfd *abfd;
  const struct elf_backend_data *bed;

  type = elf_section_data (reloc_sec)->this_hdr.sh_type;
  if (type != SHT_REL && type != SHT_RELA)
    return NULL;

  /* We look up the section the relocs apply to by name.  */
  name = reloc_sec->name;
  if (!startswith (name, ".rel"))
    return NULL;
  name += 4;
  if (type == SHT_RELA && *name++ != 'a')
    return NULL;

  abfd = reloc_sec->owner;
  bed = get_elf_backend_data (abfd);
  return bed->get_reloc_section (abfd, name);
}

/* Assign all ELF section numbers.  The dummy first section is handled here
   too.  The link/info pointers for the standard section types are filled
   in here too, while we're at it.  LINK_INFO will be 0 when arriving
   here for gas, objcopy, and when using the generic ELF linker.  */

static bool
assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
{
  struct elf_obj_tdata *t = elf_tdata (abfd);
  asection *sec;
  unsigned int section_number;
  Elf_Internal_Shdr **i_shdrp;
  struct bfd_elf_section_data *d;
  bool need_symtab;
  size_t amt;

  section_number = 1;

  _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));

  /* SHT_GROUP sections are in relocatable files only.  */
  if (link_info == NULL || !link_info->resolve_section_groups)
    {
      size_t reloc_count = 0;

      /* Put SHT_GROUP sections first.  */
      for (sec = abfd->sections; sec != NULL; sec = sec->next)
	{
	  d = elf_section_data (sec);

	  if (d->this_hdr.sh_type == SHT_GROUP)
	    {
	      if (sec->flags & SEC_LINKER_CREATED)
		{
		  /* Remove the linker created SHT_GROUP sections.  */
		  bfd_section_list_remove (abfd, sec);
		  abfd->section_count--;
		}
	      else
		d->this_idx = section_number++;
	    }

	  /* Count relocations.  */
	  reloc_count += sec->reloc_count;
	}

      /* Set/clear HAS_RELOC depending on whether there are relocations.  */
      if (reloc_count == 0)
	abfd->flags &= ~HAS_RELOC;
      else
	abfd->flags |= HAS_RELOC;
    }

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      d = elf_section_data (sec);

      if (d->this_hdr.sh_type != SHT_GROUP)
	d->this_idx = section_number++;
      if (d->this_hdr.sh_name != (unsigned int) -1)
	_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
      if (d->rel.hdr)
	{
	  d->rel.idx = section_number++;
	  if (d->rel.hdr->sh_name != (unsigned int) -1)
	    _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
	}
      else
	d->rel.idx = 0;

      if (d->rela.hdr)
	{
	  d->rela.idx = section_number++;
	  if (d->rela.hdr->sh_name != (unsigned int) -1)
	    _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
	}
      else
	d->rela.idx = 0;
    }

  need_symtab = (bfd_get_symcount (abfd) > 0
		 || (link_info == NULL
		     && ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
			 == HAS_RELOC)));
  if (need_symtab)
    {
      elf_onesymtab (abfd) = section_number++;
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
      if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
	{
	  elf_section_list *entry;

	  BFD_ASSERT (elf_symtab_shndx_list (abfd) == NULL);

	  entry = bfd_zalloc (abfd, sizeof (*entry));
	  entry->ndx = section_number++;
	  elf_symtab_shndx_list (abfd) = entry;
	  entry->hdr.sh_name
	    = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
						  ".symtab_shndx", false);
	  if (entry->hdr.sh_name == (unsigned int) -1)
	    return false;
	}
      elf_strtab_sec (abfd) = section_number++;
      _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
    }

  elf_shstrtab_sec (abfd) = section_number++;
  _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
  elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);

  if (section_number >= SHN_LORESERVE)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: too many sections: %u"),
			  abfd, section_number);
      return false;
    }

  elf_numsections (abfd) = section_number;
  elf_elfheader (abfd)->e_shnum = section_number;

  /* Set up the list of section header pointers, in agreement with the
     indices.  */
  amt = section_number * sizeof (Elf_Internal_Shdr *);
  i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
  if (i_shdrp == NULL)
    return false;

  i_shdrp[0] = (Elf_Internal_Shdr *) bfd_zalloc (abfd,
						 sizeof (Elf_Internal_Shdr));
  if (i_shdrp[0] == NULL)
    {
      bfd_release (abfd, i_shdrp);
      return false;
    }

  elf_elfsections (abfd) = i_shdrp;

  i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr;
  if (need_symtab)
    {
      i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
      if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
	{
	  elf_section_list * entry = elf_symtab_shndx_list (abfd);
	  BFD_ASSERT (entry != NULL);
	  i_shdrp[entry->ndx] = & entry->hdr;
	  entry->hdr.sh_link = elf_onesymtab (abfd);
	}
      i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
      t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
    }

  for (sec = abfd->sections; sec; sec = sec->next)
    {
      asection *s;

      d = elf_section_data (sec);

      i_shdrp[d->this_idx] = &d->this_hdr;
      if (d->rel.idx != 0)
	i_shdrp[d->rel.idx] = d->rel.hdr;
      if (d->rela.idx != 0)
	i_shdrp[d->rela.idx] = d->rela.hdr;

      /* Fill in the sh_link and sh_info fields while we're at it.  */

      /* sh_link of a reloc section is the section index of the symbol
	 table.  sh_info is the section index of the section to which
	 the relocation entries apply.  */
      if (d->rel.idx != 0)
	{
	  d->rel.hdr->sh_link = elf_onesymtab (abfd);
	  d->rel.hdr->sh_info = d->this_idx;
	  d->rel.hdr->sh_flags |= SHF_INFO_LINK;
	}
      if (d->rela.idx != 0)
	{
	  d->rela.hdr->sh_link = elf_onesymtab (abfd);
	  d->rela.hdr->sh_info = d->this_idx;
	  d->rela.hdr->sh_flags |= SHF_INFO_LINK;
	}

      /* We need to set up sh_link for SHF_LINK_ORDER.  */
      if ((d->this_hdr.sh_flags & SHF_LINK_ORDER) != 0)
	{
	  s = elf_linked_to_section (sec);
	  /* We can now have a NULL linked section pointer.
	     This happens when the sh_link field is 0, which is done
	     when a linked to section is discarded but the linking
	     section has been retained for some reason.  */
	  if (s)
	    {
	      /* Check discarded linkonce section.  */
	      if (discarded_section (s))
		{
		  asection *kept;
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: sh_link of section `%pA' points to"
		       " discarded section `%pA' of `%pB'"),
		     abfd, d->this_hdr.bfd_section, s, s->owner);
		  /* Point to the kept section if it has the same
		     size as the discarded one.  */
		  kept = _bfd_elf_check_kept_section (s, link_info);
		  if (kept == NULL)
		    {
		      bfd_set_error (bfd_error_bad_value);
		      return false;
		    }
		  s = kept;
		}
	      /* Handle objcopy. */
	      else if (s->output_section == NULL)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: sh_link of section `%pA' points to"
		       " removed section `%pA' of `%pB'"),
		     abfd, d->this_hdr.bfd_section, s, s->owner);
		  bfd_set_error (bfd_error_bad_value);
		  return false;
		}
	      s = s->output_section;
	      d->this_hdr.sh_link = elf_section_data (s)->this_idx;
	    }
	}

      switch (d->this_hdr.sh_type)
	{
	case SHT_REL:
	case SHT_RELA:
	  /* sh_link is the section index of the symbol table.
	     sh_info is the section index of the section to which the
	     relocation entries apply.  */
	  if (d->this_hdr.sh_link == 0)
	    {
	      /* FIXME maybe: If this is a reloc section which we are
		 treating as a normal section then we likely should
		 not be assuming its sh_link is .dynsym or .symtab.  */
	      if ((sec->flags & SEC_ALLOC) != 0)
		{
		  s = bfd_get_section_by_name (abfd, ".dynsym");
		  if (s != NULL)
		    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
		}
	      else
		d->this_hdr.sh_link = elf_onesymtab (abfd);
	    }

	  s = elf_get_reloc_section (sec);
	  if (s != NULL)
	    {
	      d->this_hdr.sh_info = elf_section_data (s)->this_idx;
	      d->this_hdr.sh_flags |= SHF_INFO_LINK;
	    }
	  break;

	case SHT_STRTAB:
	  /* We assume that a section named .stab*str is a stabs
	     string section.  We look for a section with the same name
	     but without the trailing ``str'', and set its sh_link
	     field to point to this section.  */
	  if (startswith (sec->name, ".stab")
	      && streq (sec->name + strlen (sec->name) - 3, "str"))
	    {
	      size_t len;
	      char *alc;

	      len = strlen (sec->name);
	      alc = (char *) bfd_malloc (len - 2);
	      if (alc == NULL)
		return false;
	      memcpy (alc, sec->name, len - 3);
	      alc[len - 3] = '\0';
	      s = bfd_get_section_by_name (abfd, alc);
	      free (alc);
	      if (s != NULL)
		{
		  elf_section_data (s)->this_hdr.sh_link = d->this_idx;

		  /* This is a .stab section.  */
		  elf_section_data (s)->this_hdr.sh_entsize = 12;
		}
	    }
	  break;

	case SHT_DYNAMIC:
	case SHT_DYNSYM:
	case SHT_GNU_verneed:
	case SHT_GNU_verdef:
	  /* sh_link is the section header index of the string table
	     used for the dynamic entries, or the symbol table, or the
	     version strings.  */
	  s = bfd_get_section_by_name (abfd, ".dynstr");
	  if (s != NULL)
	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
	  break;

	case SHT_GNU_LIBLIST:
	  /* sh_link is the section header index of the prelink library
	     list used for the dynamic entries, or the symbol table, or
	     the version strings.  */
	  s = bfd_get_section_by_name (abfd, ((sec->flags & SEC_ALLOC)
					      ? ".dynstr" : ".gnu.libstr"));
	  if (s != NULL)
	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
	  break;

	case SHT_HASH:
	case SHT_GNU_HASH:
	case SHT_GNU_versym:
	  /* sh_link is the section header index of the symbol table
	     this hash table or version table is for.  */
	  s = bfd_get_section_by_name (abfd, ".dynsym");
	  if (s != NULL)
	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;
	  break;

	case SHT_GROUP:
	  d->this_hdr.sh_link = elf_onesymtab (abfd);
	}
    }

  /* Delay setting sh_name to _bfd_elf_write_object_contents so that
     _bfd_elf_assign_file_positions_for_non_load can convert DWARF
     debug section name from .debug_* to .zdebug_* if needed.  */

  return true;
}

static bool
sym_is_global (bfd *abfd, asymbol *sym)
{
  /* If the backend has a special mapping, use it.  */
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_sym_is_global)
    return (*bed->elf_backend_sym_is_global) (abfd, sym);

  return ((sym->flags & (BSF_GLOBAL | BSF_WEAK | BSF_GNU_UNIQUE)) != 0
	  || bfd_is_und_section (bfd_asymbol_section (sym))
	  || bfd_is_com_section (bfd_asymbol_section (sym)));
}

/* Filter global symbols of ABFD to include in the import library.  All
   SYMCOUNT symbols of ABFD can be examined from their pointers in
   SYMS.  Pointers of symbols to keep should be stored contiguously at
   the beginning of that array.

   Returns the number of symbols to keep.  */

unsigned int
_bfd_elf_filter_global_symbols (bfd *abfd, struct bfd_link_info *info,
				asymbol **syms, long symcount)
{
  long src_count, dst_count = 0;

  for (src_count = 0; src_count < symcount; src_count++)
    {
      asymbol *sym = syms[src_count];
      char *name = (char *) bfd_asymbol_name (sym);
      struct bfd_link_hash_entry *h;

      if (!sym_is_global (abfd, sym))
	continue;

      h = bfd_link_hash_lookup (info->hash, name, false, false, false);
      if (h == NULL)
	continue;
      if (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak)
	continue;
      if (h->linker_def || h->ldscript_def)
	continue;

      syms[dst_count++] = sym;
    }

  syms[dst_count] = NULL;

  return dst_count;
}

/* Don't output symbols for sections that are not going to be output,
   that are duplicates or there is no BFD section.  */

static bool
ignore_sym (asymbol *sym)
{
  if (sym == NULL)
    return false;

  if (sym->section == NULL)
    return true;

  if ((sym->flags & BSF_SECTION_SYM) != 0)
    {
      if ((sym->flags & BSF_SECTION_SYM_USED) == 0)
	return true;
      /* With ld -r on generic elf targets it is possible to have
	 multiple section symbols in the output for a given section.
	 We'd like to get rid of all but the first one.  This drops
	 them if the first input section is non-zero size, but fails
	 to do so if the first input section is zero sized.  */
      if (sym->section->output_offset != 0)
	return true;
    }

  return discarded_section (sym->section);
}

/* Map symbol from it's internal number to the external number, moving
   all local symbols to be at the head of the list.  */

static bool
elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
{
  unsigned int symcount = bfd_get_symcount (abfd);
  asymbol **syms = bfd_get_outsymbols (abfd);
  asymbol **sect_syms;
  unsigned int num_locals = 0;
  unsigned int num_globals = 0;
  unsigned int max_index = 0;
  unsigned int idx;
  asection *asect;
  asymbol **new_syms;
  size_t amt;

#ifdef DEBUG
  fprintf (stderr, "elf_map_symbols\n");
  fflush (stderr);
#endif

  for (asect = abfd->sections; asect; asect = asect->next)
    {
      if (max_index < asect->index)
	max_index = asect->index;
    }

  max_index++;
  amt = max_index * sizeof (asymbol *);
  sect_syms = (asymbol **) bfd_zalloc (abfd, amt);
  if (sect_syms == NULL)
    return false;
  elf_section_syms (abfd) = sect_syms;
  elf_num_section_syms (abfd) = max_index;

  /* Init sect_syms entries for any section symbols we have already
     decided to output.  */
  for (idx = 0; idx < symcount; idx++)
    {
      asymbol *sym = syms[idx];

      if ((sym->flags & BSF_SECTION_SYM) != 0
	  && sym->value == 0
	  && !ignore_sym (sym)
	  && !bfd_is_abs_section (sym->section))
	{
	  asection *sec = sym->section;

	  if (sec->owner != abfd)
	    {
	      sec = sec->output_section;
	      if (sec == NULL)
		return false;
	    }

	  sect_syms[sec->index] = syms[idx];
	}
    }

  /* Classify all of the symbols.  */
  for (idx = 0; idx < symcount; idx++)
    {
      if (ignore_sym (syms[idx]))
	continue;
      if (sym_is_global (abfd, syms[idx]))
	num_globals++;
      else
	num_locals++;
    }

  /* We will be adding a section symbol for each normal BFD section.  Most
     sections will already have a section symbol in outsymbols, but
     eg. SHT_GROUP sections will not, and we need the section symbol mapped
     at least in that case.  */
  for (asect = abfd->sections; asect; asect = asect->next)
    {
      asymbol *sym = asect->symbol;
      /* Don't include ignored section symbols.  */
      if (!ignore_sym (sym)
	  && sect_syms[asect->index] == NULL)
	{
	  if (sym_is_global (abfd, asect->symbol))
	    num_globals++;
	  else
	    num_locals++;
	}
    }

  /* Now sort the symbols so the local symbols are first.  */
  amt = (num_locals + num_globals) * sizeof (asymbol *);
  new_syms = (asymbol **) bfd_alloc (abfd, amt);
  if (new_syms == NULL)
    return false;

  unsigned int num_globals2 = 0;
  unsigned int num_locals2 = 0;
  for (idx = 0; idx < symcount; idx++)
    {
      asymbol *sym = syms[idx];
      unsigned int i;

      if (ignore_sym (sym))
	continue;

      if (sym_is_global (abfd, sym))
	i = num_locals + num_globals2++;
      else
	i = num_locals2++;
      new_syms[i] = sym;
      sym->udata.i = i + 1;
    }
  for (asect = abfd->sections; asect; asect = asect->next)
    {
      asymbol *sym = asect->symbol;
      if (!ignore_sym (sym)
	  && sect_syms[asect->index] == NULL)
	{
	  unsigned int i;

	  sect_syms[asect->index] = sym;
	  if (sym_is_global (abfd, sym))
	    i = num_locals + num_globals2++;
	  else
	    i = num_locals2++;
	  new_syms[i] = sym;
	  sym->udata.i = i + 1;
	}
    }

  bfd_set_symtab (abfd, new_syms, num_locals + num_globals);

  *pnum_locals = num_locals;
  return true;
}

/* Assign a file position to a section, optionally aligning to the
   required section alignment.  */

file_ptr
_bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
					   file_ptr offset,
					   bool align,
					   unsigned char log_file_align)
{
  if (i_shdrp->sh_addralign > 1)
    {
      file_ptr salign = i_shdrp->sh_addralign & -i_shdrp->sh_addralign;

      if (align)
	offset = BFD_ALIGN (offset, salign);
      else if (log_file_align)
	{
	  /* Heuristic: Cap alignment at log_file_align.  */
	  file_ptr falign = 1u << log_file_align;

	  offset = BFD_ALIGN (offset, salign < falign ? salign : falign);
	}
    }
  i_shdrp->sh_offset = offset;
  if (i_shdrp->bfd_section != NULL)
    i_shdrp->bfd_section->filepos = offset;
  if (i_shdrp->sh_type != SHT_NOBITS)
    offset += i_shdrp->sh_size;
  return offset;
}

/* Compute the file positions we are going to put the sections at, and
   otherwise prepare to begin writing out the ELF file.  If LINK_INFO
   is not NULL, this is being called by the ELF backend linker.  */

bool
_bfd_elf_compute_section_file_positions (bfd *abfd,
					 struct bfd_link_info *link_info)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct fake_section_arg fsargs;
  bool failed;
  struct elf_strtab_hash *strtab = NULL;
  Elf_Internal_Shdr *shstrtab_hdr;
  bool need_symtab;

  if (abfd->output_has_begun)
    return true;

  /* Do any elf backend specific processing first.  */
  if (bed->elf_backend_begin_write_processing)
    (*bed->elf_backend_begin_write_processing) (abfd, link_info);

  if (!(*bed->elf_backend_init_file_header) (abfd, link_info))
    return false;

  fsargs.failed = false;
  fsargs.link_info = link_info;
  bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
  if (fsargs.failed)
    return false;

  if (!assign_section_numbers (abfd, link_info))
    return false;

  /* The backend linker builds symbol table information itself.  */
  need_symtab = (link_info == NULL
		 && (bfd_get_symcount (abfd) > 0
		     || ((abfd->flags & (EXEC_P | DYNAMIC | HAS_RELOC))
			 == HAS_RELOC)));
  if (need_symtab)
    {
      /* Non-zero if doing a relocatable link.  */
      int relocatable_p = ! (abfd->flags & (EXEC_P | DYNAMIC));

      if (! swap_out_syms (abfd, &strtab, relocatable_p, link_info))
	return false;
    }

  failed = false;
  if (link_info == NULL)
    {
      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
      if (failed)
	goto err_free_strtab;
    }

  shstrtab_hdr = &elf_tdata (abfd)->shstrtab_hdr;
  /* sh_name was set in init_file_header.  */
  shstrtab_hdr->sh_type = SHT_STRTAB;
  shstrtab_hdr->sh_flags = bed->elf_strtab_flags;
  shstrtab_hdr->sh_addr = 0;
  /* sh_size is set in _bfd_elf_assign_file_positions_for_non_load.  */
  shstrtab_hdr->sh_entsize = 0;
  shstrtab_hdr->sh_link = 0;
  shstrtab_hdr->sh_info = 0;
  /* sh_offset is set in _bfd_elf_assign_file_positions_for_non_load.  */
  shstrtab_hdr->sh_addralign = 1;

  if (!assign_file_positions_except_relocs (abfd, link_info))
    goto err_free_strtab;

  if (strtab != NULL)
    {
      file_ptr off;
      Elf_Internal_Shdr *hdr;

      off = elf_next_file_pos (abfd);

      hdr = & elf_symtab_hdr (abfd);
      off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0);

      if (elf_symtab_shndx_list (abfd) != NULL)
	{
	  hdr = & elf_symtab_shndx_list (abfd)->hdr;
	  if (hdr->sh_size != 0)
	    off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0);
	  /* FIXME: What about other symtab_shndx sections in the list ?  */
	}

      hdr = &elf_tdata (abfd)->strtab_hdr;
      off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0);

      elf_next_file_pos (abfd) = off;

      /* Now that we know where the .strtab section goes, write it
	 out.  */
      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
	  || ! _bfd_elf_strtab_emit (abfd, strtab))
	goto err_free_strtab;
      _bfd_elf_strtab_free (strtab);
    }

  abfd->output_has_begun = true;
  return true;

 err_free_strtab:
  if (strtab != NULL)
    _bfd_elf_strtab_free (strtab);
  return false;
}

/* Retrieve .eh_frame_hdr.  Prior to size_dynamic_sections the
   function effectively returns whether --eh-frame-hdr is given on the
   command line.  After size_dynamic_sections the result reflects
   whether .eh_frame_hdr will actually be output (sizing isn't done
   until ldemul_after_allocation).  */

static asection *
elf_eh_frame_hdr (const struct bfd_link_info *info)
{
  if (info != NULL && is_elf_hash_table (info->hash))
    return elf_hash_table (info)->eh_info.hdr_sec;
  return NULL;
}

/* Make an initial estimate of the size of the program header.  If we
   get the number wrong here, we'll redo section placement.  */

static bfd_size_type
get_program_header_size (bfd *abfd, struct bfd_link_info *info)
{
  size_t segs;
  asection *s;
  const struct elf_backend_data *bed;

  /* Assume we will need exactly two PT_LOAD segments: one for text
     and one for data.  */
  segs = 2;

  s = bfd_get_section_by_name (abfd, ".interp");
  if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size != 0)
    {
      /* If we have a loadable interpreter section, we need a
	 PT_INTERP segment.  In this case, assume we also need a
	 PT_PHDR segment, although that may not be true for all
	 targets.  */
      segs += 2;
    }

  if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
    {
      /* We need a PT_DYNAMIC segment.  */
      ++segs;
    }

  if (info != NULL && info->relro)
    {
      /* We need a PT_GNU_RELRO segment.  */
      ++segs;
    }

  if (elf_eh_frame_hdr (info))
    {
      /* We need a PT_GNU_EH_FRAME segment.  */
      ++segs;
    }

  if (elf_stack_flags (abfd))
    {
      /* We need a PT_GNU_STACK segment.  */
      ++segs;
    }

  if (elf_sframe (abfd))
    {
      /* We need a PT_GNU_SFRAME segment.  */
      ++segs;
    }

  s = bfd_get_section_by_name (abfd,
			       NOTE_GNU_PROPERTY_SECTION_NAME);
  if (s != NULL && s->size != 0)
    {
      /* We need a PT_GNU_PROPERTY segment.  */
      ++segs;
    }

  for (s = abfd->sections; s != NULL; s = s->next)
    {
      if ((s->flags & SEC_LOAD) != 0
	  && elf_section_type (s) == SHT_NOTE)
	{
	  unsigned int alignment_power;
	  /* We need a PT_NOTE segment.  */
	  ++segs;
	  /* Try to create just one PT_NOTE segment for all adjacent
	     loadable SHT_NOTE sections.  gABI requires that within a
	     PT_NOTE segment (and also inside of each SHT_NOTE section)
	     each note should have the same alignment.  So we check
	     whether the sections are correctly aligned.  */
	  alignment_power = s->alignment_power;
	  while (s->next != NULL
		 && s->next->alignment_power == alignment_power
		 && (s->next->flags & SEC_LOAD) != 0
		 && elf_section_type (s->next) == SHT_NOTE)
	    s = s->next;
	}
    }

  for (s = abfd->sections; s != NULL; s = s->next)
    {
      if (s->flags & SEC_THREAD_LOCAL)
	{
	  /* We need a PT_TLS segment.  */
	  ++segs;
	  break;
	}
    }

  bed = get_elf_backend_data (abfd);

  if ((abfd->flags & D_PAGED) != 0
      && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
    {
      /* Add a PT_GNU_MBIND segment for each mbind section.  */
      bfd_vma commonpagesize;
      unsigned int page_align_power;

      if (info != NULL)
	commonpagesize = info->commonpagesize;
      else
	commonpagesize = bed->commonpagesize;
      page_align_power = bfd_log2 (commonpagesize);
      for (s = abfd->sections; s != NULL; s = s->next)
	if (elf_section_flags (s) & SHF_GNU_MBIND)
	  {
	    if (elf_section_data (s)->this_hdr.sh_info > PT_GNU_MBIND_NUM)
	      {
		_bfd_error_handler
		  /* xgettext:c-format */
		  (_("%pB: GNU_MBIND section `%pA' has invalid "
		     "sh_info field: %d"),
		   abfd, s, elf_section_data (s)->this_hdr.sh_info);
		continue;
	      }
	    /* Align mbind section to page size.  */
	    if (s->alignment_power < page_align_power)
	      s->alignment_power = page_align_power;
	    segs ++;
	  }
    }

  /* Let the backend count up any program headers it might need.  */
  if (bed->elf_backend_additional_program_headers)
    {
      int a;

      a = (*bed->elf_backend_additional_program_headers) (abfd, info);
      if (a == -1)
	abort ();
      segs += a;
    }

  return segs * bed->s->sizeof_phdr;
}

/* Find the segment that contains the output_section of section.  */

Elf_Internal_Phdr *
_bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
{
  struct elf_segment_map *m;
  Elf_Internal_Phdr *p;

  for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr;
       m != NULL;
       m = m->next, p++)
    {
      int i;

      for (i = m->count - 1; i >= 0; i--)
	if (m->sections[i] == section)
	  return p;
    }

  return NULL;
}

/* Create a mapping from a set of sections to a program segment.  */

static struct elf_segment_map *
make_mapping (bfd *abfd,
	      asection **sections,
	      unsigned int from,
	      unsigned int to,
	      bool phdr)
{
  struct elf_segment_map *m;
  unsigned int i;
  asection **hdrpp;
  size_t amt;

  amt = sizeof (struct elf_segment_map) - sizeof (asection *);
  amt += (to - from) * sizeof (asection *);
  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
  if (m == NULL)
    return NULL;
  m->next = NULL;
  m->p_type = PT_LOAD;
  for (i = from, hdrpp = sections + from; i < to; i++, hdrpp++)
    m->sections[i - from] = *hdrpp;
  m->count = to - from;

  if (from == 0 && phdr)
    {
      /* Include the headers in the first PT_LOAD segment.  */
      m->includes_filehdr = 1;
      m->includes_phdrs = 1;
    }

  return m;
}

/* Create the PT_DYNAMIC segment, which includes DYNSEC.  Returns NULL
   on failure.  */

struct elf_segment_map *
_bfd_elf_make_dynamic_segment (bfd *abfd, asection *dynsec)
{
  struct elf_segment_map *m;

  m = (struct elf_segment_map *) bfd_zalloc (abfd,
					     sizeof (struct elf_segment_map));
  if (m == NULL)
    return NULL;
  m->next = NULL;
  m->p_type = PT_DYNAMIC;
  m->count = 1;
  m->sections[0] = dynsec;

  return m;
}

/* Possibly add or remove segments from the segment map.  */

static bool
elf_modify_segment_map (bfd *abfd,
			struct bfd_link_info *info,
			bool remove_empty_load)
{
  struct elf_segment_map **m;
  const struct elf_backend_data *bed;

  /* The placement algorithm assumes that non allocated sections are
     not in PT_LOAD segments.  We ensure this here by removing such
     sections from the segment map.  We also remove excluded
     sections.  Finally, any PT_LOAD segment without sections is
     removed.  */
  m = &elf_seg_map (abfd);
  while (*m)
    {
      unsigned int i, new_count;

      for (new_count = 0, i = 0; i < (*m)->count; i++)
	{
	  if (((*m)->sections[i]->flags & SEC_EXCLUDE) == 0
	      && (((*m)->sections[i]->flags & SEC_ALLOC) != 0
		  || (*m)->p_type != PT_LOAD))
	    {
	      (*m)->sections[new_count] = (*m)->sections[i];
	      new_count++;
	    }
	}
      (*m)->count = new_count;

      if (remove_empty_load
	  && (*m)->p_type == PT_LOAD
	  && (*m)->count == 0
	  && !(*m)->includes_phdrs)
	*m = (*m)->next;
      else
	m = &(*m)->next;
    }

  bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_modify_segment_map != NULL)
    {
      if (!(*bed->elf_backend_modify_segment_map) (abfd, info))
	return false;
    }

  return true;
}

#define IS_TBSS(s) \
  ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL)

/* Set up a mapping from BFD sections to program segments.  Update
   NEED_LAYOUT if the section layout is changed.  */

bool
bfd_elf_map_sections_to_segments (bfd *abfd,
				  struct bfd_link_info *info,
				  bool *need_layout)
{
  unsigned int count;
  struct elf_segment_map *m;
  asection **sections = NULL;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bool no_user_phdrs;

  no_user_phdrs = elf_seg_map (abfd) == NULL;

  if (info != NULL)
    {
      info->user_phdrs = !no_user_phdrs;

      /* Size the relative relocations if DT_RELR is enabled.  */
      if (info->enable_dt_relr
	  && need_layout != NULL
	  && bed->size_relative_relocs
	  && !bed->size_relative_relocs (info, need_layout))
	info->callbacks->fatal
	  (_("%P: failed to size relative relocations\n"));
    }

  if (no_user_phdrs && bfd_count_sections (abfd) != 0)
    {
      asection *s;
      unsigned int i;
      struct elf_segment_map *mfirst;
      struct elf_segment_map **pm;
      asection *last_hdr;
      bfd_vma last_size;
      unsigned int hdr_index;
      bfd_vma maxpagesize;
      asection **hdrpp;
      bool phdr_in_segment;
      bool writable;
      bool executable;
      unsigned int tls_count = 0;
      asection *first_tls = NULL;
      asection *first_mbind = NULL;
      asection *dynsec, *eh_frame_hdr;
      asection *sframe;
      size_t amt;
      bfd_vma addr_mask, wrap_to = 0;  /* Bytes.  */
      bfd_size_type phdr_size;  /* Octets/bytes.  */
      unsigned int opb = bfd_octets_per_byte (abfd, NULL);

      /* Select the allocated sections, and sort them.  */

      amt = bfd_count_sections (abfd) * sizeof (asection *);
      sections = (asection **) bfd_malloc (amt);
      if (sections == NULL)
	goto error_return;

      /* Calculate top address, avoiding undefined behaviour of shift
	 left operator when shift count is equal to size of type
	 being shifted.  */
      addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1;
      addr_mask = (addr_mask << 1) + 1;

      i = 0;
      for (s = abfd->sections; s != NULL; s = s->next)
	{
	  if ((s->flags & SEC_ALLOC) != 0)
	    {
	      /* target_index is unused until bfd_elf_final_link
		 starts output of section symbols.  Use it to make
		 qsort stable.  */
	      s->target_index = i;
	      sections[i] = s;
	      ++i;
	      /* A wrapping section potentially clashes with header.  */
	      if (((s->lma + s->size / opb) & addr_mask) < (s->lma & addr_mask))
		wrap_to = (s->lma + s->size / opb) & addr_mask;
	    }
	}
      BFD_ASSERT (i <= bfd_count_sections (abfd));
      count = i;

      qsort (sections, (size_t) count, sizeof (asection *), elf_sort_sections);

      phdr_size = elf_program_header_size (abfd);
      if (phdr_size == (bfd_size_type) -1)
	phdr_size = get_program_header_size (abfd, info);
      phdr_size += bed->s->sizeof_ehdr;
      /* phdr_size is compared to LMA values which are in bytes.  */
      phdr_size /= opb;
      if (info != NULL)
	maxpagesize = info->maxpagesize;
      else
	maxpagesize = bed->maxpagesize;
      if (maxpagesize == 0)
	maxpagesize = 1;
      phdr_in_segment = info != NULL && info->load_phdrs;
      if (count != 0
	  && (((sections[0]->lma & addr_mask) & (maxpagesize - 1))
	      >= (phdr_size & (maxpagesize - 1))))
	/* For compatibility with old scripts that may not be using
	   SIZEOF_HEADERS, add headers when it looks like space has
	   been left for them.  */
	phdr_in_segment = true;

      /* Build the mapping.  */
      mfirst = NULL;
      pm = &mfirst;

      /* If we have a .interp section, then create a PT_PHDR segment for
	 the program headers and a PT_INTERP segment for the .interp
	 section.  */
      s = bfd_get_section_by_name (abfd, ".interp");
      if (s != NULL && (s->flags & SEC_LOAD) != 0 && s->size != 0)
	{
	  amt = sizeof (struct elf_segment_map);
	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_PHDR;
	  m->p_flags = PF_R;
	  m->p_flags_valid = 1;
	  m->includes_phdrs = 1;
	  phdr_in_segment = true;
	  *pm = m;
	  pm = &m->next;

	  amt = sizeof (struct elf_segment_map);
	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_INTERP;
	  m->count = 1;
	  m->sections[0] = s;

	  *pm = m;
	  pm = &m->next;
	}

      /* Look through the sections.  We put sections in the same program
	 segment when the start of the second section can be placed within
	 a few bytes of the end of the first section.  */
      last_hdr = NULL;
      last_size = 0;
      hdr_index = 0;
      writable = false;
      executable = false;
      dynsec = bfd_get_section_by_name (abfd, ".dynamic");
      if (dynsec != NULL
	  && (dynsec->flags & SEC_LOAD) == 0)
	dynsec = NULL;

      if ((abfd->flags & D_PAGED) == 0)
	phdr_in_segment = false;

      /* Deal with -Ttext or something similar such that the first section
	 is not adjacent to the program headers.  This is an
	 approximation, since at this point we don't know exactly how many
	 program headers we will need.  */
      if (phdr_in_segment && count > 0)
	{
	  bfd_vma phdr_lma;  /* Bytes.  */
	  bool separate_phdr = false;

	  phdr_lma = (sections[0]->lma - phdr_size) & addr_mask & -maxpagesize;
	  if (info != NULL
	      && info->separate_code
	      && (sections[0]->flags & SEC_CODE) != 0)
	    {
	      /* If data sections should be separate from code and
		 thus not executable, and the first section is
		 executable then put the file and program headers in
		 their own PT_LOAD.  */
	      if (!info->one_rosegment)
		separate_phdr = true;

	      if ((((phdr_lma + phdr_size - 1) & addr_mask & -maxpagesize)
		   == (sections[0]->lma & addr_mask & -maxpagesize)))
		{
		  /* The file and program headers are currently on the
		     same page as the first section.  Put them on the
		     previous page if we can.  */
		  if (phdr_lma >= maxpagesize)
		    phdr_lma -= maxpagesize;
		  else
		    separate_phdr = false;
		}
	    }
	  if ((sections[0]->lma & addr_mask) < phdr_lma
	      || (sections[0]->lma & addr_mask) < phdr_size)
	    /* If file and program headers would be placed at the end
	       of memory then it's probably better to omit them.  */
	    phdr_in_segment = false;
	  else if (phdr_lma < wrap_to)
	    /* If a section wraps around to where we'll be placing
	       file and program headers, then the headers will be
	       overwritten.  */
	    phdr_in_segment = false;
	  else if (separate_phdr)
	    {
	      m = make_mapping (abfd, sections, 0, 0, phdr_in_segment);
	      if (m == NULL)
		goto error_return;
	      m->p_paddr = phdr_lma * opb;
	      m->p_vaddr_offset
		= (sections[0]->vma - phdr_size) & addr_mask & -maxpagesize;
	      m->p_paddr_valid = 1;
	      *pm = m;
	      pm = &m->next;
	      phdr_in_segment = false;
	    }
	}

      for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
	{
	  asection *hdr;
	  bool new_segment;

	  hdr = *hdrpp;

	  /* See if this section and the last one will fit in the same
	     segment.  */

	  if (last_hdr == NULL)
	    {
	      /* If we don't have a segment yet, then we don't need a new
		 one (we build the last one after this loop).  */
	      new_segment = false;
	    }
	  else if (last_hdr->lma - last_hdr->vma != hdr->lma - hdr->vma)
	    {
	      /* If this section has a different relation between the
		 virtual address and the load address, then we need a new
		 segment.  */
	      new_segment = true;
	    }
	  else if (hdr->lma < last_hdr->lma + last_size
		   || last_hdr->lma + last_size < last_hdr->lma)
	    {
	      /* If this section has a load address that makes it overlap
		 the previous section, then we need a new segment.  */
	      new_segment = true;
	    }
	  else if ((abfd->flags & D_PAGED) != 0
		   && (((last_hdr->lma + last_size - 1) & -maxpagesize)
		       == (hdr->lma & -maxpagesize)))
	    {
	      /* If we are demand paged then we can't map two disk
		 pages onto the same memory page.  */
	      new_segment = false;
	    }
	  /* In the next test we have to be careful when last_hdr->lma is close
	     to the end of the address space.  If the aligned address wraps
	     around to the start of the address space, then there are no more
	     pages left in memory and it is OK to assume that the current
	     section can be included in the current segment.  */
	  else if ((BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
		    + maxpagesize > last_hdr->lma)
		   && (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize)
		       + maxpagesize <= hdr->lma))
	    {
	      /* If putting this section in this segment would force us to
		 skip a page in the segment, then we need a new segment.  */
	      new_segment = true;
	    }
	  else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0
		   && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0)
	    {
	      /* We don't want to put a loaded section after a
		 nonloaded (ie. bss style) section in the same segment
		 as that will force the non-loaded section to be loaded.
		 Consider .tbss sections as loaded for this purpose.  */
	      new_segment = true;
	    }
	  else if ((abfd->flags & D_PAGED) == 0)
	    {
	      /* If the file is not demand paged, which means that we
		 don't require the sections to be correctly aligned in the
		 file, then there is no other reason for a new segment.  */
	      new_segment = false;
	    }
	  else if (info != NULL
		   && info->separate_code
		   && executable != ((hdr->flags & SEC_CODE) != 0))
	    {
	      new_segment = true;
	    }
	  else if (! writable
		   && (hdr->flags & SEC_READONLY) == 0)
	    {
	      /* We don't want to put a writable section in a read only
		 segment.  */
	      new_segment = true;
	    }
	  else
	    {
	      /* Otherwise, we can use the same segment.  */
	      new_segment = false;
	    }

	  /* Allow interested parties a chance to override our decision.  */
	  if (last_hdr != NULL
	      && info != NULL
	      && info->callbacks->override_segment_assignment != NULL)
	    new_segment
	      = info->callbacks->override_segment_assignment (info, abfd, hdr,
							      last_hdr,
							      new_segment);

	  if (! new_segment)
	    {
	      if ((hdr->flags & SEC_READONLY) == 0)
		writable = true;
	      if ((hdr->flags & SEC_CODE) != 0)
		executable = true;
	      last_hdr = hdr;
	      /* .tbss sections effectively have zero size.  */
	      last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
	      continue;
	    }

	  /* We need a new program segment.  We must create a new program
	     header holding all the sections from hdr_index until hdr.  */

	  m = make_mapping (abfd, sections, hdr_index, i, phdr_in_segment);
	  if (m == NULL)
	    goto error_return;

	  *pm = m;
	  pm = &m->next;

	  if ((hdr->flags & SEC_READONLY) == 0)
	    writable = true;
	  else
	    writable = false;

	  if ((hdr->flags & SEC_CODE) == 0)
	    executable = false;
	  else
	    executable = true;

	  last_hdr = hdr;
	  /* .tbss sections effectively have zero size.  */
	  last_size = (!IS_TBSS (hdr) ? hdr->size : 0) / opb;
	  hdr_index = i;
	  phdr_in_segment = false;
	}

      /* Create a final PT_LOAD program segment, but not if it's just
	 for .tbss.  */
      if (last_hdr != NULL
	  && (i - hdr_index != 1
	      || !IS_TBSS (last_hdr)))
	{
	  m = make_mapping (abfd, sections, hdr_index, i, phdr_in_segment);
	  if (m == NULL)
	    goto error_return;

	  *pm = m;
	  pm = &m->next;
	}

      /* If there is a .dynamic section, throw in a PT_DYNAMIC segment.  */
      if (dynsec != NULL)
	{
	  m = _bfd_elf_make_dynamic_segment (abfd, dynsec);
	  if (m == NULL)
	    goto error_return;
	  *pm = m;
	  pm = &m->next;
	}

      /* For each batch of consecutive loadable SHT_NOTE  sections,
	 add a PT_NOTE segment.  We don't use bfd_get_section_by_name,
	 because if we link together nonloadable .note sections and
	 loadable .note sections, we will generate two .note sections
	 in the output file.  */
      for (s = abfd->sections; s != NULL; s = s->next)
	{
	  if ((s->flags & SEC_LOAD) != 0
	      && elf_section_type (s) == SHT_NOTE)
	    {
	      asection *s2;
	      unsigned int alignment_power = s->alignment_power;

	      count = 1;
	      for (s2 = s; s2->next != NULL; s2 = s2->next)
		{
		  if (s2->next->alignment_power == alignment_power
		      && (s2->next->flags & SEC_LOAD) != 0
		      && elf_section_type (s2->next) == SHT_NOTE
		      && align_power (s2->lma + s2->size / opb,
				      alignment_power)
		      == s2->next->lma)
		    count++;
		  else
		    break;
		}
	      amt = sizeof (struct elf_segment_map) - sizeof (asection *);
	      amt += count * sizeof (asection *);
	      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	      if (m == NULL)
		goto error_return;
	      m->next = NULL;
	      m->p_type = PT_NOTE;
	      m->count = count;
	      while (count > 1)
		{
		  m->sections[m->count - count--] = s;
		  BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
		  s = s->next;
		}
	      m->sections[m->count - 1] = s;
	      BFD_ASSERT ((s->flags & SEC_THREAD_LOCAL) == 0);
	      *pm = m;
	      pm = &m->next;
	    }
	  if (s->flags & SEC_THREAD_LOCAL)
	    {
	      if (! tls_count)
		first_tls = s;
	      tls_count++;
	    }
	  if (first_mbind == NULL
	      && (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
	    first_mbind = s;
	}

      /* If there are any SHF_TLS output sections, add PT_TLS segment.  */
      if (tls_count > 0)
	{
	  amt = sizeof (struct elf_segment_map) - sizeof (asection *);
	  amt += tls_count * sizeof (asection *);
	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_TLS;
	  m->count = tls_count;
	  /* Mandated PF_R.  */
	  m->p_flags = PF_R;
	  m->p_flags_valid = 1;
	  s = first_tls;
	  for (i = 0; i < tls_count; ++i)
	    {
	      if ((s->flags & SEC_THREAD_LOCAL) == 0)
		{
		  _bfd_error_handler
		    (_("%pB: TLS sections are not adjacent:"), abfd);
		  s = first_tls;
		  i = 0;
		  while (i < tls_count)
		    {
		      if ((s->flags & SEC_THREAD_LOCAL) != 0)
			{
			  _bfd_error_handler (_("	    TLS: %pA"), s);
			  i++;
			}
		      else
			_bfd_error_handler (_("	non-TLS: %pA"), s);
		      s = s->next;
		    }
		  bfd_set_error (bfd_error_bad_value);
		  goto error_return;
		}
	      m->sections[i] = s;
	      s = s->next;
	    }

	  *pm = m;
	  pm = &m->next;
	}

      if (first_mbind
	  && (abfd->flags & D_PAGED) != 0
	  && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
	for (s = first_mbind; s != NULL; s = s->next)
	  if ((elf_section_flags (s) & SHF_GNU_MBIND) != 0
	      && elf_section_data (s)->this_hdr.sh_info <= PT_GNU_MBIND_NUM)
	    {
	      /* Mandated PF_R.  */
	      unsigned long p_flags = PF_R;
	      if ((s->flags & SEC_READONLY) == 0)
		p_flags |= PF_W;
	      if ((s->flags & SEC_CODE) != 0)
		p_flags |= PF_X;

	      amt = sizeof (struct elf_segment_map) + sizeof (asection *);
	      m = bfd_zalloc (abfd, amt);
	      if (m == NULL)
		goto error_return;
	      m->next = NULL;
	      m->p_type = (PT_GNU_MBIND_LO
			   + elf_section_data (s)->this_hdr.sh_info);
	      m->count = 1;
	      m->p_flags_valid = 1;
	      m->sections[0] = s;
	      m->p_flags = p_flags;

	      *pm = m;
	      pm = &m->next;
	    }

      s = bfd_get_section_by_name (abfd,
				   NOTE_GNU_PROPERTY_SECTION_NAME);
      if (s != NULL && s->size != 0)
	{
	  amt = sizeof (struct elf_segment_map) + sizeof (asection *);
	  m = bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_GNU_PROPERTY;
	  m->count = 1;
	  m->p_flags_valid = 1;
	  m->sections[0] = s;
	  m->p_flags = PF_R;
	  *pm = m;
	  pm = &m->next;
	}

      /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
	 segment.  */
      eh_frame_hdr = elf_eh_frame_hdr (info);
      if (eh_frame_hdr != NULL
	  && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
	{
	  amt = sizeof (struct elf_segment_map);
	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_GNU_EH_FRAME;
	  m->count = 1;
	  m->sections[0] = eh_frame_hdr->output_section;

	  *pm = m;
	  pm = &m->next;
	}

      /* If there is a .sframe section, throw in a PT_GNU_SFRAME
	 segment.  */
      sframe = elf_sframe (abfd);
      if (sframe != NULL
	  && (sframe->output_section->flags & SEC_LOAD) != 0
	  && sframe->size != 0)
	{
	  amt = sizeof (struct elf_segment_map);
	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_GNU_SFRAME;
	  m->count = 1;
	  m->sections[0] = sframe->output_section;

	  *pm = m;
	  pm = &m->next;
	}

      if (elf_stack_flags (abfd))
	{
	  amt = sizeof (struct elf_segment_map);
	  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	  if (m == NULL)
	    goto error_return;
	  m->next = NULL;
	  m->p_type = PT_GNU_STACK;
	  m->p_flags = elf_stack_flags (abfd);
	  m->p_align = bed->stack_align;
	  m->p_flags_valid = 1;
	  m->p_align_valid = m->p_align != 0;
	  if (info->stacksize > 0)
	    {
	      m->p_size = info->stacksize;
	      m->p_size_valid = 1;
	    }

	  *pm = m;
	  pm = &m->next;
	}

      if (info != NULL && info->relro)
	{
	  for (m = mfirst; m != NULL; m = m->next)
	    {
	      if (m->p_type == PT_LOAD
		  && m->count != 0
		  && m->sections[0]->vma >= info->relro_start
		  && m->sections[0]->vma < info->relro_end)
		{
		  i = m->count;
		  while (--i != (unsigned) -1)
		    {
		      if (m->sections[i]->size > 0
			  && (m->sections[i]->flags & SEC_LOAD) != 0
			  && (m->sections[i]->flags & SEC_HAS_CONTENTS) != 0)
			break;
		    }

		  if (i != (unsigned) -1)
		    break;
		}
	    }

	  /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
	  if (m != NULL)
	    {
	      amt = sizeof (struct elf_segment_map);
	      m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
	      if (m == NULL)
		goto error_return;
	      m->next = NULL;
	      m->p_type = PT_GNU_RELRO;
	      *pm = m;
	      pm = &m->next;
	    }
	}

      free (sections);
      elf_seg_map (abfd) = mfirst;
    }

  if (!elf_modify_segment_map (abfd, info, no_user_phdrs || info == NULL))
    return false;

  for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
    ++count;
  elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;

  return true;

 error_return:
  free (sections);
  return false;
}

/* Sort sections by address.  */

static int
elf_sort_sections (const void *arg1, const void *arg2)
{
  const asection *sec1 = *(const asection **) arg1;
  const asection *sec2 = *(const asection **) arg2;
  bfd_size_type size1, size2;

  /* Sort by LMA first, since this is the address used to
     place the section into a segment.  */
  if (sec1->lma < sec2->lma)
    return -1;
  else if (sec1->lma > sec2->lma)
    return 1;

  /* Then sort by VMA.  Normally the LMA and the VMA will be
     the same, and this will do nothing.  */
  if (sec1->vma < sec2->vma)
    return -1;
  else if (sec1->vma > sec2->vma)
    return 1;

  /* Put !SEC_LOAD sections after SEC_LOAD ones.  */

#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 \
		  && (x)->size != 0)

  if (TOEND (sec1))
    {
      if (!TOEND (sec2))
	return 1;
    }
  else if (TOEND (sec2))
    return -1;

#undef TOEND

  /* Sort by size, to put zero sized sections
     before others at the same address.  */

  size1 = (sec1->flags & SEC_LOAD) ? sec1->size : 0;
  size2 = (sec2->flags & SEC_LOAD) ? sec2->size : 0;

  if (size1 < size2)
    return -1;
  if (size1 > size2)
    return 1;

  return sec1->target_index - sec2->target_index;
}

/* This qsort comparison functions sorts PT_LOAD segments first and
   by p_paddr, for assign_file_positions_for_load_sections.  */

static int
elf_sort_segments (const void *arg1, const void *arg2)
{
  const struct elf_segment_map *m1 = *(const struct elf_segment_map **) arg1;
  const struct elf_segment_map *m2 = *(const struct elf_segment_map **) arg2;

  if (m1->p_type != m2->p_type)
    {
      if (m1->p_type == PT_NULL)
	return 1;
      if (m2->p_type == PT_NULL)
	return -1;
      return m1->p_type < m2->p_type ? -1 : 1;
    }
  if (m1->includes_filehdr != m2->includes_filehdr)
    return m1->includes_filehdr ? -1 : 1;
  if (m1->no_sort_lma != m2->no_sort_lma)
    return m1->no_sort_lma ? -1 : 1;
  if (m1->p_type == PT_LOAD && !m1->no_sort_lma)
    {
      bfd_vma lma1, lma2;  /* Octets.  */
      lma1 = 0;
      if (m1->p_paddr_valid)
	lma1 = m1->p_paddr;
      else if (m1->count != 0)
	{
	  unsigned int opb = bfd_octets_per_byte (m1->sections[0]->owner,
						  m1->sections[0]);
	  lma1 = (m1->sections[0]->lma + m1->p_vaddr_offset) * opb;
	}
      lma2 = 0;
      if (m2->p_paddr_valid)
	lma2 = m2->p_paddr;
      else if (m2->count != 0)
	{
	  unsigned int opb = bfd_octets_per_byte (m2->sections[0]->owner,
						  m2->sections[0]);
	  lma2 = (m2->sections[0]->lma + m2->p_vaddr_offset) * opb;
	}
      if (lma1 != lma2)
	return lma1 < lma2 ? -1 : 1;
    }
  if (m1->idx != m2->idx)
    return m1->idx < m2->idx ? -1 : 1;
  return 0;
}

/* Ian Lance Taylor writes:

   We shouldn't be using % with a negative signed number.  That's just
   not good.  We have to make sure either that the number is not
   negative, or that the number has an unsigned type.  When the types
   are all the same size they wind up as unsigned.  When file_ptr is a
   larger signed type, the arithmetic winds up as signed long long,
   which is wrong.

   What we're trying to say here is something like ``increase OFF by
   the least amount that will cause it to be equal to the VMA modulo
   the page size.''  */
/* In other words, something like:

   vma_offset = m->sections[0]->vma % bed->maxpagesize;
   off_offset = off % bed->maxpagesize;
   if (vma_offset < off_offset)
     adjustment = vma_offset + bed->maxpagesize - off_offset;
   else
     adjustment = vma_offset - off_offset;

   which can be collapsed into the expression below.  */

static file_ptr
vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
{
  /* PR binutils/16199: Handle an alignment of zero.  */
  if (maxpagesize == 0)
    maxpagesize = 1;
  return ((vma - off) % maxpagesize);
}

static void
print_segment_map (const struct elf_segment_map *m)
{
  unsigned int j;
  const char *pt = get_segment_type (m->p_type);
  char buf[32];

  if (pt == NULL)
    {
      if (m->p_type >= PT_LOPROC && m->p_type <= PT_HIPROC)
	sprintf (buf, "LOPROC+%7.7x",
		 (unsigned int) (m->p_type - PT_LOPROC));
      else if (m->p_type >= PT_LOOS && m->p_type <= PT_HIOS)
	sprintf (buf, "LOOS+%7.7x",
		 (unsigned int) (m->p_type - PT_LOOS));
      else
	snprintf (buf, sizeof (buf), "%8.8x",
		  (unsigned int) m->p_type);
      pt = buf;
    }
  fflush (stdout);
  fprintf (stderr, "%s:", pt);
  for (j = 0; j < m->count; j++)
    fprintf (stderr, " %s", m->sections [j]->name);
  putc ('\n',stderr);
  fflush (stderr);
}

/* Assign file positions to the sections based on the mapping from
   sections to segments.  This function also sets up some fields in
   the file header.  */

static bool
assign_file_positions_for_load_sections (bfd *abfd,
					 struct bfd_link_info *link_info)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  struct elf_segment_map *m;
  struct elf_segment_map *phdr_load_seg;
  Elf_Internal_Phdr *phdrs;
  Elf_Internal_Phdr *p;
  file_ptr off;  /* Octets.  */
  bfd_size_type maxpagesize;
  unsigned int alloc, actual;
  unsigned int i, j;
  struct elf_segment_map **sorted_seg_map;
  unsigned int opb = bfd_octets_per_byte (abfd, NULL);

  if (link_info == NULL
      && !bfd_elf_map_sections_to_segments (abfd, link_info, NULL))
    return false;

  alloc = 0;
  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
    m->idx = alloc++;

  if (alloc)
    {
      elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
      elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
    }
  else
    {
      /* PR binutils/12467.  */
      elf_elfheader (abfd)->e_phoff = 0;
      elf_elfheader (abfd)->e_phentsize = 0;
    }

  elf_elfheader (abfd)->e_phnum = alloc;

  if (elf_program_header_size (abfd) == (bfd_size_type) -1)
    {
      actual = alloc;
      elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr;
    }
  else
    {
      actual = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
      BFD_ASSERT (elf_program_header_size (abfd)
		  == actual * bed->s->sizeof_phdr);
      BFD_ASSERT (actual >= alloc);
    }

  if (alloc == 0)
    {
      elf_next_file_pos (abfd) = bed->s->sizeof_ehdr;
      return true;
    }

  /* We're writing the size in elf_program_header_size (abfd),
     see assign_file_positions_except_relocs, so make sure we have
     that amount allocated, with trailing space cleared.
     The variable alloc contains the computed need, while
     elf_program_header_size (abfd) contains the size used for the
     layout.
     See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
     where the layout is forced to according to a larger size in the
     last iterations for the testcase ld-elf/header.  */
  phdrs = bfd_zalloc (abfd, (actual * sizeof (*phdrs)
			     + alloc * sizeof (*sorted_seg_map)));
  sorted_seg_map = (struct elf_segment_map **) (phdrs + actual);
  elf_tdata (abfd)->phdr = phdrs;
  if (phdrs == NULL)
    return false;

  for (m = elf_seg_map (abfd), j = 0; m != NULL; m = m->next, j++)
    {
      sorted_seg_map[j] = m;
      /* If elf_segment_map is not from map_sections_to_segments, the
	 sections may not be correctly ordered.  NOTE: sorting should
	 not be done to the PT_NOTE section of a corefile, which may
	 contain several pseudo-sections artificially created by bfd.
	 Sorting these pseudo-sections breaks things badly.  */
      if (m->count > 1
	  && !(elf_elfheader (abfd)->e_type == ET_CORE
	       && m->p_type == PT_NOTE))
	{
	  for (i = 0; i < m->count; i++)
	    m->sections[i]->target_index = i;
	  qsort (m->sections, (size_t) m->count, sizeof (asection *),
		 elf_sort_sections);
	}
    }
  if (alloc > 1)
    qsort (sorted_seg_map, alloc, sizeof (*sorted_seg_map),
	   elf_sort_segments);

  maxpagesize = 1;
  if ((abfd->flags & D_PAGED) != 0)
    {
      if (link_info != NULL)
	maxpagesize = link_info->maxpagesize;
      else
	maxpagesize = bed->maxpagesize;
    }

  /* Sections must map to file offsets past the ELF file header.  */
  off = bed->s->sizeof_ehdr;
  /* And if one of the PT_LOAD headers doesn't include the program
     headers then we'll be mapping program headers in the usual
     position after the ELF file header.  */
  phdr_load_seg = NULL;
  for (j = 0; j < alloc; j++)
    {
      m = sorted_seg_map[j];
      if (m->p_type != PT_LOAD)
	break;
      if (m->includes_phdrs)
	{
	  phdr_load_seg = m;
	  break;
	}
    }
  if (phdr_load_seg == NULL)
    off += actual * bed->s->sizeof_phdr;

  for (j = 0; j < alloc; j++)
    {
      asection **secpp;
      bfd_vma off_adjust;  /* Octets.  */
      bool no_contents;
      bfd_size_type align_pagesize;

      /* An ELF segment (described by Elf_Internal_Phdr) may contain a
	 number of sections with contents contributing to both p_filesz
	 and p_memsz, followed by a number of sections with no contents
	 that just contribute to p_memsz.  In this loop, OFF tracks next
	 available file offset for PT_LOAD and PT_NOTE segments.  */
      m = sorted_seg_map[j];
      p = phdrs + m->idx;
      p->p_type = m->p_type;
      p->p_flags = m->p_flags;

      if (m->count == 0)
	p->p_vaddr = m->p_vaddr_offset * opb;
      else
	p->p_vaddr = (m->sections[0]->vma + m->p_vaddr_offset) * opb;

      if (m->p_paddr_valid)
	p->p_paddr = m->p_paddr;
      else if (m->count == 0)
	p->p_paddr = 0;
      else
	p->p_paddr = (m->sections[0]->lma + m->p_vaddr_offset) * opb;

      align_pagesize = 0;
      if (p->p_type == PT_LOAD
	  && (abfd->flags & D_PAGED) != 0)
	{
	  /* p_align in demand paged PT_LOAD segments effectively stores
	     the maximum page size.  When copying an executable with
	     objcopy, we set m->p_align from the input file.  Use this
	     value for maxpagesize rather than bed->maxpagesize, which
	     may be different.  Note that we use maxpagesize for PT_TLS
	     segment alignment later in this function, so we are relying
	     on at least one PT_LOAD segment appearing before a PT_TLS
	     segment.  */
	  if (m->p_align_valid)
	    maxpagesize = m->p_align;
	  else if (bed->p_align != 0
		   && (link_info == NULL
		       || !link_info->maxpagesize_is_set))
	    /* We will lay out this binary using maxpagesize but set
	       p->p_align later to the possibly smaller bed->p_align.
	       The run-time loader will then be able to load this
	       binary when the system page size is maxpagesize, but if
	       the system page size is smaller can use p->p_align.
	       In either case p->p_align will be increased if
	       necessary to match section alignment.  */
	    align_pagesize = bed->p_align;

	  p->p_align = maxpagesize;
	}
      else if (m->p_align_valid)
	p->p_align = m->p_align;
      else if (m->count == 0)
	p->p_align = 1 << bed->s->log_file_align;

      if (m == phdr_load_seg)
	off += actual * bed->s->sizeof_phdr;

      no_contents = false;
      off_adjust = 0;
      if (p->p_type == PT_LOAD
	  && m->count > 0)
	{
	  bfd_size_type align;  /* Bytes.  */
	  unsigned int align_power = 0;

	  if (m->p_align_valid)
	    align = p->p_align;
	  else
	    {
	      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
		{
		  unsigned int secalign;

		  secalign = bfd_section_alignment (*secpp);
		  if (secalign > align_power)
		    align_power = secalign;
		}
	      align = (bfd_size_type) 1 << align_power;
	      /* If a section requires alignment higher than the
		 minimum p_align value, don't reduce a maxpagesize
		 p->p_align set earlier in this function.  */
	      if (align > bed->p_align)
		align_pagesize = 0;
	      if (align < maxpagesize)
		align = maxpagesize;
	      else
		{
		  /* If a section requires alignment higher than the
		     maximum page size, set p_align to the section
		     alignment.  */
		  if ((abfd->flags & D_PAGED) != 0)
		    p->p_align = align;
		}
	    }

	  for (i = 0; i < m->count; i++)
	    if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
	      /* If we aren't making room for this section, then
		 it must be SHT_NOBITS regardless of what we've
		 set via struct bfd_elf_special_section.  */
	      elf_section_type (m->sections[i]) = SHT_NOBITS;

	  /* Find out whether this segment contains any loadable
	     sections.  */
	  no_contents = true;
	  for (i = 0; i < m->count; i++)
	    if (elf_section_type (m->sections[i]) != SHT_NOBITS)
	      {
		no_contents = false;
		break;
	      }

	  off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align * opb);

	  /* Broken hardware and/or kernel require that files do not
	     map the same page with different permissions on some hppa
	     processors.  */
	  if (j != 0
	      && (abfd->flags & D_PAGED) != 0
	      && bed->no_page_alias
	      && (off & (maxpagesize - 1)) != 0
	      && ((off & -maxpagesize)
		  == ((off + off_adjust) & -maxpagesize)))
	    off_adjust += maxpagesize;
	  off += off_adjust;
	  if (no_contents)
	    {
	      /* We shouldn't need to align the segment on disk since
		 the segment doesn't need file space, but the gABI
		 arguably requires the alignment and glibc ld.so
		 checks it.  So to comply with the alignment
		 requirement but not waste file space, we adjust
		 p_offset for just this segment.  (OFF_ADJUST is
		 subtracted from OFF later.)  This may put p_offset
		 past the end of file, but that shouldn't matter.  */
	    }
	  else
	    off_adjust = 0;
	}
      /* Make sure the .dynamic section is the first section in the
	 PT_DYNAMIC segment.  */
      else if (p->p_type == PT_DYNAMIC
	       && m->count > 1
	       && ! streq (m->sections[0]->name, ".dynamic"))
	{
	  _bfd_error_handler
	    (_("%pB: The first section in the PT_DYNAMIC segment"
	       " is not the .dynamic section"),
	     abfd);
	  bfd_set_error (bfd_error_bad_value);
	  return false;
	}
      /* Set the note section type to SHT_NOTE.  */
      else if (p->p_type == PT_NOTE)
	for (i = 0; i < m->count; i++)
	  elf_section_type (m->sections[i]) = SHT_NOTE;

      if (m->includes_filehdr)
	{
	  if (!m->p_flags_valid)
	    p->p_flags |= PF_R;
	  p->p_filesz = bed->s->sizeof_ehdr;
	  p->p_memsz = bed->s->sizeof_ehdr;
	  if (p->p_type == PT_LOAD)
	    {
	      if (m->count > 0)
		{
		  if (p->p_vaddr < (bfd_vma) off
		      || (!m->p_paddr_valid
			  && p->p_paddr < (bfd_vma) off))
		    {
		      _bfd_error_handler
			(_("%pB: not enough room for program headers,"
			   " try linking with -N"),
			 abfd);
		      bfd_set_error (bfd_error_bad_value);
		      return false;
		    }
		  p->p_vaddr -= off;
		  if (!m->p_paddr_valid)
		    p->p_paddr -= off;
		}
	    }
	  else if (sorted_seg_map[0]->includes_filehdr)
	    {
	      Elf_Internal_Phdr *filehdr = phdrs + sorted_seg_map[0]->idx;
	      p->p_vaddr = filehdr->p_vaddr;
	      if (!m->p_paddr_valid)
		p->p_paddr = filehdr->p_paddr;
	    }
	}

      if (m->includes_phdrs)
	{
	  if (!m->p_flags_valid)
	    p->p_flags |= PF_R;
	  p->p_filesz += actual * bed->s->sizeof_phdr;
	  p->p_memsz += actual * bed->s->sizeof_phdr;
	  if (!m->includes_filehdr)
	    {
	      if (p->p_type == PT_LOAD)
		{
		  p->p_offset = off - actual * bed->s->sizeof_phdr;
		  elf_elfheader (abfd)->e_phoff = p->p_offset;
		  if (m->count > 0)
		    {
		      p->p_vaddr -= off - p->p_offset;
		      if (!m->p_paddr_valid)
			p->p_paddr -= off - p->p_offset;
		    }
		}
	      else if (phdr_load_seg != NULL)
		{
		  /* Also set PT_PHDR to match phdr_load_seg.  We've
		     sorted segments so that phdr_load_seg will
		     already be set by the code immediately above.  */
		  Elf_Internal_Phdr *phdr = phdrs + phdr_load_seg->idx;
		  bfd_vma phdr_off = 0;  /* Octets.  */
		  if (phdr_load_seg->includes_filehdr)
		    phdr_off = bed->s->sizeof_ehdr;
		  p->p_vaddr = phdr->p_vaddr + phdr_off;
		  if (!m->p_paddr_valid)
		    p->p_paddr = phdr->p_paddr + phdr_off;
		  p->p_offset = phdr->p_offset + phdr_off;
		}
	      else
		p->p_offset = bed->s->sizeof_ehdr;
	    }
	}

      if (p->p_type == PT_LOAD
	  || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
	{
	  if (!m->includes_filehdr && !m->includes_phdrs)
	    {
	      p->p_offset = off;
	      if (no_contents)
		{
		  /* Put meaningless p_offset for PT_LOAD segments
		     without file contents somewhere within the first
		     page, in an attempt to not point past EOF.  */
		  bfd_size_type align = maxpagesize;
		  if (align < p->p_align)
		    align = p->p_align;
		  if (align < 1)
		    align = 1;
		  /* Avoid p_offset of zero, which might be wrongly
		     interpreted as the segment being the first one,
		     containing the file header.  PR32763.  */
		  p->p_offset = (off + align - 1) % align + 1;
		}
	    }
	  else
	    {
	      file_ptr adjust;  /* Octets.  */

	      adjust = off - (p->p_offset + p->p_filesz);
	      if (!no_contents)
		p->p_filesz += adjust;
	      p->p_memsz += adjust;
	    }
	}

      if (align_pagesize)
	p->p_align = align_pagesize;

      /* Set up p_filesz, p_memsz, p_align and p_flags from the section
	 maps.  Set filepos for sections in PT_LOAD segments, and in
	 core files, for sections in PT_NOTE segments.
	 assign_file_positions_for_non_load_sections will set filepos
	 for other sections and update p_filesz for other segments.  */
      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
	{
	  asection *sec;
	  bfd_size_type align;
	  Elf_Internal_Shdr *this_hdr;

	  sec = *secpp;
	  this_hdr = &elf_section_data (sec)->this_hdr;
	  align = (bfd_size_type) 1 << bfd_section_alignment (sec);

	  if ((p->p_type == PT_LOAD
	       || p->p_type == PT_TLS)
	      && (this_hdr->sh_type != SHT_NOBITS
		  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
		      && ((this_hdr->sh_flags & SHF_TLS) == 0
			  || p->p_type == PT_TLS))))
	    {
	      bfd_vma p_start = p->p_paddr;		/* Octets.  */
	      bfd_vma p_end = p_start + p->p_memsz;	/* Octets.  */
	      bfd_vma s_start = sec->lma * opb;		/* Octets.  */
	      bfd_vma adjust = s_start - p_end;		/* Octets.  */

	      if (adjust != 0
		  && (s_start < p_end
		      || p_end < p_start))
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: section %pA lma %#" PRIx64
		       " adjusted to %#" PRIx64),
		     abfd, sec, (uint64_t) s_start / opb,
		     (uint64_t) p_end / opb);
		  adjust = 0;
		  sec->lma = p_end / opb;
		}
	      p->p_memsz += adjust;

	      if (p->p_type == PT_LOAD)
		{
		  if (this_hdr->sh_type != SHT_NOBITS)
		    {
		      off_adjust = 0;
		      if (p->p_filesz + adjust < p->p_memsz)
			{
			  /* We have a PROGBITS section following NOBITS ones.
			     Allocate file space for the NOBITS section(s).
			     We don't need to write out the zeros, posix
			     fseek past the end of data already written
			     followed by a write at that location is
			     guaranteed to result in zeros being read
			     from the gap.  */
			  adjust = p->p_memsz - p->p_filesz;
			}
		    }
		  /* We only adjust sh_offset in SHT_NOBITS sections
		     as would seem proper for their address when the
		     section is first in the segment.  sh_offset
		     doesn't really have any significance for
		     SHT_NOBITS anyway, apart from a notional position
		     relative to other sections.  Historically we
		     didn't bother with adjusting sh_offset and some
		     programs depend on it not being adjusted.  See
		     pr12921 and pr25662.  */
		  if (this_hdr->sh_type != SHT_NOBITS || i == 0)
		    {
		      off += adjust;
		      if (this_hdr->sh_type == SHT_NOBITS)
			off_adjust += adjust;
		    }
		}
	      if (this_hdr->sh_type != SHT_NOBITS)
		p->p_filesz += adjust;
	    }

	  if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
	    {
	      /* The section at i == 0 is the one that actually contains
		 everything.  */
	      if (i == 0)
		{
		  this_hdr->sh_offset = sec->filepos = off;
		  off += this_hdr->sh_size;
		  p->p_filesz = this_hdr->sh_size;
		  p->p_memsz = 0;
		  p->p_align = 1;
		}
	      else
		{
		  /* The rest are fake sections that shouldn't be written.  */
		  sec->filepos = 0;
		  sec->size = 0;
		  sec->flags = 0;
		  continue;
		}
	    }
	  else
	    {
	      if (this_hdr->sh_type == SHT_NOBITS
		  && (this_hdr->sh_flags & SHF_TLS) != 0
		  && this_hdr->sh_offset == 0)
		{
		  /* Set sh_offset for .tbss sections to their nominal
		     offset after aligning.  They are not loaded from
		     disk so the value doesn't really matter, except
		     when the .tbss section is the first one in a
		     PT_TLS segment.  In that case it sets the
		     p_offset for the PT_TLS segment, which according
		     to the ELF gABI ought to satisfy
		     p_offset % p_align == p_vaddr % p_align.  */
		  bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
							  off, align);
		  this_hdr->sh_offset = sec->filepos = off + adjust;
		}
	      else if (p->p_type == PT_LOAD)
		{
		  this_hdr->sh_offset = sec->filepos = off;
		  if (this_hdr->sh_type != SHT_NOBITS)
		    off += this_hdr->sh_size;
		}

	      if (this_hdr->sh_type != SHT_NOBITS)
		{
		  p->p_filesz += this_hdr->sh_size;
		  /* A load section without SHF_ALLOC is something like
		     a note section in a PT_NOTE segment.  These take
		     file space but are not loaded into memory.  */
		  if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
		    p->p_memsz += this_hdr->sh_size;
		}
	      else if ((this_hdr->sh_flags & SHF_ALLOC) != 0)
		{
		  if (p->p_type == PT_TLS)
		    p->p_memsz += this_hdr->sh_size;

		  /* .tbss is special.  It doesn't contribute to p_memsz of
		     normal segments.  */
		  else if ((this_hdr->sh_flags & SHF_TLS) == 0)
		    p->p_memsz += this_hdr->sh_size;
		}

	      if (align > p->p_align
		  && !m->p_align_valid
		  && (p->p_type != PT_LOAD
		      || (abfd->flags & D_PAGED) == 0))
		p->p_align = align;
	    }

	  if (!m->p_flags_valid)
	    {
	      p->p_flags |= PF_R;
	      if ((this_hdr->sh_flags & SHF_EXECINSTR) != 0)
		p->p_flags |= PF_X;
	      if ((this_hdr->sh_flags & SHF_WRITE) != 0)
		p->p_flags |= PF_W;
	    }
	}

      off -= off_adjust;

      /* PR ld/20815 - Check that the program header segment, if
	 present, will be loaded into memory.  */
      if (p->p_type == PT_PHDR
	  && phdr_load_seg == NULL
	  && !(bed->elf_backend_allow_non_load_phdr != NULL
	       && bed->elf_backend_allow_non_load_phdr (abfd, phdrs, alloc)))
	{
	  /* The fix for this error is usually to edit the linker script being
	     used and set up the program headers manually.  Either that or
	     leave room for the headers at the start of the SECTIONS.  */
	  _bfd_error_handler (_("%pB: error: PHDR segment not covered"
				" by LOAD segment"),
			      abfd);
	  if (link_info == NULL)
	    return false;
	  /* Arrange for the linker to exit with an error, deleting
	     the output file unless --noinhibit-exec is given.  */
	  link_info->callbacks->info ("%X");
	}

      /* Check that all sections are in a PT_LOAD segment.
	 Don't check funky gdb generated core files.  */
      if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core)
	{
	  bool check_vma = true;

	  for (i = 1; i < m->count; i++)
	    if (m->sections[i]->vma == m->sections[i - 1]->vma
		&& ELF_SECTION_SIZE (&(elf_section_data (m->sections[i])
				       ->this_hdr), p) != 0
		&& ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1])
				       ->this_hdr), p) != 0)
	      {
		/* Looks like we have overlays packed into the segment.  */
		check_vma = false;
		break;
	      }

	  for (i = 0; i < m->count; i++)
	    {
	      Elf_Internal_Shdr *this_hdr;
	      asection *sec;

	      sec = m->sections[i];
	      this_hdr = &(elf_section_data(sec)->this_hdr);
	      if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
		  && !ELF_TBSS_SPECIAL (this_hdr, p))
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB: section `%pA' can't be allocated in segment %u"),
		     abfd, sec, m->idx);
		  print_segment_map (m);
		}
	    }
	}
    }

  elf_next_file_pos (abfd) = off;

  if (link_info != NULL
      && phdr_load_seg != NULL
      && phdr_load_seg->includes_filehdr)
    {
      /* There is a segment that contains both the file headers and the
	 program headers, so provide a symbol __ehdr_start pointing there.
	 A program can use this to examine itself robustly.  */

      struct elf_link_hash_table *htab = elf_hash_table (link_info);
      struct elf_link_hash_entry *hash = htab->hehdr_start;

      /* If the symbol was referenced and not defined, define it.  */
      if (hash != NULL
	  && (hash->root.type == bfd_link_hash_new
	      || hash->root.type == bfd_link_hash_undefined
	      || hash->root.type == bfd_link_hash_undefweak
	      || hash->root.type == bfd_link_hash_common))
	{
	  asection *s = NULL;
	  bfd_vma filehdr_vaddr = phdrs[phdr_load_seg->idx].p_vaddr / opb;

	  if (phdr_load_seg->count != 0)
	    /* The segment contains sections, so use the first one.  */
	    s = phdr_load_seg->sections[0];
	  else
	    /* Use the first (i.e. lowest-addressed) section in any segment.  */
	    for (m = elf_seg_map (abfd); m != NULL; m = m->next)
	      if (m->p_type == PT_LOAD && m->count != 0)
		{
		  s = m->sections[0];
		  break;
		}

	  if (s != NULL)
	    {
	      hash->root.u.def.value = filehdr_vaddr - s->vma;
	      hash->root.u.def.section = s;
	    }
	  else
	    {
	      hash->root.u.def.value = filehdr_vaddr;
	      hash->root.u.def.section = bfd_abs_section_ptr;
	    }

	  hash->root.type = bfd_link_hash_defined;
	  hash->def_regular = 1;
	  hash->non_elf = 0;
	}
    }

  return true;
}

/* Determine if a bfd is a debuginfo file.  Unfortunately there
   is no defined method for detecting such files, so we have to
   use heuristics instead.  */

bool
is_debuginfo_file (bfd *abfd)
{
  if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return false;

  Elf_Internal_Shdr **start_headers = elf_elfsections (abfd);
  Elf_Internal_Shdr **end_headers = start_headers + elf_numsections (abfd);
  Elf_Internal_Shdr **headerp;

  for (headerp = start_headers; headerp < end_headers; headerp ++)
    {
      Elf_Internal_Shdr *header = * headerp;

      /* Debuginfo files do not have any allocated SHT_PROGBITS sections.
	 The only allocated sections are SHT_NOBITS or SHT_NOTES.  */
      if ((header->sh_flags & SHF_ALLOC) == SHF_ALLOC
	  && header->sh_type != SHT_NOBITS
	  && header->sh_type != SHT_NOTE)
	return false;
    }

  return true;
}

/* Assign file positions for other sections, except for compressed debug
   and sections assigned in _bfd_elf_assign_file_positions_for_non_load.  */

static bool
assign_file_positions_for_non_load_sections (bfd *abfd,
					     struct bfd_link_info *link_info)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  Elf_Internal_Shdr **i_shdrpp;
  Elf_Internal_Shdr **hdrpp, **end_hdrpp;
  Elf_Internal_Phdr *phdrs;
  Elf_Internal_Phdr *p;
  struct elf_segment_map *m;
  file_ptr off;
  unsigned int opb = bfd_octets_per_byte (abfd, NULL);
  bfd_vma maxpagesize;

  if (link_info != NULL)
    maxpagesize = link_info->maxpagesize;
  else
    maxpagesize = bed->maxpagesize;
  i_shdrpp = elf_elfsections (abfd);
  end_hdrpp = i_shdrpp + elf_numsections (abfd);
  off = elf_next_file_pos (abfd);
  for (hdrpp = i_shdrpp + 1; hdrpp < end_hdrpp; hdrpp++)
    {
      Elf_Internal_Shdr *hdr;
      bfd_vma align;

      hdr = *hdrpp;
      if (hdr->bfd_section != NULL
	  && (hdr->bfd_section->filepos != 0
	      || (hdr->sh_type == SHT_NOBITS
		  && hdr->contents == NULL)))
	BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
      else if ((hdr->sh_flags & SHF_ALLOC) != 0)
	{
	  if (hdr->sh_size != 0
	      /* PR 24717 - debuginfo files are known to be not strictly
		 compliant with the ELF standard.  In particular they often
		 have .note.gnu.property sections that are outside of any
		 loadable segment.  This is not a problem for such files,
		 so do not warn about them.  */
	      && ! is_debuginfo_file (abfd))
	    _bfd_error_handler
	      /* xgettext:c-format */
	      (_("%pB: warning: allocated section `%s' not in segment"),
	       abfd,
	       (hdr->bfd_section == NULL
		? "*unknown*"
		: hdr->bfd_section->name));
	  /* We don't need to page align empty sections.  */
	  if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
	    align = maxpagesize;
	  else
	    align = hdr->sh_addralign & -hdr->sh_addralign;
	  off += vma_page_aligned_bias (hdr->sh_addr, off, align);
	  off = _bfd_elf_assign_file_position_for_section (hdr, off, false,
							   bed->s->log_file_align);
	}
      else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
		&& hdr->bfd_section == NULL)
	       /* We don't know the offset of these sections yet:
		  their size has not been decided.  */
	       || (abfd->is_linker_output
		   && hdr->bfd_section != NULL
		   && (hdr->sh_name == -1u
		       || bfd_section_is_ctf (hdr->bfd_section)))
	       || hdr == i_shdrpp[elf_onesymtab (abfd)]
	       || (elf_symtab_shndx_list (abfd) != NULL
		   && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
	       || hdr == i_shdrpp[elf_strtab_sec (abfd)]
	       || hdr == i_shdrpp[elf_shstrtab_sec (abfd)])
	hdr->sh_offset = -1;
      else
	off = _bfd_elf_assign_file_position_for_section (hdr, off, true, 0);
    }
  elf_next_file_pos (abfd) = off;

  /* Now that we have set the section file positions, we can set up
     the file positions for the non PT_LOAD segments.  */
  phdrs = elf_tdata (abfd)->phdr;
  for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
    {
      if (p->p_type == PT_GNU_RELRO)
	{
	  bfd_vma start, end;  /* Bytes.  */
	  bool ok;

	  if (link_info != NULL)
	    {
	      /* During linking the range of the RELRO segment is passed
		 in link_info.  Note that there may be padding between
		 relro_start and the first RELRO section.  */
	      start = link_info->relro_start;
	      end = link_info->relro_end;
	    }
	  else if (m->count != 0)
	    {
	      if (!m->p_size_valid)
		abort ();
	      start = m->sections[0]->vma;
	      end = start + m->p_size / opb;
	    }
	  else
	    {
	      start = 0;
	      end = 0;
	    }

	  ok = false;
	  if (start < end)
	    {
	      struct elf_segment_map *lm;
	      const Elf_Internal_Phdr *lp;
	      unsigned int i;

	      /* Find a LOAD segment containing a section in the RELRO
		 segment.  */
	      for (lm = elf_seg_map (abfd), lp = phdrs;
		   lm != NULL;
		   lm = lm->next, lp++)
		{
		  if (lp->p_type == PT_LOAD
		      && lm->count != 0
		      && (lm->sections[lm->count - 1]->vma
			  + (!IS_TBSS (lm->sections[lm->count - 1])
			     ? lm->sections[lm->count - 1]->size / opb
			     : 0)) > start
		      && lm->sections[0]->vma < end)
		    break;
		}

	      if (lm != NULL)
		{
		  /* Find the section starting the RELRO segment.  */
		  for (i = 0; i < lm->count; i++)
		    {
		      asection *s = lm->sections[i];
		      if (s->vma >= start
			  && s->vma < end
			  && s->size != 0)
			break;
		    }

		  if (i < lm->count)
		    {
		      p->p_vaddr = lm->sections[i]->vma * opb;
		      p->p_paddr = lm->sections[i]->lma * opb;
		      p->p_offset = lm->sections[i]->filepos;
		      p->p_memsz = end * opb - p->p_vaddr;
		      p->p_filesz = p->p_memsz;

		      /* The RELRO segment typically ends a few bytes
			 into .got.plt but other layouts are possible.
			 In cases where the end does not match any
			 loaded section (for instance is in file
			 padding), trim p_filesz back to correspond to
			 the end of loaded section contents.  */
		      if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr)
			p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr;

		      /* Preserve the alignment and flags if they are
			 valid.  The gold linker generates RW/4 for
			 the PT_GNU_RELRO section.  It is better for
			 objcopy/strip to honor these attributes
			 otherwise gdb will choke when using separate
			 debug files.  */
		      if (!m->p_align_valid)
			p->p_align = 1;
		      if (!m->p_flags_valid)
			p->p_flags = PF_R;
		      ok = true;
		    }
		}
	    }

	  if (!ok)
	    {
	      if (link_info != NULL)
		_bfd_error_handler
		  (_("%pB: warning: unable to allocate any sections"
		     " to PT_GNU_RELRO segment"),
		   abfd);
	      memset (p, 0, sizeof *p);
	    }
	}
      else if (p->p_type == PT_GNU_STACK)
	{
	  if (m->p_size_valid)
	    p->p_memsz = m->p_size;
	}
      else if (m->count != 0)
	{
	  unsigned int i;

	  if (p->p_type != PT_LOAD
	      && (p->p_type != PT_NOTE
		  || bfd_get_format (abfd) != bfd_core))
	    {
	      /* A user specified segment layout may include a PHDR
		 segment that overlaps with a LOAD segment...  */
	      if (p->p_type == PT_PHDR)
		{
		  m->count = 0;
		  continue;
		}

	      if (m->includes_filehdr || m->includes_phdrs)
		{
		  /* PR 17512: file: 2195325e.  */
		  _bfd_error_handler
		    (_("%pB: error: non-load segment %d includes file header "
		       "and/or program header"),
		     abfd, (int) (p - phdrs));
		  return false;
		}

	      p->p_filesz = 0;
	      p->p_offset = m->sections[0]->filepos;
	      for (i = m->count; i-- != 0;)
		{
		  asection *sect = m->sections[i];
		  Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
		  if (hdr->sh_type != SHT_NOBITS)
		    {
		      p->p_filesz = sect->filepos - p->p_offset + hdr->sh_size;
		      /* NB: p_memsz of the loadable PT_NOTE segment
			 should be the same as p_filesz.  */
		      if (p->p_type == PT_NOTE
			  && (hdr->sh_flags & SHF_ALLOC) != 0)
			p->p_memsz = p->p_filesz;
		      break;
		    }
		}
	    }
	}
    }

  return true;
}

static elf_section_list *
find_section_in_list (unsigned int i, elf_section_list * list)
{
  for (;list != NULL; list = list->next)
    if (list->ndx == i)
      break;
  return list;
}

/* Work out the file positions of all the sections.  This is called by
   _bfd_elf_compute_section_file_positions.  All the section sizes and
   VMAs must be known before this is called.

   Reloc sections come in two flavours: Those processed specially as
   "side-channel" data attached to a section to which they apply, and
   those that bfd doesn't process as relocations.  The latter sort are
   stored in a normal bfd section by bfd_section_from_shdr.  We don't
   consider the former sort here, unless they form part of the loadable
   image.  Reloc sections not assigned here (and compressed debugging
   sections and CTF sections which nothing else in the file can rely
   upon) will be handled later by assign_file_positions_for_relocs.

   We also don't set the positions of the .symtab and .strtab here.  */

static bool
assign_file_positions_except_relocs (bfd *abfd,
				     struct bfd_link_info *link_info)
{
  struct elf_obj_tdata *tdata = elf_tdata (abfd);
  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  unsigned int alloc;

  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
      && bfd_get_format (abfd) != bfd_core)
    {
      Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
      unsigned int num_sec = elf_numsections (abfd);
      Elf_Internal_Shdr **hdrpp;
      unsigned int i;
      file_ptr off;

      /* Start after the ELF header.  */
      off = i_ehdrp->e_ehsize;

      /* We are not creating an executable, which means that we are
	 not creating a program header, and that the actual order of
	 the sections in the file is unimportant.  */
      for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
	{
	  Elf_Internal_Shdr *hdr;

	  hdr = *hdrpp;
	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
	       && hdr->bfd_section == NULL)
	      /* Do not assign offsets for these sections yet: we don't know
		 their sizes.  */
	      || (abfd->is_linker_output
		  && hdr->bfd_section != NULL
		  && (hdr->sh_name == -1u
		      || bfd_section_is_ctf (hdr->bfd_section)))
	      || i == elf_onesymtab (abfd)
	      || (elf_symtab_shndx_list (abfd) != NULL
		  && hdr == i_shdrpp[elf_symtab_shndx_list (abfd)->ndx])
	      || i == elf_strtab_sec (abfd)
	      || i == elf_shstrtab_sec (abfd))
	    {
	      hdr->sh_offset = -1;
	    }
	  else
	    /* There shouldn't be a need to effect "capped" file alignment here,
	       yet at least the Linux kernel's modpost utility was found to be
	       unhappy without.  While the issue was addressed there, let's be
	       kind for at least the foreseeable future ...  */
	    off = _bfd_elf_assign_file_position_for_section (hdr, off, false,
							     bed->s->log_file_align);
	}

      elf_next_file_pos (abfd) = off;
      elf_program_header_size (abfd) = 0;
    }
  else
    {
      /* Assign file positions for the loaded sections based on the
	 assignment of sections to segments.  */
      if (!assign_file_positions_for_load_sections (abfd, link_info))
	return false;

      /* And for non-load sections.  */
      if (!assign_file_positions_for_non_load_sections (abfd, link_info))
	return false;
    }

  if (!(*bed->elf_backend_modify_headers) (abfd, link_info))
    return false;

  /* Write out the program headers.  */
  alloc = i_ehdrp->e_phnum;
  if (alloc != 0)
    {
      if (link_info != NULL && ! link_info->no_warn_rwx_segments)
	{
	  bool warned_tls = false;
	  bool warned_rwx = false;

	  /* Memory resident segments with non-zero size and RWX
	     permissions are a security risk, so we generate a warning
	     here if we are creating any.  */
	  unsigned int i;

	  for (i = 0; i < alloc; i++)
	    {
	      const Elf_Internal_Phdr * phdr = tdata->phdr + i;

	      if (phdr->p_memsz == 0)
		continue;

	      if (! warned_tls
		  && phdr->p_type == PT_TLS
		  && (phdr->p_flags & PF_X))
		{
		  if (link_info->warn_is_error_for_rwx_segments)
		    {
		      _bfd_error_handler (_("\
error: %pB has a TLS segment with execute permission"),
					  abfd);
		      return false;
		    }

		  _bfd_error_handler (_("\
warning: %pB has a TLS segment with execute permission"),
				      abfd);
		  if (warned_rwx)
		    break;

		  warned_tls = true;
		}
	      else if (! warned_rwx
		       && phdr->p_type == PT_LOAD
		       && ((phdr->p_flags & (PF_R | PF_W | PF_X))
			   == (PF_R | PF_W | PF_X)))
		{
		  if (link_info->warn_is_error_for_rwx_segments)
		    {
		      _bfd_error_handler (_("\
error: %pB has a LOAD segment with RWX permissions"),
					  abfd);
		      return false;
		    }

		  _bfd_error_handler (_("\
warning: %pB has a LOAD segment with RWX permissions"),
				      abfd);
		  if (warned_tls)
		    break;

		  warned_rwx = true;
		}
	    }
	}

      if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0
	  || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
	return false;
    }

  return true;
}

bool
_bfd_elf_init_file_header (bfd *abfd,
			   struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form.  */
  struct elf_strtab_hash *shstrtab;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  i_ehdrp = elf_elfheader (abfd);

  shstrtab = _bfd_elf_strtab_init ();
  if (shstrtab == NULL)
    return false;

  elf_shstrtab (abfd) = shstrtab;

  i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
  i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;
  i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;
  i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;

  i_ehdrp->e_ident[EI_CLASS] = bed->s->elfclass;
  i_ehdrp->e_ident[EI_DATA] =
    bfd_big_endian (abfd) ? ELFDATA2MSB : ELFDATA2LSB;
  i_ehdrp->e_ident[EI_VERSION] = bed->s->ev_current;

  if ((abfd->flags & DYNAMIC) != 0)
    i_ehdrp->e_type = ET_DYN;
  else if ((abfd->flags & EXEC_P) != 0)
    i_ehdrp->e_type = ET_EXEC;
  else if (bfd_get_format (abfd) == bfd_core)
    i_ehdrp->e_type = ET_CORE;
  else
    i_ehdrp->e_type = ET_REL;

  switch (bfd_get_arch (abfd))
    {
    case bfd_arch_unknown:
      i_ehdrp->e_machine = EM_NONE;
      break;

      /* There used to be a long list of cases here, each one setting
	 e_machine to the same EM_* macro #defined as ELF_MACHINE_CODE
	 in the corresponding bfd definition.  To avoid duplication,
	 the switch was removed.  Machines that need special handling
	 can generally do it in elf_backend_final_write_processing(),
	 unless they need the information earlier than the final write.
	 Such need can generally be supplied by replacing the tests for
	 e_machine with the conditions used to determine it.  */
    default:
      i_ehdrp->e_machine = bed->elf_machine_code;
    }

  i_ehdrp->e_version = bed->s->ev_current;
  i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;

  /* No program header, for now.  */
  i_ehdrp->e_phoff = 0;
  i_ehdrp->e_phentsize = 0;
  i_ehdrp->e_phnum = 0;

  /* Each bfd section is section header entry.  */
  i_ehdrp->e_entry = bfd_get_start_address (abfd);
  i_ehdrp->e_shentsize = bed->s->sizeof_shdr;

  elf_tdata (abfd)->symtab_hdr.sh_name =
    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", false);
  elf_tdata (abfd)->strtab_hdr.sh_name =
    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", false);
  elf_tdata (abfd)->shstrtab_hdr.sh_name =
    (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", false);
  if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
      || elf_tdata (abfd)->strtab_hdr.sh_name == (unsigned int) -1
      || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
    return false;

  return true;
}

/* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=.

   FIXME: We used to have code here to sort the PT_LOAD segments into
   ascending order, as per the ELF spec.  But this breaks some programs,
   including the Linux kernel.  But really either the spec should be
   changed or the programs updated.  */

bool
_bfd_elf_modify_headers (bfd *obfd, struct bfd_link_info *link_info)
{
  if (link_info != NULL && bfd_link_pie (link_info))
    {
      Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (obfd);
      unsigned int num_segments = i_ehdrp->e_phnum;
      struct elf_obj_tdata *tdata = elf_tdata (obfd);
      Elf_Internal_Phdr *segment = tdata->phdr;
      Elf_Internal_Phdr *end_segment = &segment[num_segments];

      /* Find the lowest p_vaddr in PT_LOAD segments.  */
      bfd_vma p_vaddr = (bfd_vma) -1;
      for (; segment < end_segment; segment++)
	if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
	  p_vaddr = segment->p_vaddr;

      /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
	 segments is non-zero.  */
      if (p_vaddr)
	i_ehdrp->e_type = ET_EXEC;
    }
  return true;
}

/* Assign file positions for all the reloc sections which are not part
   of the loadable file image, and the file position of section headers.  */

static bool
_bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
{
  file_ptr off;
  Elf_Internal_Shdr **shdrpp, **end_shdrpp;
  Elf_Internal_Shdr *shdrp;
  Elf_Internal_Ehdr *i_ehdrp;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  /* Skip non-load sections without section header.  */
  if ((abfd->flags & BFD_NO_SECTION_HEADER) != 0)
    return true;

  off = elf_next_file_pos (abfd);

  shdrpp = elf_elfsections (abfd);
  end_shdrpp = shdrpp + elf_numsections (abfd);
  for (shdrpp++; shdrpp < end_shdrpp; shdrpp++)
    {
      shdrp = *shdrpp;
      if (shdrp->sh_offset == -1)
	{
	  asection *sec = shdrp->bfd_section;
	  if (sec == NULL
	      || shdrp->sh_type == SHT_REL
	      || shdrp->sh_type == SHT_RELA)
	    ;
	  else if (bfd_section_is_ctf (sec))
	    {
	      /* Update section size and contents.	*/
	      shdrp->sh_size = sec->size;
	      shdrp->contents = sec->contents;
	    }
	  else if (shdrp->sh_name == -1u)
	    {
	      const char *name = sec->name;
	      struct bfd_elf_section_data *d;

	      /* Compress DWARF debug sections.  */
	      if (!bfd_compress_section (abfd, sec, shdrp->contents))
		return false;

	      if (sec->compress_status == COMPRESS_SECTION_DONE
		  && (abfd->flags & BFD_COMPRESS_GABI) == 0
		  && name[1] == 'd')
		{
		  /* If section is compressed with zlib-gnu, convert
		     section name from .debug_* to .zdebug_*.  */
		  char *new_name = bfd_debug_name_to_zdebug (abfd, name);
		  if (new_name == NULL)
		    return false;
		  name = new_name;
		}
	      /* Add section name to section name section.  */
	      shdrp->sh_name
		= (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
						      name, false);
	      d = elf_section_data (sec);

	      /* Add reloc section name to section name section.  */
	      if (d->rel.hdr
		  && !_bfd_elf_set_reloc_sh_name (abfd, d->rel.hdr,
						  name, false))
		return false;
	      if (d->rela.hdr
		  && !_bfd_elf_set_reloc_sh_name (abfd, d->rela.hdr,
						  name, true))
		return false;

	      /* Update section size and contents.  */
	      shdrp->sh_size = sec->size;
	      shdrp->contents = sec->contents;
	      sec->contents = NULL;
	    }

	  off = _bfd_elf_assign_file_position_for_section (shdrp, off,
		  (abfd->flags & (EXEC_P | DYNAMIC))
		  || bfd_get_format (abfd) == bfd_core,
		  bed->s->log_file_align);
	}
    }

  /* Place section name section after DWARF debug sections have been
     compressed.  */
  _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
  shdrp = &elf_tdata (abfd)->shstrtab_hdr;
  shdrp->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
  off = _bfd_elf_assign_file_position_for_section (shdrp, off, true, 0);

  /* Place the section headers.  */
  i_ehdrp = elf_elfheader (abfd);
  off = BFD_ALIGN (off, 1u << bed->s->log_file_align);
  i_ehdrp->e_shoff = off;
  off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
  elf_next_file_pos (abfd) = off;

  return true;
}

bool
_bfd_elf_write_object_contents (bfd *abfd)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  Elf_Internal_Shdr **i_shdrp;
  bool failed;
  unsigned int count, num_sec;
  struct elf_obj_tdata *t;

  if (! abfd->output_has_begun
      && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
    return false;
  /* Do not rewrite ELF data when the BFD has been opened for update.
     abfd->output_has_begun was set to TRUE on opening, so creation of
     new sections, and modification of existing section sizes was
     restricted.  This means the ELF header, program headers and
     section headers can't have changed.  If the contents of any
     sections has been modified, then those changes have already been
     written to the BFD.  */
  else if (abfd->direction == both_direction)
    {
      BFD_ASSERT (abfd->output_has_begun);
      return true;
    }

  i_shdrp = elf_elfsections (abfd);

  failed = false;
  bfd_map_over_sections (abfd, bed->s->write_relocs, &failed);
  if (failed)
    return false;

  if (!_bfd_elf_assign_file_positions_for_non_load (abfd))
    return false;

  /* After writing the headers, we need to write the sections too...  */
  num_sec = elf_numsections (abfd);
  for (count = 1; count < num_sec; count++)
    {
      /* Don't set the sh_name field without section header.  */
      if ((abfd->flags & BFD_NO_SECTION_HEADER) == 0)
	i_shdrp[count]->sh_name
	  = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
				    i_shdrp[count]->sh_name);
      if (bed->elf_backend_section_processing)
	if (!(*bed->elf_backend_section_processing) (abfd, i_shdrp[count]))
	  return false;
      if (i_shdrp[count]->contents)
	{
	  bfd_size_type amt = i_shdrp[count]->sh_size;

	  if (bfd_seek (abfd, i_shdrp[count]->sh_offset, SEEK_SET) != 0
	      || bfd_write (i_shdrp[count]->contents, amt, abfd) != amt)
	    return false;
	}
    }

  /* Write out the section header names.  */
  t = elf_tdata (abfd);
  if (elf_shstrtab (abfd) != NULL
      && t->shstrtab_hdr.sh_offset != -1
      && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0
	  || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
    return false;

  if (!(*bed->elf_backend_final_write_processing) (abfd))
    return false;

  if (!bed->s->write_shdrs_and_ehdr (abfd))
    return false;

  /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0].  */
  if (t->o->build_id.after_write_object_contents != NULL
      && !(*t->o->build_id.after_write_object_contents) (abfd))
    return false;
  if (t->o->package_metadata.after_write_object_contents != NULL
      && !(*t->o->package_metadata.after_write_object_contents) (abfd))
    return false;

  return true;
}

bool
_bfd_elf_write_corefile_contents (bfd *abfd)
{
  /* Hopefully this can be done just like an object file.  */
  return _bfd_elf_write_object_contents (abfd);
}

/* Given a section, search the header to find them.  */

unsigned int
_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
{
  const struct elf_backend_data *bed;
  unsigned int sec_index;

  if (elf_section_data (asect) != NULL
      && elf_section_data (asect)->this_idx != 0)
    return elf_section_data (asect)->this_idx;

  if (bfd_is_abs_section (asect))
    sec_index = SHN_ABS;
  else if (bfd_is_com_section (asect))
    sec_index = SHN_COMMON;
  else if (bfd_is_und_section (asect))
    sec_index = SHN_UNDEF;
  else
    sec_index = SHN_BAD;

  bed = get_elf_backend_data (abfd);
  if (bed->elf_backend_section_from_bfd_section)
    {
      int retval = sec_index;

      if ((*bed->elf_backend_section_from_bfd_section) (abfd, asect, &retval))
	return retval;
    }

  if (sec_index == SHN_BAD)
    bfd_set_error (bfd_error_nonrepresentable_section);

  return sec_index;
}

/* Given a BFD symbol, return the index in the ELF symbol table, or -1
   on error.  */

int
_bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
{
  asymbol *asym_ptr = *asym_ptr_ptr;
  int idx;
  flagword flags = asym_ptr->flags;

  /* When gas creates relocations against local labels, it creates its
     own symbol for the section, but does put the symbol into the
     symbol chain, so udata is 0.  When the linker is generating
     relocatable output, this section symbol may be for one of the
     input sections rather than the output section.  */
  if (asym_ptr->udata.i == 0
      && (flags & BSF_SECTION_SYM)
      && asym_ptr->section)
    {
      asection *sec;

      sec = asym_ptr->section;
      if (sec->owner != abfd && sec->output_section != NULL)
	sec = sec->output_section;
      if (sec->owner == abfd
	  && sec->index < elf_num_section_syms (abfd)
	  && elf_section_syms (abfd)[sec->index] != NULL)
	asym_ptr->udata.i = elf_section_syms (abfd)[sec->index]->udata.i;
    }

  idx = asym_ptr->udata.i;

  if (idx == 0)
    {
      /* This case can occur when using --strip-symbol on a symbol
	 which is used in a relocation entry.  */
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: symbol `%s' required but not present"),
	 abfd, bfd_asymbol_name (asym_ptr));
      bfd_set_error (bfd_error_no_symbols);
      return -1;
    }

#if DEBUG & 4
  {
    fprintf (stderr,
	     "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d,"
	     " flags = 0x%.8x\n",
	     (long) asym_ptr, asym_ptr->name, idx, flags);
    fflush (stderr);
  }
#endif

  return idx;
}

static inline bfd_vma
segment_size (Elf_Internal_Phdr *segment)
{
  return (segment->p_memsz > segment->p_filesz
	  ? segment->p_memsz : segment->p_filesz);
}


/* Returns the end address of the segment + 1.  */
static inline bfd_vma
segment_end (Elf_Internal_Phdr *segment, bfd_vma start)
{
  return start + segment_size (segment);
}

static inline bfd_size_type
section_size (asection *section, Elf_Internal_Phdr *segment)
{
  if ((section->flags & SEC_HAS_CONTENTS) != 0
      || (section->flags & SEC_THREAD_LOCAL) == 0
      || segment->p_type == PT_TLS)
    return section->size;
  return 0;
}

/* Returns TRUE if the given section is contained within the given
   segment.  LMA addresses are compared against PADDR when
   USE_VADDR is false, VMA against VADDR when true.  */
static bool
is_contained_by (asection *section, Elf_Internal_Phdr *segment,
		 bfd_vma paddr, bfd_vma vaddr, unsigned int opb,
		 bool use_vaddr)
{
  bfd_vma seg_addr = !use_vaddr ? paddr : vaddr;
  bfd_vma addr = !use_vaddr ? section->lma : section->vma;
  bfd_vma octet;
  if (_bfd_mul_overflow (addr, opb, &octet))
    return false;
  /* The third and fourth lines below are testing that the section end
     address is within the segment.  It's written this way to avoid
     overflow.  Add seg_addr + section_size to both sides of the
     inequality to make it obvious.  */
  return (octet >= seg_addr
	  && segment_size (segment) >= section_size (section, segment)
	  && (octet - seg_addr
	      <= segment_size (segment) - section_size (section, segment)));
}

/* Handle PT_NOTE segment.  */
static bool
is_note (asection *s, Elf_Internal_Phdr *p)
{
  return (p->p_type == PT_NOTE
	  && elf_section_type (s) == SHT_NOTE
	  && (ufile_ptr) s->filepos >= p->p_offset
	  && p->p_filesz >= s->size
	  && (ufile_ptr) s->filepos - p->p_offset <= p->p_filesz - s->size);
}

/* Rewrite program header information.  */

static bool
rewrite_elf_program_header (bfd *ibfd, bfd *obfd, bfd_vma maxpagesize)
{
  Elf_Internal_Ehdr *iehdr;
  struct elf_segment_map *map;
  struct elf_segment_map *map_first;
  struct elf_segment_map **pointer_to_map;
  Elf_Internal_Phdr *segment;
  asection *section;
  unsigned int i;
  unsigned int num_segments;
  bool phdr_included = false;
  bool p_paddr_valid;
  struct elf_segment_map *phdr_adjust_seg = NULL;
  unsigned int phdr_adjust_num = 0;
  const struct elf_backend_data *bed;
  unsigned int opb = bfd_octets_per_byte (ibfd, NULL);

  bed = get_elf_backend_data (ibfd);
  iehdr = elf_elfheader (ibfd);

  map_first = NULL;
  pointer_to_map = &map_first;

  num_segments = elf_elfheader (ibfd)->e_phnum;

  /* The complicated case when p_vaddr is 0 is to handle the Solaris
     linker, which generates a PT_INTERP section with p_vaddr and
     p_memsz set to 0.  */
#define IS_SOLARIS_PT_INTERP(p, s)					\
  (p->p_vaddr == 0							\
   && p->p_paddr == 0							\
   && p->p_memsz == 0							\
   && p->p_filesz > 0							\
   && (s->flags & SEC_HAS_CONTENTS) != 0				\
   && s->size > 0							\
   && (bfd_vma) s->filepos >= p->p_offset				\
   && ((bfd_vma) s->filepos + s->size					\
       <= p->p_offset + p->p_filesz))

  /* Decide if the given section should be included in the given segment.
     A section will be included if:
       1. It is within the address space of the segment -- we use the LMA
	  if that is set for the segment and the VMA otherwise,
       2. It is an allocated section or a NOTE section in a PT_NOTE
	  segment.
       3. There is an output section associated with it,
       4. The section has not already been allocated to a previous segment.
       5. PT_GNU_STACK segments do not include any sections.
       6. PT_TLS segment includes only SHF_TLS sections.
       7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
       8. PT_DYNAMIC should not contain empty sections at the beginning
	  (with the possible exception of .dynamic).  */
#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, opb, paddr_valid)	\
  (((is_contained_by (section, segment, segment->p_paddr,		\
		      segment->p_vaddr, opb, !paddr_valid)		\
     && (section->flags & SEC_ALLOC) != 0)				\
    || is_note (section, segment))					\
   && segment->p_type != PT_GNU_STACK					\
   && (segment->p_type != PT_TLS					\
       || (section->flags & SEC_THREAD_LOCAL))				\
   && (segment->p_type == PT_LOAD					\
       || segment->p_type == PT_TLS					\
       || (section->flags & SEC_THREAD_LOCAL) == 0)			\
   && (segment->p_type != PT_DYNAMIC					\
       || section_size (section, segment) > 0				\
       || (segment->p_paddr						\
	   ? segment->p_paddr != section->lma * (opb)			\
	   : segment->p_vaddr != section->vma * (opb))			\
       || (streq (bfd_section_name (section), ".dynamic")))		\
   && (segment->p_type != PT_LOAD || !section->segment_mark))

/* If the output section of a section in the input segment is NULL,
   it is removed from the corresponding output segment.   */
#define INCLUDE_SECTION_IN_SEGMENT(section, segment, opb, paddr_valid)	\
  (IS_SECTION_IN_INPUT_SEGMENT (section, segment, opb, paddr_valid)	\
   && section->output_section != NULL)

  /* Returns TRUE iff seg1 starts after the end of seg2.  */
#define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)			\
  (seg1->field >= segment_end (seg2, seg2->field))

  /* Returns TRUE iff seg1 and seg2 overlap. Segments overlap iff both
     their VMA address ranges and their LMA address ranges overlap.
     It is possible to have overlapping VMA ranges without overlapping LMA
     ranges.  RedBoot images for example can have both .data and .bss mapped
     to the same VMA range, but with the .data section mapped to a different
     LMA.  */
#define SEGMENT_OVERLAPS(seg1, seg2)					\
  (   !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_vaddr)			\
	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_vaddr))			\
   && !(SEGMENT_AFTER_SEGMENT (seg1, seg2, p_paddr)			\
	|| SEGMENT_AFTER_SEGMENT (seg2, seg1, p_paddr)))

  /* Initialise the segment mark field, and discard stupid alignment.  */
  for (section = ibfd->sections; section != NULL; section = section->next)
    {
      asection *o = section->output_section;
      if (o != NULL && o->alignment_power >= (sizeof (bfd_vma) * 8) - 1)
	o->alignment_power = 0;
      section->segment_mark = false;
    }

  /* The Solaris linker creates program headers in which all the
     p_paddr fields are zero.  When we try to objcopy or strip such a
     file, we get confused.  Check for this case, and if we find it
     don't set the p_paddr_valid fields.  */
  p_paddr_valid = false;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    if (segment->p_paddr != 0)
      {
	p_paddr_valid = true;
	break;
      }

  /* Scan through the segments specified in the program header
     of the input BFD.  For this first scan we look for overlaps
     in the loadable segments.  These can be created by weird
     parameters to objcopy.  Also, fix some solaris weirdness.  */
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    {
      unsigned int j;
      Elf_Internal_Phdr *segment2;

      if (segment->p_type == PT_INTERP)
	for (section = ibfd->sections; section; section = section->next)
	  if (IS_SOLARIS_PT_INTERP (segment, section))
	    {
	      /* Mininal change so that the normal section to segment
		 assignment code will work.  */
	      segment->p_vaddr = section->vma * opb;
	      break;
	    }

      if (segment->p_type != PT_LOAD)
	{
	  /* Remove PT_GNU_RELRO segment.  */
	  if (segment->p_type == PT_GNU_RELRO)
	    segment->p_type = PT_NULL;
	  continue;
	}

      /* Determine if this segment overlaps any previous segments.  */
      for (j = 0, segment2 = elf_tdata (ibfd)->phdr; j < i; j++, segment2++)
	{
	  bfd_signed_vma extra_length;

	  if (segment2->p_type != PT_LOAD
	      || !SEGMENT_OVERLAPS (segment, segment2))
	    continue;

	  /* Merge the two segments together.  */
	  if (segment2->p_vaddr < segment->p_vaddr)
	    {
	      /* Extend SEGMENT2 to include SEGMENT and then delete
		 SEGMENT.  */
	      extra_length = (segment_end (segment, segment->p_vaddr)
			      - segment_end (segment2, segment2->p_vaddr));

	      if (extra_length > 0)
		{
		  segment2->p_memsz += extra_length;
		  segment2->p_filesz += extra_length;
		}

	      segment->p_type = PT_NULL;

	      /* Since we have deleted P we must restart the outer loop.  */
	      i = 0;
	      segment = elf_tdata (ibfd)->phdr;
	      break;
	    }
	  else
	    {
	      /* Extend SEGMENT to include SEGMENT2 and then delete
		 SEGMENT2.  */
	      extra_length = (segment_end (segment2, segment2->p_vaddr)
			      - segment_end (segment, segment->p_vaddr));

	      if (extra_length > 0)
		{
		  segment->p_memsz += extra_length;
		  segment->p_filesz += extra_length;
		}

	      segment2->p_type = PT_NULL;
	    }
	}
    }

  /* The second scan attempts to assign sections to segments.  */
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    {
      unsigned int section_count;
      asection **sections;
      asection *output_section;
      unsigned int isec;
      asection *matching_lma;
      asection *suggested_lma;
      unsigned int j;
      size_t amt;
      asection *first_section;

      if (segment->p_type == PT_NULL)
	continue;

      first_section = NULL;
      /* Compute how many sections might be placed into this segment.  */
      for (section = ibfd->sections, section_count = 0;
	   section != NULL;
	   section = section->next)
	{
	  /* Find the first section in the input segment, which may be
	     removed from the corresponding output segment.   */
	  if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, opb, p_paddr_valid))
	    {
	      if (first_section == NULL)
		first_section = section;
	      if (section->output_section != NULL)
		++section_count;
	    }
	}

      /* Allocate a segment map big enough to contain
	 all of the sections we have selected.  */
      amt = sizeof (struct elf_segment_map) - sizeof (asection *);
      amt += section_count * sizeof (asection *);
      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
      if (map == NULL)
	return false;

      /* Initialise the fields of the segment map.  Default to
	 using the physical address of the segment in the input BFD.  */
      map->next = NULL;
      map->p_type = segment->p_type;
      map->p_flags = segment->p_flags;
      map->p_flags_valid = 1;

      if (map->p_type == PT_LOAD
	  && (ibfd->flags & D_PAGED) != 0
	  && maxpagesize > 1
	  && segment->p_align > 1)
	{
	  map->p_align = segment->p_align;
	  if (segment->p_align > maxpagesize)
	    map->p_align = maxpagesize;
	  map->p_align_valid = 1;
	}

      /* If the first section in the input segment is removed, there is
	 no need to preserve segment physical address in the corresponding
	 output segment.  */
      if (!first_section || first_section->output_section != NULL)
	{
	  map->p_paddr = segment->p_paddr;
	  map->p_paddr_valid = p_paddr_valid;
	}

      /* Determine if this segment contains the ELF file header
	 and if it contains the program headers themselves.  */
      map->includes_filehdr = (segment->p_offset == 0
			       && segment->p_filesz >= iehdr->e_ehsize);
      map->includes_phdrs = 0;

      if (!phdr_included || segment->p_type != PT_LOAD)
	{
	  map->includes_phdrs =
	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
	     && (segment->p_offset + segment->p_filesz
		 >= ((bfd_vma) iehdr->e_phoff
		     + iehdr->e_phnum * iehdr->e_phentsize)));

	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
	    phdr_included = true;
	}

      if (section_count == 0)
	{
	  /* Special segments, such as the PT_PHDR segment, may contain
	     no sections, but ordinary, loadable segments should contain
	     something.  They are allowed by the ELF spec however, so only
	     a warning is produced.
	     Don't warn if an empty PT_LOAD contains the program headers.
	     There is however the valid use case of embedded systems which
	     have segments with p_filesz of 0 and a p_memsz > 0 to initialize
	     flash memory with zeros.  No warning is shown for that case.  */
	  if (segment->p_type == PT_LOAD
	      && !map->includes_phdrs
	      && (segment->p_filesz > 0 || segment->p_memsz == 0))
	    /* xgettext:c-format */
	    _bfd_error_handler
	      (_("%pB: warning: empty loadable segment detected"
		 " at vaddr=%#" PRIx64 ", is this intentional?"),
	       ibfd, (uint64_t) segment->p_vaddr);

	  map->p_vaddr_offset = segment->p_vaddr / opb;
	  map->count = 0;
	  *pointer_to_map = map;
	  pointer_to_map = &map->next;

	  continue;
	}

      /* Now scan the sections in the input BFD again and attempt
	 to add their corresponding output sections to the segment map.
	 The problem here is how to handle an output section which has
	 been moved (ie had its LMA changed).  There are four possibilities:

	 1. None of the sections have been moved.
	    In this case we can continue to use the segment LMA from the
	    input BFD.

	 2. All of the sections have been moved by the same amount.
	    In this case we can change the segment's LMA to match the LMA
	    of the first section.

	 3. Some of the sections have been moved, others have not.
	    In this case those sections which have not been moved can be
	    placed in the current segment which will have to have its size,
	    and possibly its LMA changed, and a new segment or segments will
	    have to be created to contain the other sections.

	 4. The sections have been moved, but not by the same amount.
	    In this case we can change the segment's LMA to match the LMA
	    of the first section and we will have to create a new segment
	    or segments to contain the other sections.

	 In order to save time, we allocate an array to hold the section
	 pointers that we are interested in.  As these sections get assigned
	 to a segment, they are removed from this array.  */

      amt = section_count * sizeof (asection *);
      sections = (asection **) bfd_malloc (amt);
      if (sections == NULL)
	return false;

      /* Step One: Scan for segment vs section LMA conflicts.
	 Also add the sections to the section array allocated above.
	 Also add the sections to the current segment.  In the common
	 case, where the sections have not been moved, this means that
	 we have completely filled the segment, and there is nothing
	 more to do.  */
      isec = 0;
      matching_lma = NULL;
      suggested_lma = NULL;

      for (section = first_section, j = 0;
	   section != NULL;
	   section = section->next)
	{
	  if (INCLUDE_SECTION_IN_SEGMENT (section, segment, opb, p_paddr_valid))
	    {
	      output_section = section->output_section;

	      sections[j++] = section;

	      /* The Solaris native linker always sets p_paddr to 0.
		 We try to catch that case here, and set it to the
		 correct value.  Note - some backends require that
		 p_paddr be left as zero.  */
	      if (!p_paddr_valid
		  && segment->p_vaddr != 0
		  && !bed->want_p_paddr_set_to_zero
		  && isec == 0
		  && output_section->lma != 0
		  && (align_power (segment->p_vaddr
				   + (map->includes_filehdr
				      ? iehdr->e_ehsize : 0)
				   + (map->includes_phdrs
				      ? iehdr->e_phnum * iehdr->e_phentsize
				      : 0),
				   output_section->alignment_power * opb)
		      == (output_section->vma * opb)))
		map->p_paddr = segment->p_vaddr;

	      /* Match up the physical address of the segment with the
		 LMA address of the output section.  */
	      if (is_contained_by (output_section, segment, map->p_paddr,
				   0, opb, false)
		  || is_note (section, segment))
		{
		  if (matching_lma == NULL
		      || output_section->lma < matching_lma->lma)
		    matching_lma = output_section;

		  /* We assume that if the section fits within the segment
		     then it does not overlap any other section within that
		     segment.  */
		  map->sections[isec++] = output_section;
		}
	      else if (suggested_lma == NULL)
		suggested_lma = output_section;

	      if (j == section_count)
		break;
	    }
	}

      BFD_ASSERT (j == section_count);

      /* Step Two: Adjust the physical address of the current segment,
	 if necessary.  */
      if (isec == section_count)
	{
	  /* All of the sections fitted within the segment as currently
	     specified.  This is the default case.  Add the segment to
	     the list of built segments and carry on to process the next
	     program header in the input BFD.  */
	  map->count = section_count;
	  *pointer_to_map = map;
	  pointer_to_map = &map->next;

	  if (p_paddr_valid
	      && !bed->want_p_paddr_set_to_zero)
	    {
	      bfd_vma hdr_size = 0;
	      if (map->includes_filehdr)
		hdr_size = iehdr->e_ehsize;
	      if (map->includes_phdrs)
		hdr_size += iehdr->e_phnum * iehdr->e_phentsize;

	      /* Account for padding before the first section in the
		 segment.  */
	      map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
				     - matching_lma->lma);
	    }

	  free (sections);
	  continue;
	}
      else
	{
	  /* Change the current segment's physical address to match
	     the LMA of the first section that fitted, or if no
	     section fitted, the first section.  */
	  if (matching_lma == NULL)
	    matching_lma = suggested_lma;

	  map->p_paddr = matching_lma->lma * opb;

	  /* Offset the segment physical address from the lma
	     to allow for space taken up by elf headers.  */
	  if (map->includes_phdrs)
	    {
	      map->p_paddr -= iehdr->e_phnum * iehdr->e_phentsize;

	      /* iehdr->e_phnum is just an estimate of the number
		 of program headers that we will need.  Make a note
		 here of the number we used and the segment we chose
		 to hold these headers, so that we can adjust the
		 offset when we know the correct value.  */
	      phdr_adjust_num = iehdr->e_phnum;
	      phdr_adjust_seg = map;
	    }

	  if (map->includes_filehdr)
	    {
	      bfd_vma align = (bfd_vma) 1 << matching_lma->alignment_power;
	      map->p_paddr -= iehdr->e_ehsize;
	      /* We've subtracted off the size of headers from the
		 first section lma, but there may have been some
		 alignment padding before that section too.  Try to
		 account for that by adjusting the segment lma down to
		 the same alignment.  */
	      if (segment->p_align != 0 && segment->p_align < align)
		align = segment->p_align;
	      map->p_paddr &= -(align * opb);
	    }
	}

      /* Step Three: Loop over the sections again, this time assigning
	 those that fit to the current segment and removing them from the
	 sections array; but making sure not to leave large gaps.  Once all
	 possible sections have been assigned to the current segment it is
	 added to the list of built segments and if sections still remain
	 to be assigned, a new segment is constructed before repeating
	 the loop.  */
      isec = 0;
      do
	{
	  map->count = 0;
	  suggested_lma = NULL;

	  /* Fill the current segment with sections that fit.  */
	  for (j = 0; j < section_count; j++)
	    {
	      section = sections[j];

	      if (section == NULL)
		continue;

	      output_section = section->output_section;

	      BFD_ASSERT (output_section != NULL);

	      if (is_contained_by (output_section, segment, map->p_paddr,
				   0, opb, false)
		  || is_note (section, segment))
		{
		  if (map->count == 0)
		    {
		      /* If the first section in a segment does not start at
			 the beginning of the segment, then something is
			 wrong.  */
		      if (align_power (map->p_paddr
				       + (map->includes_filehdr
					  ? iehdr->e_ehsize : 0)
				       + (map->includes_phdrs
					  ? iehdr->e_phnum * iehdr->e_phentsize
					  : 0),
				       output_section->alignment_power * opb)
			  != output_section->lma * opb)
			goto sorry;
		    }
		  else
		    {
		      asection *prev_sec;

		      prev_sec = map->sections[map->count - 1];

		      /* If the gap between the end of the previous section
			 and the start of this section is more than
			 maxpagesize then we need to start a new segment.  */
		      if ((BFD_ALIGN (prev_sec->lma + prev_sec->size,
				      maxpagesize)
			   < BFD_ALIGN (output_section->lma, maxpagesize))
			  || (prev_sec->lma + prev_sec->size
			      > output_section->lma))
			{
			  if (suggested_lma == NULL)
			    suggested_lma = output_section;

			  continue;
			}
		    }

		  map->sections[map->count++] = output_section;
		  ++isec;
		  sections[j] = NULL;
		  if (segment->p_type == PT_LOAD)
		    section->segment_mark = true;
		}
	      else if (suggested_lma == NULL)
		suggested_lma = output_section;
	    }

	  /* PR 23932.  A corrupt input file may contain sections that cannot
	     be assigned to any segment - because for example they have a
	     negative size - or segments that do not contain any sections.
	     But there are also valid reasons why a segment can be empty.
	     So allow a count of zero.  */

	  /* Add the current segment to the list of built segments.  */
	  *pointer_to_map = map;
	  pointer_to_map = &map->next;

	  if (isec < section_count)
	    {
	      /* We still have not allocated all of the sections to
		 segments.  Create a new segment here, initialise it
		 and carry on looping.  */
	      amt = sizeof (struct elf_segment_map) - sizeof (asection *);
	      amt += section_count * sizeof (asection *);
	      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
	      if (map == NULL)
		{
		  free (sections);
		  return false;
		}

	      /* Initialise the fields of the segment map.  Set the physical
		 physical address to the LMA of the first section that has
		 not yet been assigned.  */
	      map->next = NULL;
	      map->p_type = segment->p_type;
	      map->p_flags = segment->p_flags;
	      map->p_flags_valid = 1;
	      map->p_paddr = suggested_lma->lma * opb;
	      map->p_paddr_valid = p_paddr_valid;
	      map->includes_filehdr = 0;
	      map->includes_phdrs = 0;
	    }

	  continue;
	sorry:
	  bfd_set_error (bfd_error_sorry);
	  free (sections);
	  return false;
	}
      while (isec < section_count);

      free (sections);
    }

  elf_seg_map (obfd) = map_first;

  /* If we had to estimate the number of program headers that were
     going to be needed, then check our estimate now and adjust
     the offset if necessary.  */
  if (phdr_adjust_seg != NULL)
    {
      unsigned int count;

      for (count = 0, map = map_first; map != NULL; map = map->next)
	count++;

      if (count > phdr_adjust_num)
	phdr_adjust_seg->p_paddr
	  -= (count - phdr_adjust_num) * iehdr->e_phentsize;

      for (map = map_first; map != NULL; map = map->next)
	if (map->p_type == PT_PHDR)
	  {
	    bfd_vma adjust
	      = phdr_adjust_seg->includes_filehdr ? iehdr->e_ehsize : 0;
	    map->p_paddr = phdr_adjust_seg->p_paddr + adjust;
	    break;
	  }
    }

#undef IS_SOLARIS_PT_INTERP
#undef IS_SECTION_IN_INPUT_SEGMENT
#undef INCLUDE_SECTION_IN_SEGMENT
#undef SEGMENT_AFTER_SEGMENT
#undef SEGMENT_OVERLAPS
  return true;
}

/* Return true if p_align in the ELF program header in ABFD is valid.  */

static bool
elf_is_p_align_valid (bfd *abfd)
{
  unsigned int i;
  Elf_Internal_Phdr *segment;
  unsigned int num_segments;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  bfd_size_type maxpagesize = bed->maxpagesize;
  bfd_size_type p_align = bed->p_align;

  /* Return true if the default p_align value isn't set or the maximum
     page size is the same as the minimum page size.  */
  if (p_align == 0 || maxpagesize == bed->minpagesize)
    return true;

  /* When the default p_align value is set, p_align may be set to the
     default p_align value while segments are aligned to the maximum
     page size.  In this case, the input p_align will be ignored and
     the maximum page size will be used to align the output segments.  */
  segment = elf_tdata (abfd)->phdr;
  num_segments = elf_elfheader (abfd)->e_phnum;
  for (i = 0; i < num_segments; i++, segment++)
    if (segment->p_type == PT_LOAD
	&& (segment->p_align != p_align
	    || vma_page_aligned_bias (segment->p_vaddr,
				      segment->p_offset,
				      maxpagesize) != 0))
      return true;

  return false;
}

/* Copy ELF program header information.  */

static bool
copy_elf_program_header (bfd *ibfd, bfd *obfd)
{
  Elf_Internal_Ehdr *iehdr;
  struct elf_segment_map *map;
  struct elf_segment_map *map_first;
  struct elf_segment_map **pointer_to_map;
  Elf_Internal_Phdr *segment;
  unsigned int i;
  unsigned int num_segments;
  bool phdr_included = false;
  bool p_paddr_valid;
  bool p_palign_valid;
  unsigned int opb = bfd_octets_per_byte (ibfd, NULL);

  iehdr = elf_elfheader (ibfd);

  map_first = NULL;
  pointer_to_map = &map_first;

  /* If all the segment p_paddr fields are zero, don't set
     map->p_paddr_valid.  */
  p_paddr_valid = false;
  num_segments = elf_elfheader (ibfd)->e_phnum;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    if (segment->p_paddr != 0)
      {
	p_paddr_valid = true;
	break;
      }

  p_palign_valid = elf_is_p_align_valid (ibfd);

  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    {
      asection *section;
      unsigned int section_count;
      size_t amt;
      Elf_Internal_Shdr *this_hdr;
      asection *first_section = NULL;
      asection *lowest_section;

      /* Compute how many sections are in this segment.  */
      for (section = ibfd->sections, section_count = 0;
	   section != NULL;
	   section = section->next)
	{
	  this_hdr = &(elf_section_data(section)->this_hdr);
	  if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
	    {
	      if (first_section == NULL)
		first_section = section;
	      section_count++;
	    }
	}

      /* Allocate a segment map big enough to contain
	 all of the sections we have selected.  */
      amt = sizeof (struct elf_segment_map) - sizeof (asection *);
      amt += section_count * sizeof (asection *);
      map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
      if (map == NULL)
	return false;

      /* Initialize the fields of the output segment map with the
	 input segment.  */
      map->next = NULL;
      map->p_type = segment->p_type;
      map->p_flags = segment->p_flags;
      map->p_flags_valid = 1;
      map->p_paddr = segment->p_paddr;
      map->p_paddr_valid = p_paddr_valid;
      map->p_align = segment->p_align;
      /* Keep p_align of PT_GNU_STACK for stack alignment.  */
      map->p_align_valid = (map->p_type == PT_GNU_STACK
			    || p_palign_valid);
      map->p_vaddr_offset = 0;

      if (map->p_type == PT_GNU_RELRO
	  || map->p_type == PT_GNU_STACK)
	{
	  /* The PT_GNU_RELRO segment may contain the first a few
	     bytes in the .got.plt section even if the whole .got.plt
	     section isn't in the PT_GNU_RELRO segment.  We won't
	     change the size of the PT_GNU_RELRO segment.
	     Similarly, PT_GNU_STACK size is significant on uclinux
	     systems.    */
	  map->p_size = segment->p_memsz;
	  map->p_size_valid = 1;
	}

      /* Determine if this segment contains the ELF file header
	 and if it contains the program headers themselves.  */
      map->includes_filehdr = (segment->p_offset == 0
			       && segment->p_filesz >= iehdr->e_ehsize);

      map->includes_phdrs = 0;
      if (! phdr_included || segment->p_type != PT_LOAD)
	{
	  map->includes_phdrs =
	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
	     && (segment->p_offset + segment->p_filesz
		 >= ((bfd_vma) iehdr->e_phoff
		     + iehdr->e_phnum * iehdr->e_phentsize)));

	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
	    phdr_included = true;
	}

      lowest_section = NULL;
      if (section_count != 0)
	{
	  unsigned int isec = 0;

	  for (section = first_section;
	       section != NULL;
	       section = section->next)
	    {
	      this_hdr = &(elf_section_data(section)->this_hdr);
	      if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
		{
		  map->sections[isec++] = section->output_section;
		  if ((section->flags & SEC_ALLOC) != 0)
		    {
		      bfd_vma seg_off;

		      if (lowest_section == NULL
			  || section->lma < lowest_section->lma)
			lowest_section = section;

		      /* Section lmas are set up from PT_LOAD header
			 p_paddr in _bfd_elf_make_section_from_shdr.
			 If this header has a p_paddr that disagrees
			 with the section lma, flag the p_paddr as
			 invalid.  */
		      if ((section->flags & SEC_LOAD) != 0)
			seg_off = this_hdr->sh_offset - segment->p_offset;
		      else
			seg_off = this_hdr->sh_addr - segment->p_vaddr;
		      if (section->lma * opb - segment->p_paddr != seg_off)
			map->p_paddr_valid = false;
		    }
		  if (isec == section_count)
		    break;
		}
	    }
	}

      if (section_count == 0)
	map->p_vaddr_offset = segment->p_vaddr / opb;
      else if (map->p_paddr_valid)
	{
	  /* Account for padding before the first section in the segment.  */
	  bfd_vma hdr_size = 0;
	  if (map->includes_filehdr)
	    hdr_size = iehdr->e_ehsize;
	  if (map->includes_phdrs)
	    hdr_size += iehdr->e_phnum * iehdr->e_phentsize;

	  map->p_vaddr_offset = ((map->p_paddr + hdr_size) / opb
				 - (lowest_section ? lowest_section->lma : 0));
	}

      map->count = section_count;
      *pointer_to_map = map;
      pointer_to_map = &map->next;
    }

  elf_seg_map (obfd) = map_first;
  return true;
}

/* Copy private BFD data.  This copies or rewrites ELF program header
   information.  */

static bool
copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  bfd_vma maxpagesize;

  if (elf_tdata (ibfd)->phdr == NULL)
    return true;

  if (ibfd->xvec == obfd->xvec)
    {
      /* Check to see if any sections in the input BFD
	 covered by ELF program header have changed.  */
      Elf_Internal_Phdr *segment;
      asection * section;
      asection * osec;
      asection * prev;
      unsigned int i, num_segments;
      Elf_Internal_Shdr *this_hdr;
      const struct elf_backend_data *bed;

      bed = get_elf_backend_data (ibfd);

      /* Regenerate the segment map if p_paddr is set to 0.  */
      if (bed->want_p_paddr_set_to_zero)
	goto rewrite;

      /* Initialize the segment mark field.  */
      for (section = obfd->sections; section != NULL;
	   section = section->next)
	section->segment_mark = false;

      num_segments = elf_elfheader (ibfd)->e_phnum;
      for (i = 0, segment = elf_tdata (ibfd)->phdr;
	   i < num_segments;
	   i++, segment++)
	{
	  /* PR binutils/3535.  The Solaris linker always sets the p_paddr
	     and p_memsz fields of special segments (DYNAMIC, INTERP) to 0
	     which severly confuses things, so always regenerate the segment
	     map in this case.  */
	  if (segment->p_paddr == 0
	      && segment->p_memsz == 0
	      && (segment->p_type == PT_INTERP
		  || segment->p_type == PT_DYNAMIC))
	    goto rewrite;

	  for (section = ibfd->sections, prev = NULL;
	       section != NULL; section = section->next)
	    {
	      /* We mark the output section so that we know it comes
		 from the input BFD.  */
	      osec = section->output_section;
	      if (osec)
		osec->segment_mark = true;

	      /* Check if this section is covered by the segment.  */
	      this_hdr = &(elf_section_data(section)->this_hdr);
	      if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
		{
		  /* FIXME: Check if its output section is changed or
		     removed.  What else do we need to check?  */
		  if (osec == NULL
		      || section->flags != osec->flags
		      || section->lma != osec->lma
		      || section->vma != osec->vma
		      || section->size != osec->size
		      || section->rawsize != osec->rawsize
		      || section->alignment_power != osec->alignment_power)
		    goto rewrite;

		  /* PR 31450: If this is an allocated section then make sure
		     that this section's vma to lma relationship is the same
		     as previous (allocated) section's.  */
		  if (prev != NULL
		      && section->flags & SEC_ALLOC
		      && section->lma - section->vma != prev->lma - prev->vma)
		    goto rewrite;

		  if (section->flags & SEC_ALLOC)
		    prev = section;
		}
	    }
	}

      /* Check to see if any output section do not come from the
	 input BFD.  */
      for (section = obfd->sections; section != NULL;
	   section = section->next)
	{
	  if (!section->segment_mark)
	    goto rewrite;
	  else
	    section->segment_mark = false;
	}

      return copy_elf_program_header (ibfd, obfd);
    }

 rewrite:
  maxpagesize = 0;
  if (ibfd->xvec == obfd->xvec)
    {
      /* When rewriting program header, set the output maxpagesize to
	 the maximum alignment of input PT_LOAD segments.  */
      Elf_Internal_Phdr *segment;
      unsigned int i;
      unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;

      for (i = 0, segment = elf_tdata (ibfd)->phdr;
	   i < num_segments;
	   i++, segment++)
	if (segment->p_type == PT_LOAD
	    && maxpagesize < segment->p_align)
	  {
	    /* PR 17512: file: f17299af.  */
	    if (segment->p_align > (bfd_vma) 1 << ((sizeof (bfd_vma) * 8) - 2))
	      /* xgettext:c-format */
	      _bfd_error_handler (_("%pB: warning: segment alignment of %#"
				    PRIx64 " is too large"),
				  ibfd, (uint64_t) segment->p_align);
	    else
	      maxpagesize = segment->p_align;
	  }
    }
  if (maxpagesize == 0)
    maxpagesize = get_elf_backend_data (obfd)->maxpagesize;

  return rewrite_elf_program_header (ibfd, obfd, maxpagesize);
}

/* Copy private section information from input to output.  This function
   is called both by objcopy where LINK_INFO is NULL, and ld where
   LINK_INFO is non-NULL in the usual case but NULL for a special case
   when dealing with LTO IR or cloning output sections.  */

bool
_bfd_elf_copy_private_section_data (bfd *ibfd,
				    asection *isec,
				    bfd *obfd ATTRIBUTE_UNUSED,
				    asection *osec,
				    struct bfd_link_info *link_info)
{
  if (ibfd->xvec->flavour != bfd_target_elf_flavour)
    return true;

  Elf_Internal_Shdr *ihdr = &elf_section_data (isec)->this_hdr;
  Elf_Internal_Shdr *ohdr = &elf_section_data (osec)->this_hdr;
  if (link_info == NULL)
    {
      ohdr->sh_entsize = ihdr->sh_entsize;

      if (ihdr->sh_type == SHT_SYMTAB
	  || ihdr->sh_type == SHT_DYNSYM
	  || ihdr->sh_type == SHT_GNU_verneed
	  || ihdr->sh_type == SHT_GNU_verdef)
	ohdr->sh_info = ihdr->sh_info;
    }

  /* If this is a known ABI section, ELF section type and flags may
     have been set up when OSEC was created.  For normal sections we
     allow the user to override the type and flags other than
     SHF_MASKOS and SHF_MASKPROC.  */
  if (elf_section_type (osec) == SHT_PROGBITS
      || elf_section_type (osec) == SHT_NOTE
      || elf_section_type (osec) == SHT_NOBITS)
    elf_section_type (osec) = SHT_NULL;

  /* For objcopy and relocatable link, copy the ELF section type from
     the input file if the BFD section flags are the same.  (If they
     are different the user may be doing something like
     "objcopy --set-section-flags .text=alloc,data".)  For a final
     link allow some flags that the linker clears to differ.  */
  bool final_link = (link_info != NULL
		     && !bfd_link_relocatable (link_info));
  if (elf_section_type (osec) == SHT_NULL
      && (osec->flags == isec->flags
	  || (final_link
	      && ((osec->flags ^ isec->flags)
		  & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
    elf_section_type (osec) = elf_section_type (isec);

  elf_section_flags (osec) = elf_section_flags (isec);
  /* Like for type, retain flags for objcopy (yet unlike for type, don't do so
     for relocatable link).  Same heuristic as there: If the BFD section flags
     are different, assume --set-section-flags is in use for the section.

     FIXME: Is this correct for all OS/PROC specific flags?  */
  if (link_info != NULL || osec->flags != isec->flags)
    elf_section_flags (osec) &= (SHF_MASKOS | SHF_MASKPROC);
  else
    {
      /* Clear only flags which are set below or elsewhere.  */
      elf_section_flags (osec) &= ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR
				    | SHF_MERGE | SHF_STRINGS | SHF_LINK_ORDER
				    | SHF_INFO_LINK | SHF_GROUP | SHF_TLS
				    | SHF_COMPRESSED);
      if (elf_section_flags (osec) & ~(SHF_MASKOS | SHF_MASKPROC))
	_bfd_error_handler
	  (_("%pB:%pA: warning: retaining unknown section flag(s) %#" PRIx64),
	   ibfd, isec,
	   (uint64_t) (elf_section_flags (osec)
		       & ~(SHF_MASKOS | SHF_MASKPROC)));
    }

  /* Copy sh_info from input for mbind section.  */
  if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
      && elf_section_flags (isec) & SHF_GNU_MBIND)
    elf_section_data (osec)->this_hdr.sh_info
      = elf_section_data (isec)->this_hdr.sh_info;

  /* Set things up for objcopy and relocatable link.  The output
     SHT_GROUP section will have its elf_next_in_group pointing back
     to the input group members.  Ignore linker created group section.
     See elfNN_ia64_object_p in elfxx-ia64.c.  */
  if ((link_info == NULL
       || !link_info->resolve_section_groups)
      && (elf_sec_group (isec) == NULL
	  || (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0))
    {
      if (elf_section_flags (isec) & SHF_GROUP)
	elf_section_flags (osec) |= SHF_GROUP;
      elf_next_in_group (osec) = elf_next_in_group (isec);
      elf_section_data (osec)->group = elf_section_data (isec)->group;
    }

  /* If not decompress, preserve SHF_COMPRESSED.  */
  if (!final_link && (ibfd->flags & BFD_DECOMPRESS) == 0)
    elf_section_flags (osec) |= (elf_section_flags (isec)
				 & SHF_COMPRESSED);

  /* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
     don't use the output section of the linked-to section since it
     may be NULL at this point.  */
  if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
    {
      ohdr->sh_flags |= SHF_LINK_ORDER;
      elf_linked_to_section (osec) = elf_linked_to_section (isec);
    }

  osec->use_rela_p = isec->use_rela_p;

  return true;
}

/* Look at all the SHT_GROUP sections in IBFD, making any adjustments
   necessary if we are removing either the SHT_GROUP section or any of
   the group member sections.  DISCARDED is the value that a section's
   output_section has if the section will be discarded, NULL when this
   function is called from objcopy, bfd_abs_section_ptr when called
   from the linker.  */

bool
_bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
{
  asection *isec;

  for (isec = ibfd->sections; isec != NULL; isec = isec->next)
    if (elf_section_type (isec) == SHT_GROUP)
      {
	asection *first = elf_next_in_group (isec);
	asection *s = first;
	bfd_size_type removed = 0;

	while (s != NULL)
	  {
	    /* If this member section is being output but the
	       SHT_GROUP section is not, then clear the group info
	       set up by _bfd_elf_copy_private_section_data.  */
	    if (s->output_section != discarded
		&& isec->output_section == discarded)
	      {
		elf_section_flags (s->output_section) &= ~SHF_GROUP;
		elf_group_name (s->output_section) = NULL;
	      }
	    else
	      {
		struct bfd_elf_section_data *elf_sec = elf_section_data (s);
		if (s->output_section == discarded
		    && isec->output_section != discarded)
		  {
		    /* Conversely, if the member section is not being
		       output but the SHT_GROUP section is, then adjust
		       its size.  */
		    removed += 4;
		    if (elf_sec->rel.hdr != NULL
			&& (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
		      removed += 4;
		    if (elf_sec->rela.hdr != NULL
			&& (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
		      removed += 4;
		  }
		else
		  {
		    /* Also adjust for zero-sized relocation member
		       section.  */
		    if (elf_sec->rel.hdr != NULL
			&& elf_sec->rel.hdr->sh_size == 0)
		      removed += 4;
		    if (elf_sec->rela.hdr != NULL
			&& elf_sec->rela.hdr->sh_size == 0)
		      removed += 4;
		  }
	      }
	    s = elf_next_in_group (s);
	    if (s == first)
	      break;
	  }
	if (removed != 0)
	  {
	    if (discarded != NULL)
	      {
		/* If we've been called for ld -r, then we need to
		   adjust the input section size.  */
		if (isec->rawsize == 0)
		  isec->rawsize = isec->size;
		isec->size = isec->rawsize - removed;
		if (isec->size <= 4)
		  {
		    isec->size = 0;
		    isec->flags |= SEC_EXCLUDE;
		  }
	      }
	    else if (isec->output_section != NULL)
	      {
		/* Adjust the output section size when called from
		   objcopy. */
		isec->output_section->size -= removed;
		if (isec->output_section->size <= 4)
		  {
		    isec->output_section->size = 0;
		    isec->output_section->flags |= SEC_EXCLUDE;
		  }
	      }
	  }
      }

  return true;
}

/* Copy private header information.  */

bool
_bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
{
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
    return true;

  /* Copy over private BFD data if it has not already been copied.
     This must be done here, rather than in the copy_private_bfd_data
     entry point, because the latter is called after the section
     contents have been set, which means that the program headers have
     already been worked out.  */
  if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL)
    {
      if (! copy_private_bfd_data (ibfd, obfd))
	return false;
    }

  return _bfd_elf_fixup_group_sections (ibfd, NULL);
}

/* Copy private symbol information.  If this symbol is in a section
   which we did not map into a BFD section, try to map the section
   index correctly.  We use special macro definitions for the mapped
   section indices; these definitions are interpreted by the
   swap_out_syms function.  */

#define MAP_ONESYMTAB (SHN_HIOS + 1)
#define MAP_DYNSYMTAB (SHN_HIOS + 2)
#define MAP_STRTAB    (SHN_HIOS + 3)
#define MAP_SHSTRTAB  (SHN_HIOS + 4)
#define MAP_SYM_SHNDX (SHN_HIOS + 5)

bool
_bfd_elf_copy_private_symbol_data (bfd *ibfd,
				   asymbol **isymarg,
				   bfd *obfd ATTRIBUTE_UNUSED,
				   asymbol **osymarg)
{
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
    return true;

  elf_symbol_type *isym = elf_symbol_from (*isymarg);
  elf_symbol_type *osym = elf_symbol_from (*osymarg);
  if (isym != NULL
      && isym->internal_elf_sym.st_shndx != 0
      && osym != NULL
      && bfd_is_abs_section (isym->symbol.section))
    {
      unsigned int shndx;

      shndx = isym->internal_elf_sym.st_shndx;
      if (shndx == elf_onesymtab (ibfd))
	shndx = MAP_ONESYMTAB;
      else if (shndx == elf_dynsymtab (ibfd))
	shndx = MAP_DYNSYMTAB;
      else if (shndx == elf_elfsections (ibfd)[elf_onesymtab (ibfd)]->sh_link)
	shndx = MAP_STRTAB;
      else if (shndx == elf_elfheader (ibfd)->e_shstrndx)
	shndx = MAP_SHSTRTAB;
      else if (find_section_in_list (shndx, elf_symtab_shndx_list (ibfd)))
	shndx = MAP_SYM_SHNDX;
      osym->internal_elf_sym.st_shndx = shndx;
    }

  return true;
}

/* Swap out the symbols.  */

static bool
swap_out_syms (bfd *abfd,
	       struct elf_strtab_hash **sttp,
	       int relocatable_p,
	       struct bfd_link_info *info)
{
  const struct elf_backend_data *bed;
  unsigned int symcount;
  asymbol **syms;
  struct elf_strtab_hash *stt;
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Shdr *symtab_shndx_hdr;
  Elf_Internal_Shdr *symstrtab_hdr;
  struct elf_sym_strtab *symstrtab;
  bfd_byte *outbound_syms;
  bfd_byte *outbound_shndx;
  unsigned long outbound_syms_index;
  unsigned int idx;
  unsigned int num_locals;
  size_t amt;
  bool name_local_sections;

  if (!elf_map_symbols (abfd, &num_locals))
    return false;

  /* Dump out the symtabs.  */
  stt = _bfd_elf_strtab_init ();
  if (stt == NULL)
    return false;

  bed = get_elf_backend_data (abfd);
  symcount = bfd_get_symcount (abfd);
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  symtab_hdr->sh_type = SHT_SYMTAB;
  symtab_hdr->sh_entsize = bed->s->sizeof_sym;
  symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
  symtab_hdr->sh_info = num_locals + 1;
  symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;

  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
  symstrtab_hdr->sh_type = SHT_STRTAB;

  /* Allocate buffer to swap out the .strtab section.  */
  if (_bfd_mul_overflow (symcount + 1, sizeof (*symstrtab), &amt)
      || (symstrtab = (struct elf_sym_strtab *) bfd_malloc (amt)) == NULL)
    {
      bfd_set_error (bfd_error_no_memory);
      _bfd_elf_strtab_free (stt);
      return false;
    }

  if (_bfd_mul_overflow (symcount + 1, bed->s->sizeof_sym, &amt)
      || (outbound_syms = bfd_malloc (amt)) == NULL)
    {
    error_no_mem:
      bfd_set_error (bfd_error_no_memory);
    error_return:
      free (symstrtab);
      _bfd_elf_strtab_free (stt);
      return false;
    }
  symtab_hdr->contents = outbound_syms;
  outbound_syms_index = 0;

  outbound_shndx = NULL;

  if (elf_symtab_shndx_list (abfd))
    {
      symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
      if (symtab_shndx_hdr->sh_name != 0)
	{
	  if (_bfd_mul_overflow (symcount + 1,
				 sizeof (Elf_External_Sym_Shndx), &amt))
	    goto error_no_mem;
	  outbound_shndx =  (bfd_byte *) bfd_zalloc (abfd, amt);
	  if (outbound_shndx == NULL)
	    goto error_return;

	  symtab_shndx_hdr->contents = outbound_shndx;
	  symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
	  symtab_shndx_hdr->sh_size = amt;
	  symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
	  symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
	}
      /* FIXME: What about any other headers in the list ?  */
    }

  /* Now generate the data (for "contents").  */
  {
    /* Fill in zeroth symbol and swap it out.  */
    Elf_Internal_Sym sym;
    sym.st_name = 0;
    sym.st_value = 0;
    sym.st_size = 0;
    sym.st_info = 0;
    sym.st_other = 0;
    sym.st_shndx = SHN_UNDEF;
    sym.st_target_internal = 0;
    symstrtab[outbound_syms_index].sym = sym;
    symstrtab[outbound_syms_index].dest_index = outbound_syms_index;
    outbound_syms_index++;
  }

  name_local_sections
    = (bed->elf_backend_name_local_section_symbols
       && bed->elf_backend_name_local_section_symbols (abfd));

  syms = bfd_get_outsymbols (abfd);
  for (idx = 0; idx < symcount; idx++)
    {
      Elf_Internal_Sym sym;

      flagword flags = syms[idx]->flags;
      if (!name_local_sections
	  && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
	{
	  /* Local section symbols have no name.  */
	  sym.st_name = 0;
	}
      else
	{
	  /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
	     to get the final offset for st_name.  */
	  size_t stridx = _bfd_elf_strtab_add (stt, syms[idx]->name, false);
	  if (stridx == (size_t) -1)
	    goto error_return;
	  sym.st_name = stridx;
	}

      bfd_vma value = syms[idx]->value;
      elf_symbol_type *type_ptr = elf_symbol_from (syms[idx]);
      asection *sec = syms[idx]->section;

      if ((flags & BSF_SECTION_SYM) == 0 && bfd_is_com_section (sec))
	{
	  /* ELF common symbols put the alignment into the `value' field,
	     and the size into the `size' field.  This is backwards from
	     how BFD handles it, so reverse it here.  */
	  sym.st_size = value;
	  if (type_ptr == NULL
	      || type_ptr->internal_elf_sym.st_value == 0)
	    sym.st_value = value >= 16 ? 16 : (1 << bfd_log2 (value));
	  else
	    sym.st_value = type_ptr->internal_elf_sym.st_value;
	  sym.st_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
	}
      else
	{
	  unsigned int shndx;

	  if (sec->output_section)
	    {
	      value += sec->output_offset;
	      sec = sec->output_section;
	    }

	  /* Don't add in the section vma for relocatable output.  */
	  if (! relocatable_p)
	    value += sec->vma;
	  sym.st_value = value;
	  sym.st_size = type_ptr ? type_ptr->internal_elf_sym.st_size : 0;

	  if (bfd_is_abs_section (sec)
	      && type_ptr != NULL
	      && type_ptr->internal_elf_sym.st_shndx != 0)
	    {
	      /* This symbol is in a real ELF section which we did
		 not create as a BFD section.  Undo the mapping done
		 by copy_private_symbol_data.  */
	      shndx = type_ptr->internal_elf_sym.st_shndx;
	      switch (shndx)
		{
		case MAP_ONESYMTAB:
		  shndx = elf_onesymtab (abfd);
		  break;
		case MAP_DYNSYMTAB:
		  shndx = elf_dynsymtab (abfd);
		  break;
		case MAP_STRTAB:
		  shndx = elf_strtab_sec (abfd);
		  break;
		case MAP_SHSTRTAB:
		  shndx = elf_shstrtab_sec (abfd);
		  break;
		case MAP_SYM_SHNDX:
		  if (elf_symtab_shndx_list (abfd))
		    shndx = elf_symtab_shndx_list (abfd)->ndx;
		  break;
		case SHN_COMMON:
		case SHN_ABS:
		  shndx = SHN_ABS;
		  break;
		default:
		  if (shndx >= SHN_LOPROC && shndx <= SHN_HIOS)
		    {
		      if (bed->symbol_section_index)
			shndx = bed->symbol_section_index (abfd, type_ptr);
		      /* Otherwise just leave the index alone.  */
		    }
		  else
		    {
		      if (shndx > SHN_HIOS && shndx < SHN_HIRESERVE)
			_bfd_error_handler (_("%pB: \
Unable to handle section index %x in ELF symbol.  Using ABS instead."),
					  abfd, shndx);
		      shndx = SHN_ABS;
		    }
		  break;
		}
	    }
	  else
	    {
	      shndx = _bfd_elf_section_from_bfd_section (abfd, sec);

	      if (shndx == SHN_BAD)
		{
		  asection *sec2;

		  /* Writing this would be a hell of a lot easier if
		     we had some decent documentation on bfd, and
		     knew what to expect of the library, and what to
		     demand of applications.  For example, it
		     appears that `objcopy' might not set the
		     section of a symbol to be a section that is
		     actually in the output file.  */
		  sec2 = bfd_get_section_by_name (abfd, sec->name);
		  if (sec2 != NULL)
		    shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
		  if (shndx == SHN_BAD)
		    {
		      /* xgettext:c-format */
		      _bfd_error_handler
			(_("unable to find equivalent output section"
			   " for symbol '%s' from section '%s'"),
			 syms[idx]->name ? syms[idx]->name : "<Local sym>",
			 sec->name);
		      bfd_set_error (bfd_error_invalid_operation);
		      goto error_return;
		    }
		}
	    }

	  sym.st_shndx = shndx;
	}

      int type;
      if ((flags & BSF_THREAD_LOCAL) != 0)
	type = STT_TLS;
      else if ((flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
	type = STT_GNU_IFUNC;
      else if ((flags & BSF_FUNCTION) != 0)
	type = STT_FUNC;
      else if ((flags & BSF_OBJECT) != 0)
	type = STT_OBJECT;
      else if ((flags & BSF_RELC) != 0)
	type = STT_RELC;
      else if ((flags & BSF_SRELC) != 0)
	type = STT_SRELC;
      else
	type = STT_NOTYPE;

      if (syms[idx]->section->flags & SEC_THREAD_LOCAL)
	type = STT_TLS;

      /* Processor-specific types.  */
      if (type_ptr != NULL
	  && bed->elf_backend_get_symbol_type)
	type = ((*bed->elf_backend_get_symbol_type)
		(&type_ptr->internal_elf_sym, type));

      if (flags & BSF_SECTION_SYM)
	{
	  if (flags & BSF_GLOBAL)
	    sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_SECTION);
	  else
	    sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
	}
      else if (bfd_is_com_section (syms[idx]->section))
	{
	  if (type != STT_TLS)
	    {
	      if ((abfd->flags & BFD_CONVERT_ELF_COMMON))
		type = ((abfd->flags & BFD_USE_ELF_STT_COMMON)
			? STT_COMMON : STT_OBJECT);
	      else
		type = ((flags & BSF_ELF_COMMON) != 0
			? STT_COMMON : STT_OBJECT);
	    }
	  sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
	}
      else if (bfd_is_und_section (syms[idx]->section))
	sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
				    ? STB_WEAK
				    : STB_GLOBAL),
				   type);
      else if (flags & BSF_FILE)
	sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
      else
	{
	  int bind = STB_LOCAL;

	  if (flags & BSF_LOCAL)
	    bind = STB_LOCAL;
	  else if (flags & BSF_GNU_UNIQUE)
	    bind = STB_GNU_UNIQUE;
	  else if (flags & BSF_WEAK)
	    bind = STB_WEAK;
	  else if (flags & BSF_GLOBAL)
	    bind = STB_GLOBAL;

	  sym.st_info = ELF_ST_INFO (bind, type);
	}

      if (type_ptr != NULL)
	{
	  sym.st_other = type_ptr->internal_elf_sym.st_other;
	  sym.st_target_internal
	    = type_ptr->internal_elf_sym.st_target_internal;
	}
      else
	{
	  sym.st_other = 0;
	  sym.st_target_internal = 0;
	}

      symstrtab[outbound_syms_index].sym = sym;
      symstrtab[outbound_syms_index].dest_index = outbound_syms_index;
      outbound_syms_index++;
    }

  /* Finalize the .strtab section.  */
  _bfd_elf_strtab_finalize (stt);

  /* Swap out the .strtab section.  */
  for (idx = 0; idx < outbound_syms_index; idx++)
    {
      struct elf_sym_strtab *elfsym = &symstrtab[idx];
      if (elfsym->sym.st_name != 0)
	elfsym->sym.st_name = _bfd_elf_strtab_offset (stt,
						      elfsym->sym.st_name);
      if (info && info->callbacks->ctf_new_symbol)
	info->callbacks->ctf_new_symbol (elfsym->dest_index,
					 &elfsym->sym);

      /* Inform the linker of the addition of this symbol.  */

      bed->s->swap_symbol_out (abfd, &elfsym->sym,
			       (outbound_syms
				+ (elfsym->dest_index
				   * bed->s->sizeof_sym)),
			       NPTR_ADD (outbound_shndx,
					 (elfsym->dest_index
					  * sizeof (Elf_External_Sym_Shndx))));
    }
  free (symstrtab);

  *sttp = stt;
  symstrtab_hdr->sh_size = _bfd_elf_strtab_size (stt);
  symstrtab_hdr->sh_type = SHT_STRTAB;
  symstrtab_hdr->sh_flags = bed->elf_strtab_flags;
  symstrtab_hdr->sh_addr = 0;
  symstrtab_hdr->sh_entsize = 0;
  symstrtab_hdr->sh_link = 0;
  symstrtab_hdr->sh_info = 0;
  symstrtab_hdr->sh_addralign = 1;

  return true;
}

/* Return the number of bytes required to hold the symtab vector.

   Note that we base it on the count plus 1, since we will null terminate
   the vector allocated based on this size.  However, the ELF symbol table
   always has a dummy entry as symbol #0, so it ends up even.  */

long
_bfd_elf_get_symtab_upper_bound (bfd *abfd)
{
  bfd_size_type symcount;
  long symtab_size;
  Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr;

  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
  if (symcount > LONG_MAX / sizeof (asymbol *))
    {
      bfd_set_error (bfd_error_file_too_big);
      return -1;
    }
  symtab_size = symcount * (sizeof (asymbol *));
  if (symcount == 0)
    symtab_size = sizeof (asymbol *);
  else if (!bfd_write_p (abfd))
    {
      ufile_ptr filesize = bfd_get_file_size (abfd);

      if (filesize != 0 && (unsigned long) symtab_size > filesize)
	{
	  bfd_set_error (bfd_error_file_truncated);
	  return -1;
	}
    }

  return symtab_size;
}

long
_bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
{
  bfd_size_type symcount;
  long symtab_size;
  Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->dynsymtab_hdr;

  if (elf_dynsymtab (abfd) == 0)
    {
      /* Check if there is dynamic symbol table.  */
      symcount = elf_tdata (abfd)->dt_symtab_count;
      if (symcount)
	goto compute_symtab_size;

      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
  if (symcount > LONG_MAX / sizeof (asymbol *))
    {
      bfd_set_error (bfd_error_file_too_big);
      return -1;
    }

 compute_symtab_size:
  symtab_size = symcount * (sizeof (asymbol *));
  if (symcount == 0)
    symtab_size = sizeof (asymbol *);
  else if (!bfd_write_p (abfd))
    {
      ufile_ptr filesize = bfd_get_file_size (abfd);

      if (filesize != 0 && (unsigned long) symtab_size > filesize)
	{
	  bfd_set_error (bfd_error_file_truncated);
	  return -1;
	}
    }

  return symtab_size;
}

long
_bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
{
  if (asect->reloc_count != 0 && !bfd_write_p (abfd))
    {
      /* Sanity check reloc section size.  */
      ufile_ptr filesize = bfd_get_file_size (abfd);

      if (filesize != 0)
	{
	  struct bfd_elf_section_data *d = elf_section_data (asect);
	  bfd_size_type rel_size = d->rel.hdr ? d->rel.hdr->sh_size : 0;
	  bfd_size_type rela_size = d->rela.hdr ? d->rela.hdr->sh_size : 0;

	  if (rel_size + rela_size > filesize
	      || rel_size + rela_size < rel_size)
	    {
	      bfd_set_error (bfd_error_file_truncated);
	      return -1;
	    }
	}
    }

#if SIZEOF_LONG == SIZEOF_INT
  if (asect->reloc_count >= LONG_MAX / sizeof (arelent *))
    {
      bfd_set_error (bfd_error_file_too_big);
      return -1;
    }
#endif
  return (asect->reloc_count + 1L) * sizeof (arelent *);
}

/* Canonicalize the relocs.  */

long
_bfd_elf_canonicalize_reloc (bfd *abfd,
			     sec_ptr section,
			     arelent **relptr,
			     asymbol **symbols)
{
  arelent *tblptr;
  unsigned int i;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if (! bed->s->slurp_reloc_table (abfd, section, symbols, false))
    return -1;

  tblptr = section->relocation;
  for (i = 0; i < section->reloc_count; i++)
    *relptr++ = tblptr++;

  *relptr = NULL;

  return section->reloc_count;
}

long
_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  long symcount = bed->s->slurp_symbol_table (abfd, allocation, false);

  if (symcount >= 0)
    abfd->symcount = symcount;
  return symcount;
}

long
_bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
				      asymbol **allocation)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  long symcount = bed->s->slurp_symbol_table (abfd, allocation, true);

  if (symcount >= 0)
    abfd->dynsymcount = symcount;
  return symcount;
}

/* Return the size required for the dynamic reloc entries.  Any loadable
   section that was actually installed in the BFD, and has type SHT_REL
   or SHT_RELA, and uses the dynamic symbol table, is considered to be a
   dynamic reloc section.  */

long
_bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
{
  bfd_size_type count, ext_rel_size;
  asection *s;

  if (elf_dynsymtab (abfd) == 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  count = 1;
  ext_rel_size = 0;
  for (s = abfd->sections; s != NULL; s = s->next)
    if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
	&& (elf_section_data (s)->this_hdr.sh_type == SHT_REL
	    || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
	&& (elf_section_data (s)->this_hdr.sh_flags & SHF_COMPRESSED) == 0)
      {
	ext_rel_size += elf_section_data (s)->this_hdr.sh_size;
	if (ext_rel_size < elf_section_data (s)->this_hdr.sh_size)
	  {
	    bfd_set_error (bfd_error_file_truncated);
	    return -1;
	  }
	count += NUM_SHDR_ENTRIES (&elf_section_data (s)->this_hdr);
	if (count > LONG_MAX / sizeof (arelent *))
	  {
	    bfd_set_error (bfd_error_file_too_big);
	    return -1;
	  }
      }
  if (count > 1 && !bfd_write_p (abfd))
    {
      /* Sanity check reloc section sizes.  */
      ufile_ptr filesize = bfd_get_file_size (abfd);
      if (filesize != 0 && ext_rel_size > filesize)
	{
	  bfd_set_error (bfd_error_file_truncated);
	  return -1;
	}
    }
  return count * sizeof (arelent *);
}

/* Canonicalize the dynamic relocation entries.  Note that we return the
   dynamic relocations as a single block, although they are actually
   associated with particular sections; the interface, which was
   designed for SunOS style shared libraries, expects that there is only
   one set of dynamic relocs.  Any loadable section that was actually
   installed in the BFD, and has type SHT_REL or SHT_RELA, and uses the
   dynamic symbol table, is considered to be a dynamic reloc section.  */

long
_bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
				     arelent **storage,
				     asymbol **syms)
{
  bool (*slurp_relocs) (bfd *, asection *, asymbol **, bool);
  asection *s;
  long ret;

  if (elf_dynsymtab (abfd) == 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  ret = 0;
  for (s = abfd->sections; s != NULL; s = s->next)
    {
      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
	  && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
	      || elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
	  && (elf_section_data (s)->this_hdr.sh_flags & SHF_COMPRESSED) == 0)
	{
	  arelent *p;
	  long count, i;

	  if (! (*slurp_relocs) (abfd, s, syms, true))
	    return -1;
	  count = NUM_SHDR_ENTRIES (&elf_section_data (s)->this_hdr);
	  p = s->relocation;
	  for (i = 0; i < count; i++)
	    *storage++ = p++;
	  ret += count;
	}
    }

  *storage = NULL;

  return ret;
}

/* Read in the version information.  */

bool
_bfd_elf_slurp_version_tables (bfd *abfd, bool default_imported_symver)
{
  bfd_byte *contents = NULL;
  unsigned int freeidx = 0;
  size_t amt;
  void *contents_addr = NULL;
  size_t contents_size = 0;

  if (elf_dynverref (abfd) != 0 || elf_tdata (abfd)->dt_verneed != NULL)
    {
      Elf_Internal_Shdr *hdr;
      Elf_External_Verneed *everneed;
      Elf_Internal_Verneed *iverneed;
      unsigned int i;
      bfd_byte *contents_end;
      size_t verneed_count;
      size_t verneed_size;

      if (elf_tdata (abfd)->dt_verneed != NULL)
	{
	  hdr = NULL;
	  contents = elf_tdata (abfd)->dt_verneed;
	  verneed_count = elf_tdata (abfd)->dt_verneed_count;
	  verneed_size = verneed_count * sizeof (Elf_External_Verneed);
	}
      else
	{
	  hdr = &elf_tdata (abfd)->dynverref_hdr;

	  if (hdr->sh_info > hdr->sh_size / sizeof (Elf_External_Verneed))
	    {
	    error_return_bad_verref:
	      _bfd_error_handler
		(_("%pB: .gnu.version_r invalid entry"), abfd);
	      bfd_set_error (bfd_error_bad_value);
	    error_return_verref:
	      elf_tdata (abfd)->verref = NULL;
	      elf_tdata (abfd)->cverrefs = 0;
	      goto error_return;
	    }

	  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
	    goto error_return_verref;
	  contents_size = hdr->sh_size;
	  contents = _bfd_mmap_temporary (abfd, contents_size,
					  &contents_addr, &contents_size);
	  if (contents == NULL)
	    goto error_return_verref;

	  verneed_size = hdr->sh_size;
	  verneed_count = hdr->sh_info;
	}

      if (_bfd_mul_overflow (verneed_count,
			     sizeof (Elf_Internal_Verneed), &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  goto error_return_verref;
	}
      if (amt == 0)
	goto error_return_verref;
      elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) bfd_zalloc (abfd, amt);
      if (elf_tdata (abfd)->verref == NULL)
	goto error_return_verref;

      BFD_ASSERT (sizeof (Elf_External_Verneed)
		  == sizeof (Elf_External_Vernaux));
      contents_end = (contents + verneed_size
		      - sizeof (Elf_External_Verneed));
      everneed = (Elf_External_Verneed *) contents;
      iverneed = elf_tdata (abfd)->verref;
      for (i = 0; i < verneed_count; i++, iverneed++)
	{
	  Elf_External_Vernaux *evernaux;
	  Elf_Internal_Vernaux *ivernaux;
	  unsigned int j;

	  _bfd_elf_swap_verneed_in (abfd, everneed, iverneed);

	  iverneed->vn_bfd = abfd;

	  if (elf_use_dt_symtab_p (abfd))
	    {
	      if (iverneed->vn_file < elf_tdata (abfd)->dt_strsz)
		iverneed->vn_filename
		  = elf_tdata (abfd)->dt_strtab + iverneed->vn_file;
	      else
		iverneed->vn_filename = NULL;
	    }
	  else if (hdr == NULL)
	    goto error_return_bad_verref;
	  else
	    iverneed->vn_filename
	      = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
						 iverneed->vn_file);
	  if (iverneed->vn_filename == NULL)
	    goto error_return_bad_verref;

	  if (iverneed->vn_cnt == 0)
	    iverneed->vn_auxptr = NULL;
	  else
	    {
	      if (_bfd_mul_overflow (iverneed->vn_cnt,
				     sizeof (Elf_Internal_Vernaux), &amt))
		{
		  bfd_set_error (bfd_error_file_too_big);
		  goto error_return_verref;
		}
	      iverneed->vn_auxptr = (struct elf_internal_vernaux *)
		bfd_alloc (abfd, amt);
	      if (iverneed->vn_auxptr == NULL)
		goto error_return_verref;
	    }

	  if (iverneed->vn_aux
	      > (size_t) (contents_end - (bfd_byte *) everneed))
	    goto error_return_bad_verref;

	  evernaux = ((Elf_External_Vernaux *)
		      ((bfd_byte *) everneed + iverneed->vn_aux));
	  ivernaux = iverneed->vn_auxptr;
	  for (j = 0; j < iverneed->vn_cnt; j++, ivernaux++)
	    {
	      _bfd_elf_swap_vernaux_in (abfd, evernaux, ivernaux);

	      if (elf_use_dt_symtab_p (abfd))
		{
		  if (ivernaux->vna_name < elf_tdata (abfd)->dt_strsz)
		    ivernaux->vna_nodename
		      = elf_tdata (abfd)->dt_strtab + ivernaux->vna_name;
		  else
		    ivernaux->vna_nodename = NULL;
		}
	      else if (hdr == NULL)
		goto error_return_bad_verref;
	      else
		ivernaux->vna_nodename
		  = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
						     ivernaux->vna_name);
	      if (ivernaux->vna_nodename == NULL)
		goto error_return_bad_verref;

	      if (ivernaux->vna_other > freeidx)
		freeidx = ivernaux->vna_other;

	      ivernaux->vna_nextptr = NULL;
	      if (ivernaux->vna_next == 0)
		{
		  iverneed->vn_cnt = j + 1;
		  break;
		}
	      if (j + 1 < iverneed->vn_cnt)
		ivernaux->vna_nextptr = ivernaux + 1;

	      if (ivernaux->vna_next
		  > (size_t) (contents_end - (bfd_byte *) evernaux))
		goto error_return_bad_verref;

	      evernaux = ((Elf_External_Vernaux *)
			  ((bfd_byte *) evernaux + ivernaux->vna_next));
	    }

	  iverneed->vn_nextref = NULL;
	  if (iverneed->vn_next == 0)
	    break;
	  if (hdr != NULL && (i + 1 < hdr->sh_info))
	    iverneed->vn_nextref = iverneed + 1;

	  if (iverneed->vn_next
	      > (size_t) (contents_end - (bfd_byte *) everneed))
	    goto error_return_bad_verref;

	  everneed = ((Elf_External_Verneed *)
		      ((bfd_byte *) everneed + iverneed->vn_next));
	}
      elf_tdata (abfd)->cverrefs = i;

      if (contents != elf_tdata (abfd)->dt_verneed)
	_bfd_munmap_temporary (contents_addr, contents_size);
      contents = NULL;
      contents_addr = NULL;
    }

  if (elf_dynverdef (abfd) != 0 || elf_tdata (abfd)->dt_verdef != NULL)
    {
      Elf_Internal_Shdr *hdr;
      Elf_External_Verdef *everdef;
      Elf_Internal_Verdef *iverdef;
      Elf_Internal_Verdef *iverdefarr;
      Elf_Internal_Verdef iverdefmem;
      unsigned int i;
      unsigned int maxidx;
      bfd_byte *contents_end_def, *contents_end_aux;
      size_t verdef_count;
      size_t verdef_size;

      if (elf_tdata (abfd)->dt_verdef != NULL)
	{
	  hdr = NULL;
	  contents = elf_tdata (abfd)->dt_verdef;
	  verdef_count = elf_tdata (abfd)->dt_verdef_count;
	  verdef_size = verdef_count * sizeof (Elf_External_Verdef);
	}
      else
	{
	  hdr = &elf_tdata (abfd)->dynverdef_hdr;

	  if (hdr->sh_size < sizeof (Elf_External_Verdef))
	    {
	    error_return_bad_verdef:
	      _bfd_error_handler
		(_("%pB: .gnu.version_d invalid entry"), abfd);
	      bfd_set_error (bfd_error_bad_value);
	    error_return_verdef:
	      elf_tdata (abfd)->verdef = NULL;
	      elf_tdata (abfd)->cverdefs = 0;
	      goto error_return;
	    }

	  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
	    goto error_return_verdef;
	  contents_size = hdr->sh_size;
	  contents = _bfd_mmap_temporary (abfd, contents_size,
					  &contents_addr, &contents_size);
	  if (contents == NULL)
	    goto error_return_verdef;

	  BFD_ASSERT (sizeof (Elf_External_Verdef)
		      >= sizeof (Elf_External_Verdaux));

	  verdef_count = hdr->sh_info;
	  verdef_size = hdr->sh_size;
	}

      contents_end_def = (contents + verdef_size
			  - sizeof (Elf_External_Verdef));
      contents_end_aux = (contents + verdef_size
			  - sizeof (Elf_External_Verdaux));

      /* We know the number of entries in the section but not the maximum
	 index.  Therefore we have to run through all entries and find
	 the maximum.  */
      everdef = (Elf_External_Verdef *) contents;
      maxidx = 0;
      for (i = 0; i < verdef_count; ++i)
	{
	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);

	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) == 0)
	    goto error_return_bad_verdef;
	  if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
	    maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);

	  if (iverdefmem.vd_next == 0)
	    break;

	  if (iverdefmem.vd_next
	      > (size_t) (contents_end_def - (bfd_byte *) everdef))
	    goto error_return_bad_verdef;

	  everdef = ((Elf_External_Verdef *)
		     ((bfd_byte *) everdef + iverdefmem.vd_next));
	}

      if (default_imported_symver)
	{
	  if (freeidx > maxidx)
	    maxidx = ++freeidx;
	  else
	    freeidx = ++maxidx;
	}
      if (_bfd_mul_overflow (maxidx, sizeof (Elf_Internal_Verdef), &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  goto error_return_verdef;
	}

      if (amt == 0)
	goto error_return_verdef;
      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
      if (elf_tdata (abfd)->verdef == NULL)
	goto error_return_verdef;

      elf_tdata (abfd)->cverdefs = maxidx;

      everdef = (Elf_External_Verdef *) contents;
      iverdefarr = elf_tdata (abfd)->verdef;
      for (i = 0; i < verdef_count; ++i)
	{
	  Elf_External_Verdaux *everdaux;
	  Elf_Internal_Verdaux *iverdaux;
	  unsigned int j;

	  _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);

	  if ((iverdefmem.vd_ndx & VERSYM_VERSION) == 0)
	    goto error_return_bad_verdef;

	  iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
	  memcpy (iverdef, &iverdefmem, offsetof (Elf_Internal_Verdef, vd_bfd));

	  iverdef->vd_bfd = abfd;

	  if (iverdef->vd_cnt == 0)
	    iverdef->vd_auxptr = NULL;
	  else
	    {
	      if (_bfd_mul_overflow (iverdef->vd_cnt,
				     sizeof (Elf_Internal_Verdaux), &amt))
		{
		  bfd_set_error (bfd_error_file_too_big);
		  goto error_return_verdef;
		}
	      iverdef->vd_auxptr = (struct elf_internal_verdaux *)
		bfd_alloc (abfd, amt);
	      if (iverdef->vd_auxptr == NULL)
		goto error_return_verdef;
	    }

	  if (iverdef->vd_aux
	      > (size_t) (contents_end_aux - (bfd_byte *) everdef))
	    goto error_return_bad_verdef;

	  everdaux = ((Elf_External_Verdaux *)
		      ((bfd_byte *) everdef + iverdef->vd_aux));
	  iverdaux = iverdef->vd_auxptr;
	  for (j = 0; j < iverdef->vd_cnt; j++, iverdaux++)
	    {
	      _bfd_elf_swap_verdaux_in (abfd, everdaux, iverdaux);

	      if (elf_use_dt_symtab_p (abfd))
		{
		  if (iverdaux->vda_name < elf_tdata (abfd)->dt_strsz)
		    iverdaux->vda_nodename
		      = elf_tdata (abfd)->dt_strtab + iverdaux->vda_name;
		  else
		    iverdaux->vda_nodename = NULL;
		}
	      else
		iverdaux->vda_nodename
		  = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
						     iverdaux->vda_name);
	      if (iverdaux->vda_nodename == NULL)
		goto error_return_bad_verdef;

	      iverdaux->vda_nextptr = NULL;
	      if (iverdaux->vda_next == 0)
		{
		  iverdef->vd_cnt = j + 1;
		  break;
		}
	      if (j + 1 < iverdef->vd_cnt)
		iverdaux->vda_nextptr = iverdaux + 1;

	      if (iverdaux->vda_next
		  > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
		goto error_return_bad_verdef;

	      everdaux = ((Elf_External_Verdaux *)
			  ((bfd_byte *) everdaux + iverdaux->vda_next));
	    }

	  iverdef->vd_nodename = NULL;
	  if (iverdef->vd_cnt)
	    iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;

	  iverdef->vd_nextdef = NULL;
	  if (iverdef->vd_next == 0)
	    break;
	  if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
	    iverdef->vd_nextdef = iverdef + 1;

	  everdef = ((Elf_External_Verdef *)
		     ((bfd_byte *) everdef + iverdef->vd_next));
	}

      if (contents != elf_tdata (abfd)->dt_verdef)
	_bfd_munmap_temporary (contents_addr, contents_size);
      contents = NULL;
      contents_addr = NULL;
    }
  else if (default_imported_symver)
    {
      if (freeidx < 3)
	freeidx = 3;
      else
	freeidx++;

      if (_bfd_mul_overflow (freeidx, sizeof (Elf_Internal_Verdef), &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  goto error_return;
	}
      if (amt == 0)
	goto error_return;
      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
      if (elf_tdata (abfd)->verdef == NULL)
	goto error_return;

      elf_tdata (abfd)->cverdefs = freeidx;
    }

  /* Create a default version based on the soname.  */
  if (default_imported_symver)
    {
      Elf_Internal_Verdef *iverdef;
      Elf_Internal_Verdaux *iverdaux;

      iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];

      iverdef->vd_version = VER_DEF_CURRENT;
      iverdef->vd_flags = 0;
      iverdef->vd_ndx = freeidx;
      iverdef->vd_cnt = 1;

      iverdef->vd_bfd = abfd;

      iverdef->vd_nodename = bfd_elf_get_dt_soname (abfd);
      if (iverdef->vd_nodename == NULL)
	goto error_return_verdef;
      iverdef->vd_nextdef = NULL;
      iverdef->vd_auxptr = ((struct elf_internal_verdaux *)
			    bfd_zalloc (abfd, sizeof (Elf_Internal_Verdaux)));
      if (iverdef->vd_auxptr == NULL)
	goto error_return_verdef;

      iverdaux = iverdef->vd_auxptr;
      iverdaux->vda_nodename = iverdef->vd_nodename;
    }

  return true;

 error_return:
  if (contents != elf_tdata (abfd)->dt_verneed
      && contents != elf_tdata (abfd)->dt_verdef)
    _bfd_munmap_temporary (contents_addr, contents_size);
  return false;
}

asymbol *
_bfd_elf_make_empty_symbol (bfd *abfd)
{
  elf_symbol_type *newsym;

  newsym = (elf_symbol_type *) bfd_zalloc (abfd, sizeof (*newsym));
  if (!newsym)
    return NULL;
  newsym->symbol.the_bfd = abfd;
  return &newsym->symbol;
}

void
_bfd_elf_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
			  asymbol *symbol,
			  symbol_info *ret)
{
  bfd_symbol_info (symbol, ret);
}

/* Return whether a symbol name implies a local symbol.  Most targets
   use this function for the is_local_label_name entry point, but some
   override it.  */

bool
_bfd_elf_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
			      const char *name)
{
  /* Normal local symbols start with ``.L''.  */
  if (name[0] == '.' && name[1] == 'L')
    return true;

  /* At least some SVR4 compilers (e.g., UnixWare 2.1 cc) generate
     DWARF debugging symbols starting with ``..''.  */
  if (name[0] == '.' && name[1] == '.')
    return true;

  /* gcc will sometimes generate symbols beginning with ``_.L_'' when
     emitting DWARF debugging output.  I suspect this is actually a
     small bug in gcc (it calls ASM_OUTPUT_LABEL when it should call
     ASM_GENERATE_INTERNAL_LABEL, and this causes the leading
     underscore to be emitted on some ELF targets).  For ease of use,
     we treat such symbols as local.  */
  if (name[0] == '_' && name[1] == '.' && name[2] == 'L' && name[3] == '_')
    return true;

  /* Treat assembler generated fake symbols, dollar local labels and
     forward-backward labels (aka local labels) as locals.
     These labels have the form:

       L0^A.*				       (fake symbols)

       [.]?L[0123456789]+{^A|^B}[0123456789]*  (local labels)

     Versions which start with .L will have already been matched above,
     so we only need to match the rest.  */
  if (name[0] == 'L' && ISDIGIT (name[1]))
    {
      bool ret = false;
      const char * p;
      char c;

      for (p = name + 2; (c = *p); p++)
	{
	  if (c == 1 || c == 2)
	    {
	      if (c == 1 && p == name + 2)
		/* A fake symbol.  */
		return true;

	      /* FIXME: We are being paranoid here and treating symbols like
		 L0^Bfoo as if there were non-local, on the grounds that the
		 assembler will never generate them.  But can any symbol
		 containing an ASCII value in the range 1-31 ever be anything
		 other than some kind of local ?  */
	      ret = true;
	    }

	  if (! ISDIGIT (c))
	    {
	      ret = false;
	      break;
	    }
	}
      return ret;
    }

  return false;
}

alent *
_bfd_elf_get_lineno (bfd *abfd ATTRIBUTE_UNUSED,
		     asymbol *symbol ATTRIBUTE_UNUSED)
{
  abort ();
  return NULL;
}

bool
_bfd_elf_set_arch_mach (bfd *abfd,
			enum bfd_architecture arch,
			unsigned long machine)
{
  /* If this isn't the right architecture for this backend, and this
     isn't the generic backend, fail.  */
  if (arch != get_elf_backend_data (abfd)->arch
      && arch != bfd_arch_unknown
      && get_elf_backend_data (abfd)->arch != bfd_arch_unknown)
    return false;

  return bfd_default_set_arch_mach (abfd, arch, machine);
}

/* Find the nearest line to a particular section and offset,
   for error reporting.  */

bool
_bfd_elf_find_nearest_line (bfd *abfd,
			    asymbol **symbols,
			    asection *section,
			    bfd_vma offset,
			    const char **filename_ptr,
			    const char **functionname_ptr,
			    unsigned int *line_ptr,
			    unsigned int *discriminator_ptr)
{
  return _bfd_elf_find_nearest_line_with_alt (abfd, NULL, symbols, section,
					      offset, filename_ptr,
					      functionname_ptr, line_ptr,
					      discriminator_ptr);
}

/* Find the nearest line to a particular section and offset,
   for error reporting.  ALT_BFD representing a .gnu_debugaltlink file
   can be optionally specified.  */

bool
_bfd_elf_find_nearest_line_with_alt (bfd *abfd,
				     const char *alt_filename,
				     asymbol **symbols,
				     asection *section,
				     bfd_vma offset,
				     const char **filename_ptr,
				     const char **functionname_ptr,
				     unsigned int *line_ptr,
				     unsigned int *discriminator_ptr)
{
  bool found;

  if (_bfd_dwarf2_find_nearest_line_with_alt (abfd, alt_filename, symbols, NULL,
					      section, offset, filename_ptr,
					      functionname_ptr, line_ptr,
					      discriminator_ptr,
					      dwarf_debug_sections,
					      &elf_tdata (abfd)->dwarf2_find_line_info))
    return true;

  if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
				     filename_ptr, functionname_ptr, line_ptr))
    {
      if (!*functionname_ptr)
	_bfd_elf_find_function (abfd, symbols, section, offset,
				*filename_ptr ? NULL : filename_ptr,
				functionname_ptr);
      return true;
    }

  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
					     &found, filename_ptr,
					     functionname_ptr, line_ptr,
					     &elf_tdata (abfd)->line_info))
    return false;
  if (found && (*functionname_ptr || *line_ptr))
    return true;

  if (symbols == NULL)
    return false;

  if (! _bfd_elf_find_function (abfd, symbols, section, offset,
				filename_ptr, functionname_ptr))
    return false;

  *line_ptr = 0;
  return true;
}

/* Find the line for a symbol.  */

bool
_bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
		    const char **filename_ptr, unsigned int *line_ptr)
{
  struct elf_obj_tdata *tdata = elf_tdata (abfd);
  return _bfd_dwarf2_find_nearest_line (abfd, symbols, symbol, NULL, 0,
					filename_ptr, NULL, line_ptr, NULL,
					dwarf_debug_sections,
					&tdata->dwarf2_find_line_info);
}

/* After a call to bfd_find_nearest_line, successive calls to
   bfd_find_inliner_info can be used to get source information about
   each level of function inlining that terminated at the address
   passed to bfd_find_nearest_line.  Currently this is only supported
   for DWARF2 with appropriate DWARF3 extensions. */

bool
_bfd_elf_find_inliner_info (bfd *abfd,
			    const char **filename_ptr,
			    const char **functionname_ptr,
			    unsigned int *line_ptr)
{
  struct elf_obj_tdata *tdata = elf_tdata (abfd);
  return _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
					functionname_ptr, line_ptr,
					&tdata->dwarf2_find_line_info);
}

int
_bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  int ret = bed->s->sizeof_ehdr;

  if (!bfd_link_relocatable (info))
    {
      bfd_size_type phdr_size = elf_program_header_size (abfd);

      if (phdr_size == (bfd_size_type) -1)
	{
	  struct elf_segment_map *m;

	  phdr_size = 0;
	  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
	    phdr_size += bed->s->sizeof_phdr;

	  if (phdr_size == 0)
	    phdr_size = get_program_header_size (abfd, info);
	}

      elf_program_header_size (abfd) = phdr_size;
      ret += phdr_size;
    }

  return ret;
}

bool
_bfd_elf_set_section_contents (bfd *abfd,
			       sec_ptr section,
			       const void *location,
			       file_ptr offset,
			       bfd_size_type count)
{
  Elf_Internal_Shdr *hdr;

  if (! abfd->output_has_begun
      && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
    return false;

  if (!count)
    return true;

  hdr = &elf_section_data (section)->this_hdr;
  if (hdr->sh_offset == (file_ptr) -1)
    {
      unsigned char *contents;

      if (bfd_section_is_ctf (section))
	/* Nothing to do with this section: the contents are generated
	   later.  */
	return true;

      if ((offset + count) > hdr->sh_size)
	{
	  _bfd_error_handler
	    (_("%pB:%pA: error: attempting to write"
	       " over the end of the section"),
	     abfd, section);

	  bfd_set_error (bfd_error_invalid_operation);
	  return false;
	}

      contents = hdr->contents;
      if (contents == NULL)
	{
	  _bfd_error_handler
	    (_("%pB:%pA: error: attempting to write"
	       " section into an empty buffer"),
	     abfd, section);

	  bfd_set_error (bfd_error_invalid_operation);
	  return false;
	}

      memcpy (contents + offset, location, count);
      return true;
    }

  return _bfd_generic_set_section_contents (abfd, section,
					    location, offset, count);
}

bool
_bfd_elf_no_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
			   arelent *cache_ptr ATTRIBUTE_UNUSED,
			   Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
{
  abort ();
  return false;
}

/* Try to convert a non-ELF reloc into an ELF one.  */

bool
_bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
{
  /* Check whether we really have an ELF howto.  */

  if ((*areloc->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec)
    {
      bfd_reloc_code_real_type code;
      reloc_howto_type *howto;

      /* Alien reloc: Try to determine its type to replace it with an
	 equivalent ELF reloc.  */

      if (areloc->howto->pc_relative)
	{
	  switch (areloc->howto->bitsize)
	    {
	    case 8:
	      code = BFD_RELOC_8_PCREL;
	      break;
	    case 12:
	      code = BFD_RELOC_12_PCREL;
	      break;
	    case 16:
	      code = BFD_RELOC_16_PCREL;
	      break;
	    case 24:
	      code = BFD_RELOC_24_PCREL;
	      break;
	    case 32:
	      code = BFD_RELOC_32_PCREL;
	      break;
	    case 64:
	      code = BFD_RELOC_64_PCREL;
	      break;
	    default:
	      goto fail;
	    }

	  howto = bfd_reloc_type_lookup (abfd, code);

	  if (howto && areloc->howto->pcrel_offset != howto->pcrel_offset)
	    {
	      if (howto->pcrel_offset)
		areloc->addend += areloc->address;
	      else
		areloc->addend -= areloc->address; /* addend is unsigned!! */
	    }
	}
      else
	{
	  switch (areloc->howto->bitsize)
	    {
	    case 8:
	      code = BFD_RELOC_8;
	      break;
	    case 14:
	      code = BFD_RELOC_14;
	      break;
	    case 16:
	      code = BFD_RELOC_16;
	      break;
	    case 26:
	      code = BFD_RELOC_26;
	      break;
	    case 32:
	      code = BFD_RELOC_32;
	      break;
	    case 64:
	      code = BFD_RELOC_64;
	      break;
	    default:
	      goto fail;
	    }

	  howto = bfd_reloc_type_lookup (abfd, code);
	}

      if (howto)
	areloc->howto = howto;
      else
	goto fail;
    }

  return true;

 fail:
  /* xgettext:c-format */
  _bfd_error_handler (_("%pB: %s unsupported"),
		      abfd, areloc->howto->name);
  bfd_set_error (bfd_error_sorry);
  return false;
}

bool
_bfd_elf_free_cached_info (bfd *abfd)
{
  struct elf_obj_tdata *tdata;

  if ((bfd_get_format (abfd) == bfd_object
       || bfd_get_format (abfd) == bfd_core)
      && (tdata = elf_tdata (abfd)) != NULL)
    {
      if (tdata->o != NULL && elf_shstrtab (abfd) != NULL)
	_bfd_elf_strtab_free (elf_shstrtab (abfd));
      _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
      _bfd_dwarf1_cleanup_debug_info (abfd, &tdata->dwarf1_find_line_info);
      _bfd_stab_cleanup (abfd, &tdata->line_info);
      for (asection *sec = abfd->sections; sec != NULL; sec = sec->next)
	{
	  _bfd_elf_munmap_section_contents (sec, sec->contents);
	  if (!sec->alloced)
	    {
	      free (elf_section_data (sec)->this_hdr.contents);
	      elf_section_data (sec)->this_hdr.contents = NULL;
	    }
	  free (elf_section_data (sec)->relocs);
	  elf_section_data (sec)->relocs = NULL;
	  if (sec->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
	    {
	      struct eh_frame_sec_info *sec_info = sec->sec_info;
	      free (sec_info->cies);
	    }
	}
      free (tdata->symtab_hdr.contents);
      tdata->symtab_hdr.contents = NULL;
    }

  return _bfd_generic_bfd_free_cached_info (abfd);
}

/* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY
   in the relocation's offset.  Thus we cannot allow any sort of sanity
   range-checking to interfere.  There is nothing else to do in processing
   this reloc.  */

bfd_reloc_status_type
_bfd_elf_rel_vtable_reloc_fn
  (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
   struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
   void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
   bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
{
  return bfd_reloc_ok;
}

/* Elf core file support.  Much of this only works on native
   toolchains, since we rely on knowing the
   machine-dependent procfs structure in order to pick
   out details about the corefile.  */

#ifdef HAVE_SYS_PROCFS_H
# include <sys/procfs.h>
#endif

/* Return a PID that identifies a "thread" for threaded cores, or the
   PID of the main process for non-threaded cores.  */

static int
elfcore_make_pid (bfd *abfd)
{
  int pid;

  pid = elf_tdata (abfd)->core->lwpid;
  if (pid == 0)
    pid = elf_tdata (abfd)->core->pid;

  return pid;
}

/* If there isn't a section called NAME, make one, using data from
   SECT.  Note, this function will generate a reference to NAME, so
   you shouldn't deallocate or overwrite it.  */

static bool
elfcore_maybe_make_sect (bfd *abfd, char *name, asection *sect)
{
  asection *sect2;

  if (bfd_get_section_by_name (abfd, name) != NULL)
    return true;

  sect2 = bfd_make_section_with_flags (abfd, name, sect->flags);
  if (sect2 == NULL)
    return false;

  sect2->size = sect->size;
  sect2->filepos = sect->filepos;
  sect2->alignment_power = sect->alignment_power;
  return true;
}

/* Create a pseudosection containing SIZE bytes at FILEPOS.  This
   actually creates up to two pseudosections:
   - For the single-threaded case, a section named NAME, unless
     such a section already exists.
   - For the multi-threaded case, a section named "NAME/PID", where
     PID is elfcore_make_pid (abfd).
   Both pseudosections have identical contents.  */
bool
_bfd_elfcore_make_pseudosection (bfd *abfd,
				 char *name,
				 size_t size,
				 ufile_ptr filepos)
{
  char buf[100];
  char *threaded_name;
  size_t len;
  asection *sect;

  /* Build the section name.  */

  sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
  len = strlen (buf) + 1;
  threaded_name = (char *) bfd_alloc (abfd, len);
  if (threaded_name == NULL)
    return false;
  memcpy (threaded_name, buf, len);

  sect = bfd_make_section_anyway_with_flags (abfd, threaded_name,
					     SEC_HAS_CONTENTS);
  if (sect == NULL)
    return false;
  sect->size = size;
  sect->filepos = filepos;
  sect->alignment_power = 2;

  return elfcore_maybe_make_sect (abfd, name, sect);
}

static bool
elfcore_make_auxv_note_section (bfd *abfd, Elf_Internal_Note *note,
				size_t offs)
{
  asection *sect = bfd_make_section_anyway_with_flags (abfd, ".auxv",
						       SEC_HAS_CONTENTS);

  if (sect == NULL)
    return false;

  sect->size = note->descsz - offs;
  sect->filepos = note->descpos + offs;
  sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;

  return true;
}

/* prstatus_t exists on:
     solaris 2.5+
     linux 2.[01] + glibc
     unixware 4.2
*/

#if defined (HAVE_PRSTATUS_T)

static bool
elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  size_t size;
  int offset;

  if (note->descsz == sizeof (prstatus_t))
    {
      prstatus_t prstat;

      size = sizeof (prstat.pr_reg);
      offset   = offsetof (prstatus_t, pr_reg);
      memcpy (&prstat, note->descdata, sizeof (prstat));

      /* Do not overwrite the core signal if it
	 has already been set by another thread.  */
      if (elf_tdata (abfd)->core->signal == 0)
	elf_tdata (abfd)->core->signal = prstat.pr_cursig;
      if (elf_tdata (abfd)->core->pid == 0)
	elf_tdata (abfd)->core->pid = prstat.pr_pid;

      /* pr_who exists on:
	 solaris 2.5+
	 unixware 4.2
	 pr_who doesn't exist on:
	 linux 2.[01]
	 */
#if defined (HAVE_PRSTATUS_T_PR_WHO)
      elf_tdata (abfd)->core->lwpid = prstat.pr_who;
#else
      elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
#endif
    }
#if defined (HAVE_PRSTATUS32_T)
  else if (note->descsz == sizeof (prstatus32_t))
    {
      /* 64-bit host, 32-bit corefile */
      prstatus32_t prstat;

      size = sizeof (prstat.pr_reg);
      offset   = offsetof (prstatus32_t, pr_reg);
      memcpy (&prstat, note->descdata, sizeof (prstat));

      /* Do not overwrite the core signal if it
	 has already been set by another thread.  */
      if (elf_tdata (abfd)->core->signal == 0)
	elf_tdata (abfd)->core->signal = prstat.pr_cursig;
      if (elf_tdata (abfd)->core->pid == 0)
	elf_tdata (abfd)->core->pid = prstat.pr_pid;

      /* pr_who exists on:
	 solaris 2.5+
	 unixware 4.2
	 pr_who doesn't exist on:
	 linux 2.[01]
	 */
#if defined (HAVE_PRSTATUS32_T_PR_WHO)
      elf_tdata (abfd)->core->lwpid = prstat.pr_who;
#else
      elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
#endif
    }
#endif /* HAVE_PRSTATUS32_T */
  else
    {
      /* Fail - we don't know how to handle any other
	 note size (ie. data object type).  */
      return true;
    }

  /* Make a ".reg/999" section and a ".reg" section.  */
  return _bfd_elfcore_make_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG,
					  size, note->descpos + offset);
}
#endif /* defined (HAVE_PRSTATUS_T) */

/* Create a pseudosection containing the exact contents of NOTE.  */
static bool
elfcore_make_note_pseudosection (bfd *abfd,
				 char *name,
				 Elf_Internal_Note *note)
{
  return _bfd_elfcore_make_pseudosection (abfd, name,
					  note->descsz, note->descpos);
}

/* There isn't a consistent prfpregset_t across platforms,
   but it doesn't matter, because we don't have to pick this
   data structure apart.  */

static bool
elfcore_grok_prfpreg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG2, note);
}

/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
   type of NT_PRXFPREG.  Just include the whole note's contents
   literally.  */

static bool
elfcore_grok_prxfpreg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_XFP, note);
}

/* Linux dumps the Intel XSAVE extended state in a note named "LINUX"
   with a note type of NT_X86_XSTATE.  Just include the whole note's
   contents literally.  */

static bool
elfcore_grok_xstatereg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_XSTATE, note);
}

static bool
elfcore_grok_sspreg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_SSP, note);
}

static bool
elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_VMX, note);
}

static bool
elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_VSX, note);
}

static bool
elfcore_grok_ppc_tar (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TAR, note);
}

static bool
elfcore_grok_ppc_ppr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_PPR, note);
}

static bool
elfcore_grok_ppc_dscr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_DSCR, note);
}

static bool
elfcore_grok_ppc_ebb (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_EBB, note);
}

static bool
elfcore_grok_ppc_pmu (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_PMU, note);
}

static bool
elfcore_grok_ppc_tm_cgpr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CGPR, note);
}

static bool
elfcore_grok_ppc_tm_cfpr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CFPR, note);
}

static bool
elfcore_grok_ppc_tm_cvmx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CVMX, note);
}

static bool
elfcore_grok_ppc_tm_cvsx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CVSX, note);
}

static bool
elfcore_grok_ppc_tm_spr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_SPR, note);
}

static bool
elfcore_grok_ppc_tm_ctar (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CTAR, note);
}

static bool
elfcore_grok_ppc_tm_cppr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CPPR, note);
}

static bool
elfcore_grok_ppc_tm_cdscr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_PPC_TM_CDSCR, note);
}

static bool
elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_HIGH_GPRS, note);
}

static bool
elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_TIMER, note);
}

static bool
elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_TODCMP, note);
}

static bool
elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_TODPREG, note);
}

static bool
elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_CTRS, note);
}

static bool
elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_PREFIX, note);
}

static bool
elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_LAST_BREAK, note);
}

static bool
elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_SYSTEM_CALL, note);
}

static bool
elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_TDB, note);
}

static bool
elfcore_grok_s390_vxrs_low (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_VXRS_LOW, note);
}

static bool
elfcore_grok_s390_vxrs_high (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_VXRS_HIGH, note);
}

static bool
elfcore_grok_s390_gs_cb (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_GS_CB, note);
}

static bool
elfcore_grok_s390_gs_bc (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_S390_GS_BC, note);
}

static bool
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_ARM_VFP, note);
}

static bool
elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_TLS, note);
}

static bool
elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_HW_BREAK, note);
}

static bool
elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_HW_WATCH, note);
}

static bool
elfcore_grok_aarch_sve (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_SVE, note);
}

static bool
elfcore_grok_aarch_pauth (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_PAUTH, note);
}

static bool
elfcore_grok_aarch_mte (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_MTE, note);
}

static bool
elfcore_grok_aarch_ssve (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_SSVE, note);
}

static bool
elfcore_grok_aarch_za (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_ZA, note);
}

/* Convert NOTE into a bfd_section called ".reg-aarch-zt".  Return TRUE if
   successful, otherwise return FALSE.  */

static bool
elfcore_grok_aarch_zt (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_ZT, note);
}

/* Convert NOTE into a bfd_section called ".reg-aarch-gcs".  Return TRUE if
   successful, otherwise return FALSE.  */

static bool
elfcore_grok_aarch_gcs (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_GCS, note);
}

/* Convert NOTE into the appropriate note pseudo-section for the AArch64 FPMR.
 * Return TRUE if successful, otherwise return FALSE.  */

static bool
elfcore_grok_aarch_fpmr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_AARCH_FPMR, note);
}

static bool
elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_ARC_V2, note);
}

/* Convert NOTE into a bfd_section called ".reg-riscv-csr".  Return TRUE if
   successful otherwise, return FALSE.  */

static bool
elfcore_grok_riscv_csr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_RISCV_CSR, note);
}

/* Convert NOTE into a bfd_section called ".gdb-tdesc".  Return TRUE if
   successful otherwise, return FALSE.  */

static bool
elfcore_grok_gdb_tdesc (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".gdb-tdesc", note);
}

static bool
elfcore_grok_i386_tls (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_I386_TLS,
					  note);
}

static bool
elfcore_grok_loongarch_cpucfg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_LOONGARCH_CPUCFG, note);
}

static bool
elfcore_grok_loongarch_lbt (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_LOONGARCH_LBT, note);
}

static bool
elfcore_grok_loongarch_lsx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_LOONGARCH_LSX, note);
}

static bool
elfcore_grok_loongarch_lasx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_LOONGARCH_LASX, note);
}

#if defined (HAVE_PRPSINFO_T)
typedef prpsinfo_t   elfcore_psinfo_t;
#if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
typedef prpsinfo32_t elfcore_psinfo32_t;
#endif
#endif

#if defined (HAVE_PSINFO_T)
typedef psinfo_t   elfcore_psinfo_t;
#if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
typedef psinfo32_t elfcore_psinfo32_t;
#endif
#endif

/* return a malloc'ed copy of a string at START which is at
   most MAX bytes long, possibly without a terminating '\0'.
   the copy will always have a terminating '\0'.  */

char *
_bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
{
  char *dups;
  char *end = (char *) memchr (start, '\0', max);
  size_t len;

  if (end == NULL)
    len = max;
  else
    len = end - start;

  dups = (char *) bfd_alloc (abfd, len + 1);
  if (dups == NULL)
    return NULL;

  memcpy (dups, start, len);
  dups[len] = '\0';

  return dups;
}

#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
static bool
elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
  if (note->descsz == sizeof (elfcore_psinfo_t))
    {
      elfcore_psinfo_t psinfo;

      memcpy (&psinfo, note->descdata, sizeof (psinfo));

#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
      elf_tdata (abfd)->core->pid = psinfo.pr_pid;
#endif
      elf_tdata (abfd)->core->program
	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
				sizeof (psinfo.pr_fname));

      elf_tdata (abfd)->core->command
	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
				sizeof (psinfo.pr_psargs));
    }
#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
  else if (note->descsz == sizeof (elfcore_psinfo32_t))
    {
      /* 64-bit host, 32-bit corefile */
      elfcore_psinfo32_t psinfo;

      memcpy (&psinfo, note->descdata, sizeof (psinfo));

#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
      elf_tdata (abfd)->core->pid = psinfo.pr_pid;
#endif
      elf_tdata (abfd)->core->program
	= _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
				sizeof (psinfo.pr_fname));

      elf_tdata (abfd)->core->command
	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
				sizeof (psinfo.pr_psargs));
    }
#endif

  else
    {
      /* Fail - we don't know how to handle any other
	 note size (ie. data object type).  */
      return true;
    }

  /* Note that for some reason, a spurious space is tacked
     onto the end of the args in some (at least one anyway)
     implementations, so strip it off if it exists.  */

  {
    char *command = elf_tdata (abfd)->core->command;
    int n = strlen (command);

    if (0 < n && command[n - 1] == ' ')
      command[n - 1] = '\0';
  }

  return true;
}
#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */

#if defined (HAVE_PSTATUS_T)
static bool
elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
{
  if (note->descsz == sizeof (pstatus_t)
#if defined (HAVE_PXSTATUS_T)
      || note->descsz == sizeof (pxstatus_t)
#endif
      )
    {
      pstatus_t pstat;

      memcpy (&pstat, note->descdata, sizeof (pstat));

      elf_tdata (abfd)->core->pid = pstat.pr_pid;
    }
#if defined (HAVE_PSTATUS32_T)
  else if (note->descsz == sizeof (pstatus32_t))
    {
      /* 64-bit host, 32-bit corefile */
      pstatus32_t pstat;

      memcpy (&pstat, note->descdata, sizeof (pstat));

      elf_tdata (abfd)->core->pid = pstat.pr_pid;
    }
#endif
  /* Could grab some more details from the "representative"
     lwpstatus_t in pstat.pr_lwp, but we'll catch it all in an
     NT_LWPSTATUS note, presumably.  */

  return true;
}
#endif /* defined (HAVE_PSTATUS_T) */

#if defined (HAVE_LWPSTATUS_T)
static bool
elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
{
  lwpstatus_t lwpstat;
  char buf[100];
  char *name;
  size_t len;
  asection *sect;

  if (note->descsz != sizeof (lwpstat)
#if defined (HAVE_LWPXSTATUS_T)
      && note->descsz != sizeof (lwpxstatus_t)
#endif
      )
    return true;

  memcpy (&lwpstat, note->descdata, sizeof (lwpstat));

  elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
  /* Do not overwrite the core signal if it has already been set by
     another thread.  */
  if (elf_tdata (abfd)->core->signal == 0)
    elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;

  /* Make a ".reg/999" section.  */

  sprintf (buf, NOTE_PSEUDO_SECTION_REG "/%d", elfcore_make_pid (abfd));
  len = strlen (buf) + 1;
  name = bfd_alloc (abfd, len);
  if (name == NULL)
    return false;
  memcpy (name, buf, len);

  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  if (sect == NULL)
    return false;

#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
  sect->size = sizeof (lwpstat.pr_context.uc_mcontext.gregs);
  sect->filepos = note->descpos
    + offsetof (lwpstatus_t, pr_context.uc_mcontext.gregs);
#endif

#if defined (HAVE_LWPSTATUS_T_PR_REG)
  sect->size = sizeof (lwpstat.pr_reg);
  sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_reg);
#endif

  sect->alignment_power = 2;

  if (!elfcore_maybe_make_sect (abfd, NOTE_PSEUDO_SECTION_REG, sect))
    return false;

  /* Make a ".reg2/999" section */

  sprintf (buf, NOTE_PSEUDO_SECTION_REG2 "/%d", elfcore_make_pid (abfd));
  len = strlen (buf) + 1;
  name = bfd_alloc (abfd, len);
  if (name == NULL)
    return false;
  memcpy (name, buf, len);

  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  if (sect == NULL)
    return false;

#if defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
  sect->size = sizeof (lwpstat.pr_context.uc_mcontext.fpregs);
  sect->filepos = note->descpos
    + offsetof (lwpstatus_t, pr_context.uc_mcontext.fpregs);
#endif

#if defined (HAVE_LWPSTATUS_T_PR_FPREG)
  sect->size = sizeof (lwpstat.pr_fpreg);
  sect->filepos = note->descpos + offsetof (lwpstatus_t, pr_fpreg);
#endif

  sect->alignment_power = 2;

  return elfcore_maybe_make_sect (abfd, NOTE_PSEUDO_SECTION_REG2, sect);
}
#endif /* defined (HAVE_LWPSTATUS_T) */

/* These constants, and the structure offsets used below, are defined by
   Cygwin's core_dump.h */
#define NOTE_INFO_PROCESS  1
#define NOTE_INFO_THREAD   2
#define NOTE_INFO_MODULE   3
#define NOTE_INFO_MODULE64 4

static bool
elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
{
  char buf[30];
  char *name;
  size_t len;
  unsigned int name_size;
  asection *sect;
  unsigned int type;
  int is_active_thread;
  bfd_vma base_addr;

  if (note->descsz < 4)
    return true;

  if (! startswith (note->namedata, "win32"))
    return true;

  type = bfd_get_32 (abfd, note->descdata);

  static const struct
  {
    const char *type_name;
    unsigned long min_size;
  } size_check[] =
      {
       { "NOTE_INFO_PROCESS", 12 },
       { "NOTE_INFO_THREAD", 12 },
       { "NOTE_INFO_MODULE", 12 },
       { "NOTE_INFO_MODULE64", 16 },
      };

  if (type == 0 || type > (sizeof(size_check)/sizeof(size_check[0])))
      return true;

  if (note->descsz < size_check[type - 1].min_size)
    {
      _bfd_error_handler (_("%pB: warning: win32pstatus %s of size %lu bytes"
			    " is too small"),
			  abfd, size_check[type - 1].type_name, note->descsz);
      return true;
    }

  switch (type)
    {
    case NOTE_INFO_PROCESS:
      /* FIXME: need to add ->core->command.  */
      elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 4);
      elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 8);
      break;

    case NOTE_INFO_THREAD:
      /* Make a ".reg/<tid>" section containing the Win32 API thread CONTEXT
	 structure. */
      /* thread_info.tid */
      sprintf (buf, NOTE_PSEUDO_SECTION_REG "/%ld", (long) bfd_get_32 (abfd, note->descdata + 4));

      len = strlen (buf) + 1;
      name = (char *) bfd_alloc (abfd, len);
      if (name == NULL)
	return false;

      memcpy (name, buf, len);

      sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
      if (sect == NULL)
	return false;

      /* sizeof (thread_info.thread_context) */
      sect->size = note->descsz - 12;
      /* offsetof (thread_info.thread_context) */
      sect->filepos = note->descpos + 12;
      sect->alignment_power = 2;

      /* thread_info.is_active_thread */
      is_active_thread = bfd_get_32 (abfd, note->descdata + 8);

      if (is_active_thread)
	if (! elfcore_maybe_make_sect (abfd, NOTE_PSEUDO_SECTION_REG, sect))
	  return false;
      break;

    case NOTE_INFO_MODULE:
    case NOTE_INFO_MODULE64:
      /* Make a ".module/xxxxxxxx" section.  */
      if (type == NOTE_INFO_MODULE)
	{
	  /* module_info.base_address */
	  base_addr = bfd_get_32 (abfd, note->descdata + 4);
	  sprintf (buf, ".module/%08lx", (unsigned long) base_addr);
	  /* module_info.module_name_size */
	  name_size = bfd_get_32 (abfd, note->descdata + 8);
	}
      else /* NOTE_INFO_MODULE64 */
	{
	  /* module_info.base_address */
	  base_addr = bfd_get_64 (abfd, note->descdata + 4);
	  sprintf (buf, ".module/%016lx", (unsigned long) base_addr);
	  /* module_info.module_name_size */
	  name_size = bfd_get_32 (abfd, note->descdata + 12);
	}

      len = strlen (buf) + 1;
      name = (char *) bfd_alloc (abfd, len);
      if (name == NULL)
	return false;

      memcpy (name, buf, len);

      sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);

      if (sect == NULL)
	return false;

      if (note->descsz < 12 + name_size)
	{
	  _bfd_error_handler (_("%pB: win32pstatus NOTE_INFO_MODULE of size %lu"
				" is too small to contain a name of size %u"),
			      abfd, note->descsz, name_size);
	  return true;
	}

      sect->size = note->descsz;
      sect->filepos = note->descpos;
      sect->alignment_power = 2;
      break;

    default:
      return true;
    }

  return true;
}

static bool
elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  /* Short cut for LINUX notes.  */
  if (note->namesz == 6 /* strlen (NOTE_NAME_LINUX) + 1 */
      && streq (note->namedata, NOTE_NAME_LINUX))
    {
      switch (note->type)
	{
	case NT_386_TLS:	return elfcore_grok_i386_tls (abfd, note);
	case NT_ARC_V2:		return elfcore_grok_arc_v2 (abfd, note);
	case NT_ARM_FPMR:	return elfcore_grok_aarch_fpmr (abfd, note);
	case NT_ARM_GCS:	return elfcore_grok_aarch_gcs (abfd, note);
	case NT_ARM_HW_BREAK:	return elfcore_grok_aarch_hw_break (abfd, note);
	case NT_ARM_HW_WATCH:	return elfcore_grok_aarch_hw_watch (abfd, note);
	case NT_ARM_PAC_MASK:	return elfcore_grok_aarch_pauth (abfd, note);
	case NT_ARM_SSVE:	return elfcore_grok_aarch_ssve (abfd, note);
	case NT_ARM_SVE:	return elfcore_grok_aarch_sve (abfd, note);
	case NT_ARM_TAGGED_ADDR_CTRL: return elfcore_grok_aarch_mte (abfd, note);
	case NT_ARM_TLS:	return elfcore_grok_aarch_tls (abfd, note);
	case NT_ARM_VFP:	return elfcore_grok_arm_vfp (abfd, note);
	case NT_ARM_ZA:		return elfcore_grok_aarch_za (abfd, note);
	case NT_ARM_ZT:		return elfcore_grok_aarch_zt (abfd, note);
	case NT_LARCH_CPUCFG:	return elfcore_grok_loongarch_cpucfg (abfd, note);
	case NT_LARCH_LASX:	return elfcore_grok_loongarch_lasx (abfd, note);
	case NT_LARCH_LBT:	return elfcore_grok_loongarch_lbt (abfd, note);
	case NT_LARCH_LSX:	return elfcore_grok_loongarch_lsx (abfd, note);
	case NT_PPC_DSCR:	return elfcore_grok_ppc_dscr (abfd, note);
	case NT_PPC_EBB:	return elfcore_grok_ppc_ebb (abfd, note);
	case NT_PPC_PMU:	return elfcore_grok_ppc_pmu (abfd, note);
	case NT_PPC_PPR:	return elfcore_grok_ppc_ppr (abfd, note);
	case NT_PPC_TAR:	return elfcore_grok_ppc_tar (abfd, note);
	case NT_PPC_TM_CDSCR:	return elfcore_grok_ppc_tm_cdscr (abfd, note);
	case NT_PPC_TM_CFPR:	return elfcore_grok_ppc_tm_cfpr (abfd, note);
	case NT_PPC_TM_CGPR:	return elfcore_grok_ppc_tm_cgpr (abfd, note);
	case NT_PPC_TM_CPPR:	return elfcore_grok_ppc_tm_cppr (abfd, note);
	case NT_PPC_TM_CTAR:	return elfcore_grok_ppc_tm_ctar (abfd, note);
	case NT_PPC_TM_CVMX:	return elfcore_grok_ppc_tm_cvmx (abfd, note);
	case NT_PPC_TM_CVSX:	return elfcore_grok_ppc_tm_cvsx (abfd, note);
	case NT_PPC_TM_SPR:	return elfcore_grok_ppc_tm_spr (abfd, note);
	case NT_PPC_VMX:	return elfcore_grok_ppc_vmx (abfd, note);
	case NT_PPC_VSX:	return elfcore_grok_ppc_vsx (abfd, note);
	case NT_PRXFPREG:	return elfcore_grok_prxfpreg (abfd, note);
	case NT_S390_CTRS:	return elfcore_grok_s390_ctrs (abfd, note);
	case NT_S390_GS_BC:	return elfcore_grok_s390_gs_bc (abfd, note);
	case NT_S390_GS_CB:	return elfcore_grok_s390_gs_cb (abfd, note);
	case NT_S390_HIGH_GPRS:	return elfcore_grok_s390_high_gprs (abfd, note);
	case NT_S390_LAST_BREAK:  return elfcore_grok_s390_last_break (abfd, note);
	case NT_S390_PREFIX:	return elfcore_grok_s390_prefix (abfd, note);
	case NT_S390_SYSTEM_CALL: return elfcore_grok_s390_system_call (abfd, note);
	case NT_S390_TDB:	return elfcore_grok_s390_tdb (abfd, note);
	case NT_S390_TIMER:	return elfcore_grok_s390_timer (abfd, note);
	case NT_S390_TODCMP:	return elfcore_grok_s390_todcmp (abfd, note);
	case NT_S390_TODPREG:	return elfcore_grok_s390_todpreg (abfd, note);
	case NT_S390_VXRS_HIGH:	return elfcore_grok_s390_vxrs_high (abfd, note);
	case NT_S390_VXRS_LOW:	return elfcore_grok_s390_vxrs_low (abfd, note);
	case NT_X86_SHSTK:	return elfcore_grok_sspreg (abfd, note);
	case NT_X86_XSTATE:	return elfcore_grok_xstatereg (abfd, note);
	default: break;
	}
    }
  
  switch (note->type)
    {
    default:
      return true;

    case NT_PRSTATUS:
      if (bed->elf_backend_grok_prstatus)
	if ((*bed->elf_backend_grok_prstatus) (abfd, note))
	  return true;
#if defined (HAVE_PRSTATUS_T)
      return elfcore_grok_prstatus (abfd, note);
#else
      return true;
#endif

#if defined (HAVE_PSTATUS_T)
    case NT_PSTATUS:
      return elfcore_grok_pstatus (abfd, note);
#endif

#if defined (HAVE_LWPSTATUS_T)
    case NT_LWPSTATUS:
      return elfcore_grok_lwpstatus (abfd, note);
#endif

    case NT_FPREGSET:		/* FIXME: rename to NT_PRFPREG.  */
      return elfcore_grok_prfpreg (abfd, note);

    case NT_WIN32PSTATUS:
      return elfcore_grok_win32pstatus (abfd, note);

    case NT_GDB_TDESC:
      if (note->namesz == 4 && streq (note->namedata, NOTE_NAME_GDB))
	return elfcore_grok_gdb_tdesc (abfd, note);
      else
	return true;

    case NT_RISCV_CSR:
      if (note->namesz == 4 && streq (note->namedata, NOTE_NAME_GDB))
	return elfcore_grok_riscv_csr (abfd, note);
      else
	return true;

    case NT_PRPSINFO:
    case NT_PSINFO:
      if (bed->elf_backend_grok_psinfo)
	if ((*bed->elf_backend_grok_psinfo) (abfd, note))
	  return true;
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
      return elfcore_grok_psinfo (abfd, note);
#else
      return true;
#endif

    case NT_AUXV:
      return elfcore_make_auxv_note_section (abfd, note, 0);

    case NT_FILE:
      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
					      note);

    case NT_SIGINFO:
      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
					      note);
    }
}

static bool
elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
{
  struct bfd_build_id* build_id;

  if (note->descsz == 0)
    return false;

  build_id = bfd_alloc (abfd, sizeof (struct bfd_build_id) - 1 + note->descsz);
  if (build_id == NULL)
    return false;

  build_id->size = note->descsz;
  memcpy (build_id->data, note->descdata, note->descsz);
  abfd->build_id = build_id;

  return true;
}

static bool
elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
{
  switch (note->type)
    {
    default:
      return true;

    case NT_GNU_PROPERTY_TYPE_0:
      return _bfd_elf_parse_gnu_properties (abfd, note);

    case NT_GNU_BUILD_ID:
      return elfobj_grok_gnu_build_id (abfd, note);
    }
}

static bool
elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note)
{
  struct sdt_note *cur =
    (struct sdt_note *) bfd_alloc (abfd,
				   sizeof (struct sdt_note) + note->descsz);

  cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head;
  cur->size = (bfd_size_type) note->descsz;
  memcpy (cur->data, note->descdata, note->descsz);

  elf_tdata (abfd)->sdt_note_head = cur;

  return true;
}

static bool
elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
{
  switch (note->type)
    {
    case NT_STAPSDT:
      return elfobj_grok_stapsdt_note_1 (abfd, note);

    default:
      return true;
    }
}

static bool
elfcore_grok_freebsd_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
  size_t offset;

  switch (elf_elfheader (abfd)->e_ident[EI_CLASS])
    {
    case ELFCLASS32:
      if (note->descsz < 108)
	return false;
      break;

    case ELFCLASS64:
      if (note->descsz < 120)
	return false;
      break;

    default:
      return false;
    }

  /* Check for version 1 in pr_version.  */
  if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
    return false;

  offset = 4;

  /* Skip over pr_psinfosz. */
  if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
    offset += 4;
  else
    {
      offset += 4;	/* Padding before pr_psinfosz. */
      offset += 8;
    }

  /* pr_fname is PRFNAMESZ (16) + 1 bytes in size.  */
  elf_tdata (abfd)->core->program
    = _bfd_elfcore_strndup (abfd, note->descdata + offset, 17);
  offset += 17;

  /* pr_psargs is PRARGSZ (80) + 1 bytes in size.  */
  elf_tdata (abfd)->core->command
    = _bfd_elfcore_strndup (abfd, note->descdata + offset, 81);
  offset += 81;

  /* Padding before pr_pid.  */
  offset += 2;

  /* The pr_pid field was added in version "1a".  */
  if (note->descsz < offset + 4)
    return true;

  elf_tdata (abfd)->core->pid
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);

  return true;
}

static bool
elfcore_grok_freebsd_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  size_t offset;
  size_t size;
  size_t min_size;

  /* Compute offset of pr_getregsz, skipping over pr_statussz.
     Also compute minimum size of this note.  */
  switch (elf_elfheader (abfd)->e_ident[EI_CLASS])
    {
    case ELFCLASS32:
      offset = 4 + 4;
      min_size = offset + (4 * 2) + 4 + 4 + 4;
      break;

    case ELFCLASS64:
      offset = 4 + 4 + 8;	/* Includes padding before pr_statussz.  */
      min_size = offset + (8 * 2) + 4 + 4 + 4 + 4;
      break;

    default:
      return false;
    }

  if (note->descsz < min_size)
    return false;

  /* Check for version 1 in pr_version.  */
  if (bfd_h_get_32 (abfd, (bfd_byte *) note->descdata) != 1)
    return false;

  /* Extract size of pr_reg from pr_gregsetsz.  */
  /* Skip over pr_gregsetsz and pr_fpregsetsz.  */
  if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS32)
    {
      size = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
      offset += 4 * 2;
    }
  else
    {
      size = bfd_h_get_64 (abfd, (bfd_byte *) note->descdata + offset);
      offset += 8 * 2;
    }

  /* Skip over pr_osreldate.  */
  offset += 4;

  /* Read signal from pr_cursig.  */
  if (elf_tdata (abfd)->core->signal == 0)
    elf_tdata (abfd)->core->signal
      = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
  offset += 4;

  /* Read TID from pr_pid.  */
  elf_tdata (abfd)->core->lwpid
      = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + offset);
  offset += 4;

  /* Padding before pr_reg.  */
  if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
    offset += 4;

  /* Make sure that there is enough data remaining in the note.  */
  if ((note->descsz - offset) < size)
    return false;

  /* Make a ".reg/999" section and a ".reg" section.  */
  return _bfd_elfcore_make_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG,
					  size, note->descpos + offset);
}

static bool
elfcore_grok_freebsd_note (bfd *abfd, Elf_Internal_Note *note)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  switch (note->type)
    {
    case NT_PRSTATUS:
      if (bed->elf_backend_grok_freebsd_prstatus)
	if ((*bed->elf_backend_grok_freebsd_prstatus) (abfd, note))
	  return true;
      return elfcore_grok_freebsd_prstatus (abfd, note);

    case NT_FPREGSET:
      return elfcore_grok_prfpreg (abfd, note);

    case NT_PRPSINFO:
      return elfcore_grok_freebsd_psinfo (abfd, note);

    case NT_FREEBSD_THRMISC:
      return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);

    case NT_FREEBSD_PROCSTAT_PROC:
      return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.proc",
					      note);

    case NT_FREEBSD_PROCSTAT_FILES:
      return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.files",
					      note);

    case NT_FREEBSD_PROCSTAT_VMMAP:
      return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.vmmap",
					      note);

    case NT_FREEBSD_PROCSTAT_AUXV:
      return elfcore_make_auxv_note_section (abfd, note, 4);

    case NT_FREEBSD_X86_SEGBASES:
      return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_X86_SEGBASES, note);

    case NT_X86_XSTATE:
      return elfcore_grok_xstatereg (abfd, note);

    case NT_FREEBSD_PTLWPINFO:
      return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
					      note);

    case NT_ARM_TLS:
      return elfcore_grok_aarch_tls (abfd, note);

    case NT_ARM_VFP:
      return elfcore_grok_arm_vfp (abfd, note);

    default:
      return true;
    }
}

static bool
elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
{
  char *cp;

  cp = strchr (note->namedata, '@');
  if (cp != NULL)
    {
      *lwpidp = atoi(cp + 1);
      return true;
    }
  return false;
}

static bool
elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
{
  if (note->descsz <= 0x7c + 31)
    return false;

  /* Signal number at offset 0x08. */
  elf_tdata (abfd)->core->signal
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);

  /* Process ID at offset 0x50. */
  elf_tdata (abfd)->core->pid
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);

  /* Command name at 0x7c (max 32 bytes, including nul). */
  elf_tdata (abfd)->core->command
    = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);

  return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
					  note);
}

static bool
elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
{
  int lwp;

  if (elfcore_netbsd_get_lwpid (note, &lwp))
    elf_tdata (abfd)->core->lwpid = lwp;

  switch (note->type)
    {
    case NT_NETBSDCORE_PROCINFO:
      /* NetBSD-specific core "procinfo".  Note that we expect to
	 find this note before any of the others, which is fine,
	 since the kernel writes this note out first when it
	 creates a core file.  */
      return elfcore_grok_netbsd_procinfo (abfd, note);
    case NT_NETBSDCORE_AUXV:
      /* NetBSD-specific Elf Auxiliary Vector data. */
      return elfcore_make_auxv_note_section (abfd, note, 4);
    case NT_NETBSDCORE_LWPSTATUS:
      return elfcore_make_note_pseudosection (abfd,
					      ".note.netbsdcore.lwpstatus",
					      note);
    default:
      break;
    }

  /* As of March 2020 there are no other machine-independent notes
     defined for NetBSD core files.  If the note type is less
     than the start of the machine-dependent note types, we don't
     understand it.  */

  if (note->type < NT_NETBSDCORE_FIRSTMACH)
    return true;


  switch (bfd_get_arch (abfd))
    {
      /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0 and
	 PT_GETFPREGS == mach+2.  */

    case bfd_arch_aarch64:
    case bfd_arch_alpha:
    case bfd_arch_sparc:
      switch (note->type)
	{
	case NT_NETBSDCORE_FIRSTMACH+0:
	  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG, note);

	case NT_NETBSDCORE_FIRSTMACH+2:
	  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG2, note);

	default:
	  return true;
	}

      /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
	 There's also old PT___GETREGS40 == mach + 1 for old reg
	 structure which lacks GBR.  */

    case bfd_arch_sh:
      switch (note->type)
	{
	case NT_NETBSDCORE_FIRSTMACH+3:
	  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG, note);

	case NT_NETBSDCORE_FIRSTMACH+5:
	  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG2, note);

	default:
	  return true;
	}

      /* On all other arch's, PT_GETREGS == mach+1 and
	 PT_GETFPREGS == mach+3.  */

    default:
      switch (note->type)
	{
	case NT_NETBSDCORE_FIRSTMACH+1:
	  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG, note);

	case NT_NETBSDCORE_FIRSTMACH+3:
	  return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG2, note);

	default:
	  return true;
	}
    }
    /* NOTREACHED */
}

static bool
elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
{
  if (note->descsz <= 0x48 + 31)
    return false;

  /* Signal number at offset 0x08. */
  elf_tdata (abfd)->core->signal
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);

  /* Process ID at offset 0x20. */
  elf_tdata (abfd)->core->pid
    = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);

  /* Command name at 0x48 (max 32 bytes, including nul). */
  elf_tdata (abfd)->core->command
    = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);

  return true;
}

/* Processes Solaris's process status note.
   sig_off ~ offsetof(prstatus_t, pr_cursig)
   pid_off ~ offsetof(prstatus_t, pr_pid)
   lwpid_off ~ offsetof(prstatus_t, pr_who)
   gregset_size ~ sizeof(gregset_t)
   gregset_offset ~ offsetof(prstatus_t, pr_reg)  */

static bool
elfcore_grok_solaris_prstatus (bfd *abfd, Elf_Internal_Note* note, int sig_off,
			       int pid_off, int lwpid_off, size_t gregset_size,
			       size_t gregset_offset)
{
  asection *sect = NULL;
  elf_tdata (abfd)->core->signal
    = bfd_get_16 (abfd, note->descdata + sig_off);
  elf_tdata (abfd)->core->pid
    = bfd_get_32 (abfd, note->descdata + pid_off);
  elf_tdata (abfd)->core->lwpid
    = bfd_get_32 (abfd, note->descdata + lwpid_off);

  sect = bfd_get_section_by_name (abfd, NOTE_PSEUDO_SECTION_REG);
  if (sect != NULL)
    sect->size = gregset_size;

  return _bfd_elfcore_make_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG, gregset_size,
					  note->descpos + gregset_offset);
}

/* Gets program and arguments from a core.
   prog_off ~ offsetof(prpsinfo | psinfo_t, pr_fname)
   comm_off ~ offsetof(prpsinfo | psinfo_t, pr_psargs)  */

static bool
elfcore_grok_solaris_info(bfd *abfd, Elf_Internal_Note* note,
			  int prog_off, int comm_off)
{
  elf_tdata (abfd)->core->program
    = _bfd_elfcore_strndup (abfd, note->descdata + prog_off, 16);
  elf_tdata (abfd)->core->command
    = _bfd_elfcore_strndup (abfd, note->descdata + comm_off, 80);

  return true;
}

/* Processes Solaris's LWP status note.
   gregset_size ~ sizeof(gregset_t)
   gregset_off ~ offsetof(lwpstatus_t, pr_reg)
   fpregset_size ~ sizeof(fpregset_t)
   fpregset_off ~ offsetof(lwpstatus_t, pr_fpreg)  */

static bool
elfcore_grok_solaris_lwpstatus (bfd *abfd, Elf_Internal_Note* note,
				size_t gregset_size, int gregset_off,
				size_t fpregset_size, int fpregset_off)
{
  asection *sect = NULL;
  char reg2_section_name[16] = { 0 };

  (void) snprintf (reg2_section_name, 16, "%s/%i", NOTE_PSEUDO_SECTION_REG2,
		   elf_tdata (abfd)->core->lwpid);

  /* offsetof(lwpstatus_t, pr_lwpid) */
  elf_tdata (abfd)->core->lwpid
    = bfd_get_32 (abfd, note->descdata + 4);
  /* offsetof(lwpstatus_t, pr_cursig) */
  elf_tdata (abfd)->core->signal
    = bfd_get_16 (abfd, note->descdata + 12);

  sect = bfd_get_section_by_name (abfd, NOTE_PSEUDO_SECTION_REG);
  if (sect != NULL)
    sect->size = gregset_size;
  else if (!_bfd_elfcore_make_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG, gregset_size,
					     note->descpos + gregset_off))
    return false;

  sect = bfd_get_section_by_name (abfd, reg2_section_name);
  if (sect != NULL)
    {
      sect->size = fpregset_size;
      sect->filepos = note->descpos + fpregset_off;
      sect->alignment_power = 2;
    }
  else if (!_bfd_elfcore_make_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG2, fpregset_size,
					     note->descpos + fpregset_off))
    return false;

  return true;
}

static bool
elfcore_grok_solaris_note_impl (bfd *abfd, Elf_Internal_Note *note)
{
  if (note == NULL)
    return false;

  /* core files are identified as 32- or 64-bit, SPARC or x86,
     by the size of the descsz which matches the sizeof()
     the type appropriate for that note type (e.g., prstatus_t for
     SOLARIS_NT_PRSTATUS) for the corresponding architecture
     on Solaris. The core file bitness may differ from the bitness of
     gdb itself, so fixed values are used instead of sizeof().
     Appropriate fixed offsets are also used to obtain data from
     the note.  */

  switch ((int) note->type)
    {
    case SOLARIS_NT_PRSTATUS:
      switch (note->descsz)
	{
	case 508: /* sizeof(prstatus_t) SPARC 32-bit */
	  return elfcore_grok_solaris_prstatus(abfd, note,
					       136, 216, 308, 152, 356);
	case 904: /* sizeof(prstatus_t) SPARC 64-bit */
	  return elfcore_grok_solaris_prstatus(abfd, note,
					       264, 360, 520, 304, 600);
	case 432: /* sizeof(prstatus_t) Intel 32-bit */
	  return elfcore_grok_solaris_prstatus(abfd, note,
					       136, 216, 308, 76, 356);
	case 824: /* sizeof(prstatus_t) Intel 64-bit */
	  return elfcore_grok_solaris_prstatus(abfd, note,
					       264, 360, 520, 224, 600);
	default:
	  return true;
	}

    case SOLARIS_NT_PSINFO:
    case SOLARIS_NT_PRPSINFO:
      switch (note->descsz)
	{
	case 260: /* sizeof(prpsinfo_t) SPARC and Intel 32-bit */
	  return elfcore_grok_solaris_info(abfd, note, 84, 100);
	case 328: /* sizeof(prpsinfo_t) SPARC and Intel 64-bit */
	  return elfcore_grok_solaris_info(abfd, note, 120, 136);
	case 360: /* sizeof(psinfo_t) SPARC and Intel 32-bit */
	  return elfcore_grok_solaris_info(abfd, note, 88, 104);
	case 440: /* sizeof(psinfo_t) SPARC and Intel 64-bit */
	  return elfcore_grok_solaris_info(abfd, note, 136, 152);
	default:
	  return true;
	}

    case SOLARIS_NT_LWPSTATUS:
      switch (note->descsz)
	{
	case 896: /* sizeof(lwpstatus_t) SPARC 32-bit */
	  return elfcore_grok_solaris_lwpstatus(abfd, note,
						152, 344, 400, 496);
	case 1392: /* sizeof(lwpstatus_t) SPARC 64-bit */
	  return elfcore_grok_solaris_lwpstatus(abfd, note,
						304, 544, 544, 848);
	case 800: /* sizeof(lwpstatus_t) Intel 32-bit */
	  return elfcore_grok_solaris_lwpstatus(abfd, note,
						76, 344, 380, 420);
	case 1296: /* sizeof(lwpstatus_t) Intel 64-bit */
	  return elfcore_grok_solaris_lwpstatus(abfd, note,
						224, 544, 528, 768);
	default:
	  return true;
	}

    case SOLARIS_NT_LWPSINFO:
      /* sizeof(lwpsinfo_t) on 32- and 64-bit, respectively */
      if (note->descsz == 128 || note->descsz == 152)
	elf_tdata (abfd)->core->lwpid =
	  bfd_get_32 (abfd, note->descdata + 4);
      break;

    default:
      break;
    }

  return true;
}

/* For name starting with "CORE" this may be either a Solaris
   core file or a gdb-generated core file.  Do Solaris-specific
   processing on selected note types first with
   elfcore_grok_solaris_note(), then process the note
   in elfcore_grok_note().  */

static bool
elfcore_grok_solaris_note (bfd *abfd, Elf_Internal_Note *note)
{
  if (!elfcore_grok_solaris_note_impl (abfd, note))
    return false;

  return elfcore_grok_note (abfd, note);
}

static bool
elfcore_grok_openbsd_note (bfd *abfd, Elf_Internal_Note *note)
{
  if (note->type == NT_OPENBSD_PROCINFO)
    return elfcore_grok_openbsd_procinfo (abfd, note);

  if (note->type == NT_OPENBSD_REGS)
    return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG, note);

  if (note->type == NT_OPENBSD_FPREGS)
    return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_REG2, note);

  if (note->type == NT_OPENBSD_XFPREGS)
    return elfcore_make_note_pseudosection (abfd, NOTE_PSEUDO_SECTION_XFP, note);

  if (note->type == NT_OPENBSD_AUXV)
    return elfcore_make_auxv_note_section (abfd, note, 0);

  if (note->type == NT_OPENBSD_WCOOKIE)
    {
      asection *sect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
							   SEC_HAS_CONTENTS);

      if (sect == NULL)
	return false;
      sect->size = note->descsz;
      sect->filepos = note->descpos;
      sect->alignment_power = 1 + bfd_get_arch_size (abfd) / 32;

      return true;
    }

  return true;
}

static bool
elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
{
  void *ddata = note->descdata;
  char buf[100];
  char *name;
  asection *sect;
  short sig;
  unsigned flags;

  if (note->descsz < 16)
    return false;

  /* nto_procfs_status 'pid' field is at offset 0.  */
  elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);

  /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
  *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);

  /* nto_procfs_status 'flags' field is at offset 8.  */
  flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8);

  /* nto_procfs_status 'what' field is at offset 14.  */
  if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
    {
      elf_tdata (abfd)->core->signal = sig;
      elf_tdata (abfd)->core->lwpid = *tid;
    }

  /* _DEBUG_FLAG_CURTID (current thread) is 0x80.  Some cores
     do not come from signals so we make sure we set the current
     thread just in case.  */
  if (flags & 0x00000080)
    elf_tdata (abfd)->core->lwpid = *tid;

  /* Make a ".qnx_core_status/%d" section.  */
  sprintf (buf, ".qnx_core_status/%ld", *tid);

  name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
  if (name == NULL)
    return false;
  strcpy (name, buf);

  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  if (sect == NULL)
    return false;

  sect->size		= note->descsz;
  sect->filepos		= note->descpos;
  sect->alignment_power = 2;

  return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
}

static bool
elfcore_grok_nto_regs (bfd *abfd,
		       Elf_Internal_Note *note,
		       long tid,
		       char *base)
{
  char buf[100];
  char *name;
  asection *sect;

  /* Make a "(base)/%d" section.  */
  sprintf (buf, "%s/%ld", base, tid);

  name = (char *) bfd_alloc (abfd, strlen (buf) + 1);
  if (name == NULL)
    return false;
  strcpy (name, buf);

  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  if (sect == NULL)
    return false;

  sect->size		= note->descsz;
  sect->filepos		= note->descpos;
  sect->alignment_power = 2;

  /* This is the current thread.  */
  if (elf_tdata (abfd)->core->lwpid == tid)
    return elfcore_maybe_make_sect (abfd, base, sect);

  return true;
}

static bool
elfcore_grok_nto_note (bfd *abfd, Elf_Internal_Note *note)
{
  /* Every GREG section has a STATUS section before it.  Store the
     tid from the previous call to pass down to the next gregs
     function.  */
  static long tid = 1;

  switch (note->type)
    {
    case QNT_CORE_INFO:
      return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
    case QNT_CORE_STATUS:
      return elfcore_grok_nto_status (abfd, note, &tid);
    case QNT_CORE_GREG:
      return elfcore_grok_nto_regs (abfd, note, tid, NOTE_PSEUDO_SECTION_REG);
    case QNT_CORE_FPREG:
      return elfcore_grok_nto_regs (abfd, note, tid, NOTE_PSEUDO_SECTION_REG2);
    default:
      return true;
    }
}

static bool
elfcore_grok_spu_note (bfd *abfd, Elf_Internal_Note *note)
{
  char *name;
  asection *sect;
  size_t len;

  /* Use note name as section name.  */
  len = note->namesz;
  name = (char *) bfd_alloc (abfd, len);
  if (name == NULL)
    return false;
  memcpy (name, note->namedata, len);
  name[len - 1] = '\0';

  sect = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS);
  if (sect == NULL)
    return false;

  sect->size		= note->descsz;
  sect->filepos		= note->descpos;
  sect->alignment_power = 1;

  return true;
}

/* Function: elfcore_write_note

   Inputs:
     buffer to hold note, and current size of buffer
     name of note
     type of note
     data for note
     size of data for note

   Writes note to end of buffer.  ELF64 notes are written exactly as
   for ELF32, despite the current (as of 2006) ELF gabi specifying
   that they ought to have 8-byte namesz and descsz field, and have
   8-byte alignment.  Other writers, eg. Linux kernel, do the same.

   Return:
   Pointer to realloc'd buffer, *BUFSIZ updated.  */

char *
elfcore_write_note (bfd *abfd,
		    char *buf,
		    int *bufsiz,
		    const char *name,
		    int type,
		    const void *input,
		    int size)
{
  Elf_External_Note *xnp;
  size_t namesz;
  size_t newspace;
  char *dest;

  namesz = 0;
  if (name != NULL)
    namesz = strlen (name) + 1;

  newspace = 12 + ((namesz + 3) & -4) + ((size + 3) & -4);

  buf = (char *) realloc (buf, *bufsiz + newspace);
  if (buf == NULL)
    return buf;
  dest = buf + *bufsiz;
  *bufsiz += newspace;
  xnp = (Elf_External_Note *) dest;
  H_PUT_32 (abfd, namesz, xnp->namesz);
  H_PUT_32 (abfd, size, xnp->descsz);
  H_PUT_32 (abfd, type, xnp->type);
  dest = xnp->name;
  if (name != NULL)
    {
      memcpy (dest, name, namesz);
      dest += namesz;
      while (namesz & 3)
	{
	  *dest++ = '\0';
	  ++namesz;
	}
    }
  memcpy (dest, input, size);
  dest += size;
  while (size & 3)
    {
      *dest++ = '\0';
      ++size;
    }
  return buf;
}

/* gcc-8 warns (*) on all the strncpy calls in this function about
   possible string truncation.  The "truncation" is not a bug.  We
   have an external representation of structs with fields that are not
   necessarily NULL terminated and corresponding internal
   representation fields that are one larger so that they can always
   be NULL terminated.
   gcc versions between 4.2 and 4.6 do not allow pragma control of
   diagnostics inside functions, giving a hard error if you try to use
   the finer control available with later versions.
   gcc prior to 4.2 warns about diagnostic push and pop.
   gcc-5, gcc-6 and gcc-7 warn that -Wstringop-truncation is unknown,
   unless you also add #pragma GCC diagnostic ignored "-Wpragma".
   (*) Depending on your system header files!  */
#if GCC_VERSION >= 8000
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
char *
elfcore_write_prpsinfo (bfd  *abfd,
			char *buf,
			int  *bufsiz,
			const char *fname,
			const char *psargs)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if (bed->elf_backend_write_core_note != NULL)
    {
      char *ret;
      ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
						 NT_PRPSINFO, fname, psargs);
      if (ret != NULL)
	return ret;
    }

#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
# if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
  if (bed->s->elfclass == ELFCLASS32)
    {
#  if defined (HAVE_PSINFO32_T)
      psinfo32_t data;
      int note_type = NT_PSINFO;
#  else
      prpsinfo32_t data;
      int note_type = NT_PRPSINFO;
#  endif

      memset (&data, 0, sizeof (data));
      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
      return elfcore_write_note (abfd, buf, bufsiz,
				 NOTE_NAME_CORE, note_type, &data, sizeof (data));
    }
  else
# endif
    {
# if defined (HAVE_PSINFO_T)
      psinfo_t data;
      int note_type = NT_PSINFO;
# else
      prpsinfo_t data;
      int note_type = NT_PRPSINFO;
# endif

      memset (&data, 0, sizeof (data));
      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
      return elfcore_write_note (abfd, buf, bufsiz,
				 NOTE_NAME_CORE, note_type, &data, sizeof (data));
    }
#endif	/* PSINFO_T or PRPSINFO_T */

  free (buf);
  return NULL;
}
#if GCC_VERSION >= 8000
# pragma GCC diagnostic pop
#endif

char *
elfcore_write_linux_prpsinfo32
  (bfd *abfd, char *buf, int *bufsiz,
   const struct elf_internal_linux_prpsinfo *prpsinfo)
{
  if (get_elf_backend_data (abfd)->linux_prpsinfo32_ugid16)
    {
      struct elf_external_linux_prpsinfo32_ugid16 data;

      swap_linux_prpsinfo32_ugid16_out (abfd, prpsinfo, &data);
      return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE, NT_PRPSINFO,
				 &data, sizeof (data));
    }
  else
    {
      struct elf_external_linux_prpsinfo32_ugid32 data;

      swap_linux_prpsinfo32_ugid32_out (abfd, prpsinfo, &data);
      return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE, NT_PRPSINFO,
				 &data, sizeof (data));
    }
}

char *
elfcore_write_linux_prpsinfo64
  (bfd *abfd, char *buf, int *bufsiz,
   const struct elf_internal_linux_prpsinfo *prpsinfo)
{
  if (get_elf_backend_data (abfd)->linux_prpsinfo64_ugid16)
    {
      struct elf_external_linux_prpsinfo64_ugid16 data;

      swap_linux_prpsinfo64_ugid16_out (abfd, prpsinfo, &data);
      return elfcore_write_note (abfd, buf, bufsiz,
				 NOTE_NAME_CORE, NT_PRPSINFO, &data, sizeof (data));
    }
  else
    {
      struct elf_external_linux_prpsinfo64_ugid32 data;

      swap_linux_prpsinfo64_ugid32_out (abfd, prpsinfo, &data);
      return elfcore_write_note (abfd, buf, bufsiz,
				 NOTE_NAME_CORE, NT_PRPSINFO, &data, sizeof (data));
    }
}

char *
elfcore_write_prstatus (bfd *abfd,
			char *buf,
			int *bufsiz,
			long pid,
			int cursig,
			const void *gregs)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if (bed->elf_backend_write_core_note != NULL)
    {
      char *ret;
      ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
						 NT_PRSTATUS,
						 pid, cursig, gregs);
      if (ret != NULL)
	return ret;
    }

#if defined (HAVE_PRSTATUS_T)
#if defined (HAVE_PRSTATUS32_T)
  if (bed->s->elfclass == ELFCLASS32)
    {
      prstatus32_t prstat;

      memset (&prstat, 0, sizeof (prstat));
      prstat.pr_pid = pid;
      prstat.pr_cursig = cursig;
      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
      return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE,
				 NT_PRSTATUS, &prstat, sizeof (prstat));
    }
  else
#endif
    {
      prstatus_t prstat;

      memset (&prstat, 0, sizeof (prstat));
      prstat.pr_pid = pid;
      prstat.pr_cursig = cursig;
      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
      return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE,
				 NT_PRSTATUS, &prstat, sizeof (prstat));
    }
#endif /* HAVE_PRSTATUS_T */

  free (buf);
  return NULL;
}

#if defined (HAVE_LWPSTATUS_T)
char *
elfcore_write_lwpstatus (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 long pid,
			 int cursig,
			 const void *gregs)
{
  lwpstatus_t lwpstat;

  memset (&lwpstat, 0, sizeof (lwpstat));
  lwpstat.pr_lwpid  = pid >> 16;
  lwpstat.pr_cursig = cursig;
#if defined (HAVE_LWPSTATUS_T_PR_REG)
  memcpy (&lwpstat.pr_reg, gregs, sizeof (lwpstat.pr_reg));
#elif defined (HAVE_LWPSTATUS_T_PR_CONTEXT)
#if !defined(gregs)
  memcpy (lwpstat.pr_context.uc_mcontext.gregs,
	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.gregs));
#else
  memcpy (lwpstat.pr_context.uc_mcontext.__gregs,
	  gregs, sizeof (lwpstat.pr_context.uc_mcontext.__gregs));
#endif
#endif
  return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE,
			     NT_LWPSTATUS, &lwpstat, sizeof (lwpstat));
}
#endif /* HAVE_LWPSTATUS_T */

#if defined (HAVE_PSTATUS_T)
char *
elfcore_write_pstatus (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       long pid,
		       int cursig ATTRIBUTE_UNUSED,
		       const void *gregs ATTRIBUTE_UNUSED)
{
#if defined (HAVE_PSTATUS32_T)
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);

  if (bed->s->elfclass == ELFCLASS32)
    {
      pstatus32_t pstat;

      memset (&pstat, 0, sizeof (pstat));
      pstat.pr_pid = pid & 0xffff;
      buf = elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE,
				NT_PSTATUS, &pstat, sizeof (pstat));
      return buf;
    }
  else
#endif
    {
      pstatus_t pstat;

      memset (&pstat, 0, sizeof (pstat));
      pstat.pr_pid = pid & 0xffff;
      buf = elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_CORE,
				NT_PSTATUS, &pstat, sizeof (pstat));
      return buf;
    }
}
#endif /* HAVE_PSTATUS_T */

char *
elfcore_write_prfpreg (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *fpregs,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_CORE, NT_FPREGSET, fpregs, size);
}

char *
elfcore_write_prxfpreg (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *xfpregs,
			int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PRXFPREG, xfpregs, size);
}

char *
elfcore_write_xstatereg (bfd *abfd, char *buf, int *bufsiz,
			 const void *xfpregs, int size)
{
  char *note_name;

  if (get_elf_backend_data (abfd)->elf_osabi == ELFOSABI_FREEBSD)
    note_name = NOTE_NAME_FREEBSD;
  else
    note_name = NOTE_NAME_LINUX;

  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_X86_XSTATE, xfpregs, size);
}

static char *
elfcore_write_sspreg (bfd *abfd, char *buf, int *bufsiz,
		      const void *ssp, int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_X86_SHSTK, ssp, size);
}

char *
elfcore_write_x86_segbases (bfd *abfd, char *buf, int *bufsiz,
			    const void *regs, int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_FREEBSD, NT_FREEBSD_X86_SEGBASES,
			     regs, size);
}

char *
elfcore_write_i386_tls (bfd *abfd, char *buf, int *bufsiz,
			    const void *regs, int size)
{
  return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_LINUX, NT_386_TLS,
			     regs, size);
}

char *
elfcore_write_ppc_vmx (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_vmx,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_VMX, ppc_vmx, size);
}

char *
elfcore_write_ppc_vsx (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_vsx,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_VSX, ppc_vsx, size);
}

char *
elfcore_write_ppc_tar (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_tar,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TAR, ppc_tar, size);
}

char *
elfcore_write_ppc_ppr (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_ppr,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_PPR, ppc_ppr, size);
}

char *
elfcore_write_ppc_dscr (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *ppc_dscr,
			int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_DSCR, ppc_dscr, size);
}

char *
elfcore_write_ppc_ebb (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_ebb,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_EBB, ppc_ebb, size);
}

char *
elfcore_write_ppc_pmu (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_pmu,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_PMU, ppc_pmu, size);
}

char *
elfcore_write_ppc_tm_cgpr (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *ppc_tm_cgpr,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CGPR,
			     ppc_tm_cgpr, size);
}

char *
elfcore_write_ppc_tm_cfpr (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *ppc_tm_cfpr,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CFPR,
			     ppc_tm_cfpr, size);
}

char *
elfcore_write_ppc_tm_cvmx (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *ppc_tm_cvmx,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CVMX,
			     ppc_tm_cvmx, size);
}

char *
elfcore_write_ppc_tm_cvsx (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *ppc_tm_cvsx,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CVSX,
			     ppc_tm_cvsx, size);
}

char *
elfcore_write_ppc_tm_spr (bfd *abfd,
			  char *buf,
			  int *bufsiz,
			  const void *ppc_tm_spr,
			  int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_SPR,
			     ppc_tm_spr, size);
}

char *
elfcore_write_ppc_tm_ctar (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *ppc_tm_ctar,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CTAR,
			     ppc_tm_ctar, size);
}

char *
elfcore_write_ppc_tm_cppr (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *ppc_tm_cppr,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CPPR,
			     ppc_tm_cppr, size);
}

char *
elfcore_write_ppc_tm_cdscr (bfd *abfd,
			    char *buf,
			    int *bufsiz,
			    const void *ppc_tm_cdscr,
			    int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_PPC_TM_CDSCR,
			     ppc_tm_cdscr, size);
}

static char *
elfcore_write_s390_high_gprs (bfd *abfd,
			      char *buf,
			      int *bufsiz,
			      const void *s390_high_gprs,
			      int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_HIGH_GPRS,
			     s390_high_gprs, size);
}

char *
elfcore_write_s390_timer (bfd *abfd,
			  char *buf,
			  int *bufsiz,
			  const void *s390_timer,
			  int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_TIMER,
			     s390_timer, size);
}

char *
elfcore_write_s390_todcmp (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *s390_todcmp,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_TODCMP,
			     s390_todcmp, size);
}

char *
elfcore_write_s390_todpreg (bfd *abfd,
			    char *buf,
			    int *bufsiz,
			    const void *s390_todpreg,
			    int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_TODPREG,
			     s390_todpreg, size);
}

char *
elfcore_write_s390_ctrs (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 const void *s390_ctrs,
			 int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_CTRS, s390_ctrs, size);
}

char *
elfcore_write_s390_prefix (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *s390_prefix,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_PREFIX,
			     s390_prefix, size);
}

char *
elfcore_write_s390_last_break (bfd *abfd,
			       char *buf,
			       int *bufsiz,
			       const void *s390_last_break,
			       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_LAST_BREAK,
			     s390_last_break, size);
}

char *
elfcore_write_s390_system_call (bfd *abfd,
				char *buf,
				int *bufsiz,
				const void *s390_system_call,
				int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_SYSTEM_CALL,
			     s390_system_call, size);
}

char *
elfcore_write_s390_tdb (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *s390_tdb,
			int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_TDB, s390_tdb, size);
}

char *
elfcore_write_s390_vxrs_low (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const void *s390_vxrs_low,
			     int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_VXRS_LOW,
			     s390_vxrs_low, size);
}

char *
elfcore_write_s390_vxrs_high (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const void *s390_vxrs_high,
			     int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_VXRS_HIGH,
			     s390_vxrs_high, size);
}

char *
elfcore_write_s390_gs_cb (bfd *abfd,
			  char *buf,
			  int *bufsiz,
			  const void *s390_gs_cb,
			  int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_GS_CB,
			     s390_gs_cb, size);
}

char *
elfcore_write_s390_gs_bc (bfd *abfd,
			  char *buf,
			  int *bufsiz,
			  const void *s390_gs_bc,
			  int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_S390_GS_BC,
			     s390_gs_bc, size);
}

char *
elfcore_write_arm_vfp (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *arm_vfp,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_VFP,
			     arm_vfp, size);
}

char *
elfcore_write_aarch_tls (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *aarch_tls,
		       int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_TLS, aarch_tls, size);
}

char *
elfcore_write_aarch_hw_break (bfd *abfd,
			    char *buf,
			    int *bufsiz,
			    const void *aarch_hw_break,
			    int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_HW_BREAK,
			     aarch_hw_break, size);
}

char *
elfcore_write_aarch_hw_watch (bfd *abfd,
			    char *buf,
			    int *bufsiz,
			    const void *aarch_hw_watch,
			    int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_HW_WATCH,
			     aarch_hw_watch, size);
}

char *
elfcore_write_aarch_sve (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 const void *aarch_sve,
			 int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_SVE, aarch_sve, size);
}

char *
elfcore_write_aarch_pauth (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *aarch_pauth,
			   int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_PAC_MASK,
			     aarch_pauth, size);
}

char *
elfcore_write_aarch_mte (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 const void *aarch_mte,
			 int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_TAGGED_ADDR_CTRL,
			     aarch_mte, size);
}

char *
elfcore_write_aarch_ssve (bfd *abfd,
			  char *buf,
			  int *bufsiz,
			  const void *aarch_ssve,
			  int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_SSVE,
			     aarch_ssve, size);
}

char *
elfcore_write_aarch_za (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *aarch_za,
			int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_ZA,
			     aarch_za, size);
}

/* Write the buffer of zt register values in aarch_zt (length SIZE) into
   the note buffer BUF and update *BUFSIZ.  ABFD is the bfd the note is being
   written into.  Return a pointer to the new start of the note buffer, to
   replace BUF which may no longer be valid.  */

char *
elfcore_write_aarch_zt (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *aarch_zt,
			int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_ZT,
			     aarch_zt, size);
}

/* Write the buffer of GCS register values in AARCH_GCS (length SIZE) into
   the note buffer BUF and update *BUFSIZ.  ABFD is the bfd the note is being
   written into.  Return a pointer to the new start of the note buffer, to
   replace BUF which may no longer be valid.  */

static char *
elfcore_write_aarch_gcs (bfd *abfd, char *buf, int *bufsiz,
			 const void *aarch_gcs, int size)
{
  return elfcore_write_note (abfd, buf, bufsiz, NOTE_NAME_LINUX, NT_ARM_GCS,
			     aarch_gcs, size);
}

/* Write the buffer of FPMR value in AARCH_FPMR (length SIZE) into
   the note buffer BUF and update *BUFSIZ.  ABFD is the bfd the note is being
   written into.  Return a pointer to the new start of the note buffer, to
   replace BUF which may no longer be valid.  */

char *
elfcore_write_aarch_fpmr (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *aarch_fpmr,
			int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARM_FPMR, aarch_fpmr, size);
}

char *
elfcore_write_arc_v2 (bfd *abfd,
		      char *buf,
		      int *bufsiz,
		      const void *arc_v2,
		      int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_ARC_V2, arc_v2, size);
}

char *
elfcore_write_loongarch_cpucfg (bfd *abfd,
				char *buf,
				int *bufsiz,
				const void *loongarch_cpucfg,
				int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_LARCH_CPUCFG,
			     loongarch_cpucfg, size);
}

char *
elfcore_write_loongarch_lbt (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const void *loongarch_lbt,
			     int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_LARCH_LBT,
			     loongarch_lbt, size);
}

char *
elfcore_write_loongarch_lsx (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const void *loongarch_lsx,
			     int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_LARCH_LSX,
			     loongarch_lsx, size);
}

char *
elfcore_write_loongarch_lasx (bfd *abfd,
			      char *buf,
			      int *bufsiz,
			      const void *loongarch_lasx,
			      int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_LINUX, NT_LARCH_LASX,
			     loongarch_lasx, size);
}

/* Write the buffer of csr values in CSRS (length SIZE) into the note
   buffer BUF and update *BUFSIZ.  ABFD is the bfd the note is being
   written into.  Return a pointer to the new start of the note buffer, to
   replace BUF which may no longer be valid.  */

char *
elfcore_write_riscv_csr (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 const void *csrs,
			 int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_GDB, NT_RISCV_CSR, csrs, size);
}

/* Write the target description (a string) pointed to by TDESC, length
   SIZE, into the note buffer BUF, and update *BUFSIZ.  ABFD is the bfd the
   note is being written into.  Return a pointer to the new start of the
   note buffer, to replace BUF which may no longer be valid.  */

char *
elfcore_write_gdb_tdesc (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 const void *tdesc,
			 int size)
{
  return elfcore_write_note (abfd, buf, bufsiz,
			     NOTE_NAME_GDB, NT_GDB_TDESC, tdesc, size);
}

char *
elfcore_write_register_note (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const char *section,
			     const void *data,
			     int size)
{
  static const struct
    {
      const char * section_name;
      char *       (*writer) (bfd *, char *, int *, const void *, int);
    }
  note_writers [] =
    {
      { NOTE_PSEUDO_SECTION_AARCH_FPMR,       elfcore_write_aarch_fpmr},
      { NOTE_PSEUDO_SECTION_AARCH_GCS,        elfcore_write_aarch_gcs},
      { NOTE_PSEUDO_SECTION_AARCH_HW_BREAK,   elfcore_write_aarch_hw_break},
      { NOTE_PSEUDO_SECTION_AARCH_HW_WATCH,   elfcore_write_aarch_hw_watch},
      { NOTE_PSEUDO_SECTION_AARCH_MTE,        elfcore_write_aarch_mte},
      { NOTE_PSEUDO_SECTION_AARCH_PAUTH,      elfcore_write_aarch_pauth},
      { NOTE_PSEUDO_SECTION_AARCH_SSVE,       elfcore_write_aarch_ssve},
      { NOTE_PSEUDO_SECTION_AARCH_SVE,        elfcore_write_aarch_sve},
      { NOTE_PSEUDO_SECTION_AARCH_TLS,        elfcore_write_aarch_tls},
      { NOTE_PSEUDO_SECTION_AARCH_ZA,         elfcore_write_aarch_za},
      { NOTE_PSEUDO_SECTION_AARCH_ZT,         elfcore_write_aarch_zt},
      { NOTE_PSEUDO_SECTION_ARC_V2,           elfcore_write_arc_v2},
      { NOTE_PSEUDO_SECTION_ARM_VFP,          elfcore_write_arm_vfp},
      { NOTE_PSEUDO_SECTION_I386_TLS,         elfcore_write_i386_tls},
      { NOTE_PSEUDO_SECTION_LOONGARCH_CPUCFG, elfcore_write_loongarch_cpucfg},
      { NOTE_PSEUDO_SECTION_LOONGARCH_LASX,   elfcore_write_loongarch_lasx},
      { NOTE_PSEUDO_SECTION_LOONGARCH_LBT,    elfcore_write_loongarch_lbt},
      { NOTE_PSEUDO_SECTION_LOONGARCH_LSX,    elfcore_write_loongarch_lsx},
      { NOTE_PSEUDO_SECTION_PPC_DSCR,         elfcore_write_ppc_dscr},
      { NOTE_PSEUDO_SECTION_PPC_EBB,          elfcore_write_ppc_ebb},
      { NOTE_PSEUDO_SECTION_PPC_PMU,          elfcore_write_ppc_pmu},
      { NOTE_PSEUDO_SECTION_PPC_PPR,          elfcore_write_ppc_ppr},
      { NOTE_PSEUDO_SECTION_PPC_TAR,          elfcore_write_ppc_tar},
      { NOTE_PSEUDO_SECTION_PPC_TM_CDSCR,     elfcore_write_ppc_tm_cdscr},
      { NOTE_PSEUDO_SECTION_PPC_TM_CFPR,      elfcore_write_ppc_tm_cfpr},
      { NOTE_PSEUDO_SECTION_PPC_TM_CGPR,      elfcore_write_ppc_tm_cgpr},
      { NOTE_PSEUDO_SECTION_PPC_TM_CPPR,      elfcore_write_ppc_tm_cppr},
      { NOTE_PSEUDO_SECTION_PPC_TM_CTAR,      elfcore_write_ppc_tm_ctar},
      { NOTE_PSEUDO_SECTION_PPC_TM_CVMX,      elfcore_write_ppc_tm_cvmx},
      { NOTE_PSEUDO_SECTION_PPC_TM_CVSX,      elfcore_write_ppc_tm_cvsx},
      { NOTE_PSEUDO_SECTION_PPC_TM_SPR,       elfcore_write_ppc_tm_spr},
      { NOTE_PSEUDO_SECTION_PPC_VMX,          elfcore_write_ppc_vmx},
      { NOTE_PSEUDO_SECTION_PPC_VSX,          elfcore_write_ppc_vsx},
      { NOTE_PSEUDO_SECTION_REG2,             elfcore_write_prfpreg},
      { NOTE_PSEUDO_SECTION_RISCV_CSR,        elfcore_write_riscv_csr},
      { NOTE_PSEUDO_SECTION_S390_CTRS,        elfcore_write_s390_ctrs},
      { NOTE_PSEUDO_SECTION_S390_GS_BC,       elfcore_write_s390_gs_bc},
      { NOTE_PSEUDO_SECTION_S390_GS_CB,       elfcore_write_s390_gs_cb},
      { NOTE_PSEUDO_SECTION_S390_HIGH_GPRS,   elfcore_write_s390_high_gprs},
      { NOTE_PSEUDO_SECTION_S390_LAST_BREAK,  elfcore_write_s390_last_break},
      { NOTE_PSEUDO_SECTION_S390_PREFIX,      elfcore_write_s390_prefix},
      { NOTE_PSEUDO_SECTION_S390_SYSTEM_CALL, elfcore_write_s390_system_call},
      { NOTE_PSEUDO_SECTION_S390_TDB,         elfcore_write_s390_tdb},
      { NOTE_PSEUDO_SECTION_S390_TIMER,       elfcore_write_s390_timer},
      { NOTE_PSEUDO_SECTION_S390_TODCMP,      elfcore_write_s390_todcmp},
      { NOTE_PSEUDO_SECTION_S390_TODPREG,     elfcore_write_s390_todpreg},
      { NOTE_PSEUDO_SECTION_S390_VXRS_HIGH,   elfcore_write_s390_vxrs_high},
      { NOTE_PSEUDO_SECTION_S390_VXRS_LOW,    elfcore_write_s390_vxrs_low},
      { NOTE_PSEUDO_SECTION_SSP,              elfcore_write_sspreg},
      { NOTE_PSEUDO_SECTION_TDESC,            elfcore_write_gdb_tdesc},
      { NOTE_PSEUDO_SECTION_X86_SEGBASES,     elfcore_write_x86_segbases},
      { NOTE_PSEUDO_SECTION_XFP,              elfcore_write_prxfpreg},
      { NOTE_PSEUDO_SECTION_XSTATE,           elfcore_write_xstatereg} /* NB/ No comma.  */
    };

  int i;

  for (i = ARRAY_SIZE (note_writers); i--;)
    if (streq (section, note_writers[i].section_name))
      return  note_writers[i].writer (abfd, buf, bufsiz, data, size);

  return NULL;
}

char *
elfcore_write_file_note (bfd *obfd, char *note_data, int *note_size,
			 const void *buf, int bufsiz)
{
  return elfcore_write_note (obfd, note_data, note_size,
			     NOTE_NAME_CORE, NT_FILE, buf, bufsiz);
}

static bool
elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset,
		 size_t align)
{
  char *p;

  /* NB: CORE PT_NOTE segments may have p_align values of 0 or 1.
     gABI specifies that PT_NOTE alignment should be aligned to 4
     bytes for 32-bit objects and to 8 bytes for 64-bit objects.  If
     align is less than 4, we use 4 byte alignment.   */
  if (align < 4)
    align = 4;
  if (align != 4 && align != 8)
    return false;

  p = buf;
  while (p < buf + size)
    {
      Elf_External_Note *xnp = (Elf_External_Note *) p;
      Elf_Internal_Note in;

      if (offsetof (Elf_External_Note, name) > buf - p + size)
	return false;

      in.type = H_GET_32 (abfd, xnp->type);

      in.namesz = H_GET_32 (abfd, xnp->namesz);
      in.namedata = xnp->name;
      if (in.namesz > buf - in.namedata + size)
	return false;

      in.descsz = H_GET_32 (abfd, xnp->descsz);
      in.descdata = p + ELF_NOTE_DESC_OFFSET (in.namesz, align);
      in.descpos = offset + (in.descdata - buf);
      if (in.descsz != 0
	  && (in.descdata >= buf + size
	      || in.descsz > buf - in.descdata + size))
	return false;

      switch (bfd_get_format (abfd))
	{
	default:
	  return true;

	case bfd_core:
	  {
#define GROKER_ELEMENT(S,F) {S, sizeof (S) - 1, F}
	    static const struct
	    {
	      const char * string;
	      size_t len;
	      bool (*func) (bfd *, Elf_Internal_Note *);
	    }
	    grokers[] =
	    {
	      GROKER_ELEMENT ("", elfcore_grok_note),
	      GROKER_ELEMENT (NOTE_NAME_FREEBSD, elfcore_grok_freebsd_note),
	      GROKER_ELEMENT ("NetBSD-CORE", elfcore_grok_netbsd_note),
	      GROKER_ELEMENT ("OpenBSD", elfcore_grok_openbsd_note),
	      GROKER_ELEMENT ("QNX", elfcore_grok_nto_note),
	      GROKER_ELEMENT ("SPU/", elfcore_grok_spu_note),
	      GROKER_ELEMENT ("GNU", elfobj_grok_gnu_note),
	      GROKER_ELEMENT (NOTE_NAME_CORE, elfcore_grok_solaris_note)
	    };
#undef GROKER_ELEMENT
	    int i;

	    for (i = ARRAY_SIZE (grokers); i--;)
	      {
		if (in.namesz >= grokers[i].len
		    && strncmp (in.namedata, grokers[i].string,
				grokers[i].len) == 0)
		  {
		    if (! grokers[i].func (abfd, & in))
		      return false;
		    break;
		  }
	      }
	    break;
	  }

	case bfd_object:
	  if (in.namesz == sizeof "GNU" && strcmp (in.namedata, "GNU") == 0)
	    {
	      if (! elfobj_grok_gnu_note (abfd, &in))
		return false;
	    }
	  else if (in.namesz == sizeof "stapsdt"
		   && strcmp (in.namedata, "stapsdt") == 0)
	    {
	      if (! elfobj_grok_stapsdt_note (abfd, &in))
		return false;
	    }
	  break;
	}

      p += ELF_NOTE_NEXT_OFFSET (in.namesz, in.descsz, align);
    }

  return true;
}

bool
_bfd_elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size,
		     size_t align)
{
  char *buf;

  if (size == 0 || (size + 1) == 0)
    return true;

  if (bfd_seek (abfd, offset, SEEK_SET) != 0)
    return false;

  buf = (char *) _bfd_malloc_and_read (abfd, size + 1, size);
  if (buf == NULL)
    return false;

  /* PR 17512: file: ec08f814
     0-termintate the buffer so that string searches will not overflow.  */
  buf[size] = 0;

  if (!elf_parse_notes (abfd, buf, size, offset, align))
    {
      free (buf);
      return false;
    }

  free (buf);
  return true;
}

/* Providing external access to the ELF program header table.  */

/* Return an upper bound on the number of bytes required to store a
   copy of ABFD's program header table entries.  Return -1 if an error
   occurs; bfd_get_error will return an appropriate code.  */

long
bfd_get_elf_phdr_upper_bound (bfd *abfd)
{
  if (abfd->xvec->flavour != bfd_target_elf_flavour)
    {
      bfd_set_error (bfd_error_wrong_format);
      return -1;
    }

  return elf_elfheader (abfd)->e_phnum * sizeof (Elf_Internal_Phdr);
}

/* Copy ABFD's program header table entries to *PHDRS.  The entries
   will be stored as an array of Elf_Internal_Phdr structures, as
   defined in include/elf/internal.h.  To find out how large the
   buffer needs to be, call bfd_get_elf_phdr_upper_bound.

   Return the number of program header table entries read, or -1 if an
   error occurs; bfd_get_error will return an appropriate code.  */

int
bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
{
  int num_phdrs;

  if (abfd->xvec->flavour != bfd_target_elf_flavour)
    {
      bfd_set_error (bfd_error_wrong_format);
      return -1;
    }

  num_phdrs = elf_elfheader (abfd)->e_phnum;
  if (num_phdrs != 0)
    memcpy (phdrs, elf_tdata (abfd)->phdr,
	    num_phdrs * sizeof (Elf_Internal_Phdr));

  return num_phdrs;
}

enum elf_reloc_type_class
_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
			   const asection *rel_sec ATTRIBUTE_UNUSED,
			   const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
{
  return reloc_class_normal;
}

/* For RELA architectures, return the relocation value for a
   relocation against a local symbol.  */

bfd_vma
_bfd_elf_rela_local_sym (bfd *abfd,
			 Elf_Internal_Sym *sym,
			 asection **psec,
			 Elf_Internal_Rela *rel)
{
  asection *sec = *psec;
  bfd_vma relocation;

  relocation = (sec->output_section->vma
		+ sec->output_offset
		+ sym->st_value);
  if ((sec->flags & SEC_MERGE)
      && ELF_ST_TYPE (sym->st_info) == STT_SECTION
      && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
    {
      rel->r_addend =
	_bfd_merged_section_offset (abfd, psec,
				    sym->st_value + rel->r_addend);
      if (sec != *psec)
	{
	  /* If we have changed the section, and our original section is
	     marked with SEC_EXCLUDE, it means that the original
	     SEC_MERGE section has been completely subsumed in some
	     other SEC_MERGE section.  In this case, we need to leave
	     some info around for --emit-relocs.  */
	  if ((sec->flags & SEC_EXCLUDE) != 0)
	    sec->kept_section = *psec;
	  sec = *psec;
	}
      rel->r_addend -= relocation;
      rel->r_addend += sec->output_section->vma + sec->output_offset;
    }
  return relocation;
}

bfd_vma
_bfd_elf_rel_local_sym (bfd *abfd,
			Elf_Internal_Sym *sym,
			asection **psec,
			bfd_vma addend)
{
  asection *sec = *psec;

  if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
    return sym->st_value + addend;

  return _bfd_merged_section_offset (abfd, psec,
				     sym->st_value + addend);
}

/* Adjust an address within a section.  Given OFFSET within SEC, return
   the new offset within the section, based upon changes made to the
   section.  Returns -1 if the offset is now invalid.
   The offset (in abnd out) is in target sized bytes, however big a
   byte may be.  */

bfd_vma
_bfd_elf_section_offset (bfd *abfd,
			 struct bfd_link_info *info,
			 asection *sec,
			 bfd_vma offset)
{
  switch (sec->sec_info_type)
    {
    case SEC_INFO_TYPE_STABS:
      return _bfd_stab_section_offset (sec, offset);

    case SEC_INFO_TYPE_EH_FRAME:
      return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);

    case SEC_INFO_TYPE_SFRAME:
      return _bfd_elf_sframe_section_offset (abfd, info, sec, offset);

    default:
      if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
	{
	  /* Reverse the offset.  */
	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
	  bfd_size_type address_size = bed->s->arch_size / 8;

	  /* address_size and sec->size are in octets.  Convert
	     to bytes before subtracting the original offset.  */
	  offset = ((sec->size - address_size)
		    / bfd_octets_per_byte (abfd, sec) - offset);
	}
      return offset;
    }
}

long
_bfd_elf_get_synthetic_symtab (bfd *abfd,
			       long symcount ATTRIBUTE_UNUSED,
			       asymbol **syms ATTRIBUTE_UNUSED,
			       long dynsymcount,
			       asymbol **dynsyms,
			       asymbol **ret)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  asection *relplt;
  asymbol *s;
  const char *relplt_name;
  bool (*slurp_relocs) (bfd *, asection *, asymbol **, bool);
  arelent *p;
  long count, i, n;
  size_t size;
  Elf_Internal_Shdr *hdr;
  char *names;
  asection *plt;

  *ret = NULL;

  if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
    return 0;

  if (dynsymcount <= 0)
    return 0;

  if (!bed->plt_sym_val)
    return 0;

  relplt_name = bed->relplt_name;
  if (relplt_name == NULL)
    relplt_name = bed->rela_plts_and_copies_p ? ".rela.plt" : ".rel.plt";
  relplt = bfd_get_section_by_name (abfd, relplt_name);
  if (relplt == NULL)
    return 0;

  hdr = &elf_section_data (relplt)->this_hdr;
  if (hdr->sh_link != elf_dynsymtab (abfd)
      || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
    return 0;

  plt = bfd_get_section_by_name (abfd, ".plt");
  if (plt == NULL)
    return 0;

  slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
  if (! (*slurp_relocs) (abfd, relplt, dynsyms, true))
    return -1;

  count = NUM_SHDR_ENTRIES (hdr);
  size = count * sizeof (asymbol);
  p = relplt->relocation;
  for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
    {
      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
      if (p->addend != 0)
	{
#ifdef BFD64
	  size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
#else
	  size += sizeof ("+0x") - 1 + 8;
#endif
	}
    }

  s = *ret = (asymbol *) bfd_malloc (size);
  if (s == NULL)
    return -1;

  names = (char *) (s + count);
  p = relplt->relocation;
  n = 0;
  for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
    {
      size_t len;
      bfd_vma addr;

      addr = bed->plt_sym_val (i, plt, p);
      if (addr == (bfd_vma) -1)
	continue;

      *s = **p->sym_ptr_ptr;
      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
	 we are defining a symbol, ensure one of them is set.  */
      if ((s->flags & BSF_LOCAL) == 0)
	s->flags |= BSF_GLOBAL;
      s->flags |= BSF_SYNTHETIC;
      s->section = plt;
      s->value = addr - plt->vma;
      s->name = names;
      s->udata.p = NULL;
      len = strlen ((*p->sym_ptr_ptr)->name);
      memcpy (names, (*p->sym_ptr_ptr)->name, len);
      names += len;
      if (p->addend != 0)
	{
	  char buf[30], *a;

	  memcpy (names, "+0x", sizeof ("+0x") - 1);
	  names += sizeof ("+0x") - 1;
	  bfd_sprintf_vma (abfd, buf, p->addend);
	  for (a = buf; *a == '0'; ++a)
	    ;
	  len = strlen (a);
	  memcpy (names, a, len);
	  names += len;
	}
      memcpy (names, "@plt", sizeof ("@plt"));
      names += sizeof ("@plt");
      ++s, ++n;
    }

  return n;
}

bool
_bfd_elf_final_write_processing (bfd *abfd)
{
  Elf_Internal_Ehdr *i_ehdrp;	/* ELF file header, internal form.  */

  i_ehdrp = elf_elfheader (abfd);

  if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
    i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;

  /* Set the osabi field to ELFOSABI_GNU if the binary contains
     SHF_GNU_MBIND or SHF_GNU_RETAIN sections or symbols of STT_GNU_IFUNC type
     or STB_GNU_UNIQUE binding.  */
  if (elf_tdata (abfd)->has_gnu_osabi != 0)
    {
      if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
	i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
      else if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU
	       && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
	{
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind)
	    _bfd_error_handler (_("GNU_MBIND section is supported only by GNU "
				  "and FreeBSD targets"));
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_ifunc)
	    _bfd_error_handler (_("symbol type STT_GNU_IFUNC is supported "
				  "only by GNU and FreeBSD targets"));
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique)
	    _bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is supported "
				  "only by GNU and FreeBSD targets"));
	  if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_retain)
	    _bfd_error_handler (_("GNU_RETAIN section is supported "
				  "only by GNU and FreeBSD targets"));
	  bfd_set_error (bfd_error_sorry);
	  return false;
	}
    }
  return true;
}


/* Return TRUE for ELF symbol types that represent functions.
   This is the default version of this function, which is sufficient for
   most targets.  It returns true if TYPE is STT_FUNC or STT_GNU_IFUNC.  */

bool
_bfd_elf_is_function_type (unsigned int type)
{
  return (type == STT_FUNC
	  || type == STT_GNU_IFUNC);
}

/* If the ELF symbol SYM might be a function in SEC, return the
   function size and set *CODE_OFF to the function's entry point,
   otherwise return zero.  */

bfd_size_type
_bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
			     bfd_vma *code_off)
{
  bfd_size_type size;
  elf_symbol_type * elf_sym = (elf_symbol_type *) sym;

  if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
		     | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
      || sym->section != sec)
    return 0;

  size = (sym->flags & BSF_SYNTHETIC) ? 0 : elf_sym->internal_elf_sym.st_size;

  /* In theory we should check that the symbol's type satisfies
     _bfd_elf_is_function_type(), but there are some function-like
     symbols which would fail this test.  (eg _start).  Instead
     we check for hidden, local, notype symbols with zero size.
     This type of symbol is generated by the annobin plugin for gcc
     and clang, and should not be considered to be a function symbol.  */
  if (size == 0
      && ((sym->flags & (BSF_SYNTHETIC | BSF_LOCAL)) == BSF_LOCAL)
      && ELF_ST_TYPE (elf_sym->internal_elf_sym.st_info) == STT_NOTYPE
      && ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other) == STV_HIDDEN)
    return 0;

  *code_off = sym->value;
  /* Do not return 0 for the function's size.  */
  return size ? size : 1;
}

/* Set to non-zero to enable some debug messages.  */
#define DEBUG_SECONDARY_RELOCS	 0

/* An internal-to-the-bfd-library only section type
   used to indicate a cached secondary reloc section.  */
#define SHT_SECONDARY_RELOC	 (SHT_LOOS + SHT_RELA)

/* Create a BFD section to hold a secondary reloc section.  */

bool
_bfd_elf_init_secondary_reloc_section (bfd * abfd,
				       Elf_Internal_Shdr *hdr,
				       const char * name,
				       unsigned int shindex)
{
  /* We only support RELA secondary relocs.  */
  if (hdr->sh_type != SHT_RELA)
    return false;

#if DEBUG_SECONDARY_RELOCS
  fprintf (stderr, "secondary reloc section %s encountered\n", name);
#endif
  hdr->sh_type = SHT_SECONDARY_RELOC;
  return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
}

/* Read in any secondary relocs associated with SEC.  */

bool
_bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
					asection *  sec,
					asymbol **  symbols,
					bool dynamic)
{
  const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
  asection * relsec;
  bool result = true;
  bfd_vma (*r_sym) (bfd_vma);
  ufile_ptr filesize;

#if BFD_DEFAULT_TARGET_SIZE > 32
  if (bfd_arch_bits_per_address (abfd) != 32)
    r_sym = elf64_r_sym;
  else
#endif
    r_sym = elf32_r_sym;

  if (!elf_section_data (sec)->has_secondary_relocs)
    return true;

  /* Discover if there are any secondary reloc sections
     associated with SEC.  */
  filesize = bfd_get_file_size (abfd);
  for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
    {
      Elf_Internal_Shdr * hdr = & elf_section_data (relsec)->this_hdr;

      if (hdr->sh_type == SHT_SECONDARY_RELOC
	  && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx
	  && (hdr->sh_entsize == ebd->s->sizeof_rel
	      || hdr->sh_entsize == ebd->s->sizeof_rela))
	{
	  bfd_byte * native_relocs;
	  bfd_byte * native_reloc;
	  arelent * internal_relocs;
	  arelent * internal_reloc;
	  size_t i;
	  unsigned int entsize;
	  unsigned int symcount;
	  bfd_size_type reloc_count;
	  size_t amt;

	  if (ebd->elf_info_to_howto == NULL)
	    return false;

#if DEBUG_SECONDARY_RELOCS
	  fprintf (stderr, "read secondary relocs for %s from %s\n",
		   sec->name, relsec->name);
#endif
	  entsize = hdr->sh_entsize;

	  if (filesize != 0
	      && ((ufile_ptr) hdr->sh_offset > filesize
		  || hdr->sh_size > filesize - hdr->sh_offset))
	    {
	      bfd_set_error (bfd_error_file_truncated);
	      result = false;
	      continue;
	    }

	  native_relocs = bfd_malloc (hdr->sh_size);
	  if (native_relocs == NULL)
	    {
	      result = false;
	      continue;
	    }

	  reloc_count = NUM_SHDR_ENTRIES (hdr);
	  if (_bfd_mul_overflow (reloc_count, sizeof (arelent), & amt))
	    {
	      free (native_relocs);
	      bfd_set_error (bfd_error_file_too_big);
	      result = false;
	      continue;
	    }

	  internal_relocs = (arelent *) bfd_alloc (abfd, amt);
	  if (internal_relocs == NULL)
	    {
	      free (native_relocs);
	      result = false;
	      continue;
	    }

	  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
	      || bfd_read (native_relocs, hdr->sh_size, abfd) != hdr->sh_size)
	    {
	      free (native_relocs);
	      /* The internal_relocs will be freed when
		 the memory for the bfd is released.  */
	      result = false;
	      continue;
	    }

	  if (dynamic)
	    symcount = bfd_get_dynamic_symcount (abfd);
	  else
	    symcount = bfd_get_symcount (abfd);

	  for (i = 0, internal_reloc = internal_relocs,
		 native_reloc = native_relocs;
	       i < reloc_count;
	       i++, internal_reloc++, native_reloc += entsize)
	    {
	      bool res;
	      Elf_Internal_Rela rela;

	      if (entsize == ebd->s->sizeof_rel)
		ebd->s->swap_reloc_in (abfd, native_reloc, & rela);
	      else /* entsize == ebd->s->sizeof_rela */
		ebd->s->swap_reloca_in (abfd, native_reloc, & rela);

	      /* The address of an ELF reloc is section relative for an object
		 file, and absolute for an executable file or shared library.
		 The address of a normal BFD reloc is always section relative,
		 and the address of a dynamic reloc is absolute..  */
	      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
		internal_reloc->address = rela.r_offset;
	      else
		internal_reloc->address = rela.r_offset - sec->vma;

	      if (r_sym (rela.r_info) == STN_UNDEF)
		{
		  /* FIXME: This and the error case below mean that we
		     have a symbol on relocs that is not elf_symbol_type.  */
		  internal_reloc->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
		}
	      else if (r_sym (rela.r_info) > symcount)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB(%pA): relocation %zu has invalid symbol index %lu"),
		     abfd, sec, i, (long) r_sym (rela.r_info));
		  bfd_set_error (bfd_error_bad_value);
		  internal_reloc->sym_ptr_ptr = &bfd_abs_section_ptr->symbol;
		  result = false;
		}
	      else
		{
		  asymbol **ps;

		  ps = symbols + r_sym (rela.r_info) - 1;
		  internal_reloc->sym_ptr_ptr = ps;
		  /* Make sure that this symbol is not removed by strip.  */
		  (*ps)->flags |= BSF_KEEP;
		}

	      internal_reloc->addend = rela.r_addend;

	      res = ebd->elf_info_to_howto (abfd, internal_reloc, & rela);
	      if (! res || internal_reloc->howto == NULL)
		{
#if DEBUG_SECONDARY_RELOCS
		  fprintf (stderr,
			   "there is no howto associated with reloc %lx\n",
			   rela.r_info);
#endif
		  result = false;
		}
	    }

	  free (native_relocs);
	  /* Store the internal relocs.  */
	  relsec->sec_info = internal_relocs;
	}
    }

  return result;
}

/* Set the ELF section header fields of an output secondary reloc section.  */

bool
_bfd_elf_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
				      bfd *obfd ATTRIBUTE_UNUSED,
				      const Elf_Internal_Shdr *isection,
				      Elf_Internal_Shdr *osection)
{
  asection * isec;
  asection * osec;
  struct bfd_elf_section_data * esd;

  if (isection == NULL)
    return false;

  if (isection->sh_type != SHT_SECONDARY_RELOC)
    return true;

  isec = isection->bfd_section;
  if (isec == NULL)
    return false;

  osec = osection->bfd_section;
  if (osec == NULL)
    return false;

  BFD_ASSERT (osec->sec_info == NULL);
  osec->sec_info = isec->sec_info;
  osection->sh_type = SHT_RELA;
  osection->sh_link = elf_onesymtab (obfd);
  if (osection->sh_link == 0)
    {
      /* There is no symbol table - we are hosed...  */
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB(%pA): link section cannot be set"
	   " because the output file does not have a symbol table"),
	obfd, osec);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  /* Find the output section that corresponds to the isection's
     sh_info link.  */
  if (isection->sh_info == 0
      || isection->sh_info >= elf_numsections (ibfd))
    {
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB(%pA): info section index is invalid"),
	obfd, osec);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  isection = elf_elfsections (ibfd)[isection->sh_info];

  if (isection == NULL
      || isection->bfd_section == NULL
      || isection->bfd_section->output_section == NULL)
    {
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB(%pA): info section index cannot be set"
	   " because the section is not in the output"),
	obfd, osec);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  esd = elf_section_data (isection->bfd_section->output_section);
  BFD_ASSERT (esd != NULL);
  osection->sh_info = esd->this_idx;
  esd->has_secondary_relocs = true;
#if DEBUG_SECONDARY_RELOCS
  fprintf (stderr, "update header of %s, sh_link = %u, sh_info = %u\n",
	   osec->name, osection->sh_link, osection->sh_info);
  fprintf (stderr, "mark section %s as having secondary relocs\n",
	   bfd_section_name (isection->bfd_section->output_section));
#endif

  return true;
}

/* Write out a secondary reloc section.

   FIXME: Currently this function can result in a serious performance penalty
   for files with secondary relocs and lots of sections.  The proper way to
   fix this is for _bfd_elf_copy_special_section_fields() to chain secondary
   relocs together and then to have this function just walk that chain.  */

bool
_bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
{
  const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
  bfd_vma addr_offset;
  asection * relsec;
  bfd_vma (*r_info) (bfd_vma, bfd_vma);
  bool result = true;

  if (sec == NULL)
    return false;

#if BFD_DEFAULT_TARGET_SIZE > 32
  if (bfd_arch_bits_per_address (abfd) != 32)
    r_info = elf64_r_info;
  else
#endif
    r_info = elf32_r_info;

  /* The address of an ELF reloc is section relative for an object
     file, and absolute for an executable file or shared library.
     The address of a BFD reloc is always section relative.  */
  addr_offset = 0;
  if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
    addr_offset = sec->vma;

  /* Discover if there are any secondary reloc sections
     associated with SEC.  */
  for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
    {
      const struct bfd_elf_section_data * const esd = elf_section_data (relsec);
      Elf_Internal_Shdr * const hdr = (Elf_Internal_Shdr *) & esd->this_hdr;

      if (hdr->sh_type == SHT_RELA
	  && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx)
	{
	  asymbol *    last_sym;
	  int          last_sym_idx;
	  size_t       reloc_count;
	  size_t       idx;
	  bfd_size_type entsize;
	  arelent *    src_irel;
	  bfd_byte *   dst_rela;

	  if (hdr->contents != NULL)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB(%pA): error: secondary reloc section processed twice"),
		 abfd, relsec);
	      bfd_set_error (bfd_error_bad_value);
	      result = false;
	      continue;
	    }

	  entsize = hdr->sh_entsize;
	  if (entsize == 0)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB(%pA): error: secondary reloc section"
		   " has zero sized entries"),
		 abfd, relsec);
	      bfd_set_error (bfd_error_bad_value);
	      result = false;
	      continue;
	    }
	  else if (entsize != ebd->s->sizeof_rel
		   && entsize != ebd->s->sizeof_rela)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB(%pA): error: secondary reloc section"
		   " has non-standard sized entries"),
		 abfd, relsec);
	      bfd_set_error (bfd_error_bad_value);
	      result = false;
	      continue;
	    }

	  reloc_count = hdr->sh_size / entsize;
	  hdr->sh_size = entsize * reloc_count;
	  if (reloc_count == 0)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB(%pA): error: secondary reloc section is empty!"),
		 abfd, relsec);
	      bfd_set_error (bfd_error_bad_value);
	      result = false;
	      continue;
	    }

	  hdr->contents = bfd_alloc (abfd, hdr->sh_size);
	  if (hdr->contents == NULL)
	    continue;
	  relsec->alloced = 1;

#if DEBUG_SECONDARY_RELOCS
	  fprintf (stderr, "write %u secondary relocs for %s from %s\n",
		   reloc_count, sec->name, relsec->name);
#endif
	  last_sym = NULL;
	  last_sym_idx = 0;
	  dst_rela = hdr->contents;
	  src_irel = sec->sec_info;
	  if (src_irel == NULL)
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB(%pA): error: internal relocs missing"
		   " for secondary reloc section"),
		 abfd, relsec);
	      bfd_set_error (bfd_error_bad_value);
	      result = false;
	      continue;
	    }

	  for (idx = 0; idx < reloc_count; idx++, dst_rela += entsize)
	    {
	      Elf_Internal_Rela src_rela;
	      arelent *ptr;
	      asymbol *sym;
	      int n;

	      ptr = src_irel + idx;
	      if (ptr == NULL)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB(%pA): error: reloc table entry %zu is empty"),
		     abfd, relsec, idx);
		  bfd_set_error (bfd_error_bad_value);
		  result = false;
		  break;
		}

	      if (ptr->sym_ptr_ptr == NULL)
		{
		  /* FIXME: Is this an error ? */
		  n = 0;
		}
	      else
		{
		  sym = *ptr->sym_ptr_ptr;

		  if (sym == last_sym)
		    n = last_sym_idx;
		  else
		    {
		      n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
		      if (n < 0)
			{
			  _bfd_error_handler
			    /* xgettext:c-format */
			    (_("%pB(%pA): error: secondary reloc %zu"
			       " references a missing symbol"),
			     abfd, relsec, idx);
			  bfd_set_error (bfd_error_bad_value);
			  result = false;
			  n = 0;
			}

		      last_sym = sym;
		      last_sym_idx = n;
		    }

		  if (sym->the_bfd != NULL
		      && sym->the_bfd->xvec != abfd->xvec
		      && ! _bfd_elf_validate_reloc (abfd, ptr))
		    {
		      _bfd_error_handler
			/* xgettext:c-format */
			(_("%pB(%pA): error: secondary reloc %zu"
			   " references a deleted symbol"),
			 abfd, relsec, idx);
		      bfd_set_error (bfd_error_bad_value);
		      result = false;
		      n = 0;
		    }
		}

	      src_rela.r_offset = ptr->address + addr_offset;
	      if (ptr->howto == NULL)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB(%pA): error: secondary reloc %zu"
		       " is of an unknown type"),
		     abfd, relsec, idx);
		  bfd_set_error (bfd_error_bad_value);
		  result = false;
		  src_rela.r_info = r_info (0, 0);
		}
	      else
		src_rela.r_info = r_info (n, ptr->howto->type);
	      src_rela.r_addend = ptr->addend;

	      if (entsize == ebd->s->sizeof_rel)
		ebd->s->swap_reloc_out (abfd, &src_rela, dst_rela);
	      else /* entsize == ebd->s->sizeof_rela */
		ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
	    }
	}
    }

  return result;
}

/* Mmap in section contents.  */

static bool
elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf)
{
#ifdef USE_MMAP
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  if (bed->use_mmap
      && sec->compress_status == COMPRESS_SECTION_NONE
      && (sec->flags & SEC_LINKER_CREATED) == 0)
    {
      /* Use mmap only if section size >= the minimum mmap section
	 size.  */
      size_t readsz = bfd_get_section_limit_octets (abfd, sec);
      size_t allocsz = bfd_get_section_alloc_size (abfd, sec);
      if (readsz == allocsz && readsz >= _bfd_minimum_mmap_size)
	{
	  if (sec->contents != NULL)
	    {
	      if (!sec->mmapped_p)
		abort ();
	      *buf = sec->contents;
	      return true;
	    }
	  if (sec->mmapped_p)
	    abort ();
	  sec->mmapped_p = 1;

	  /* We can't use the final link preallocated buffer for mmap.  */
	  *buf = NULL;
	}
    }
#endif
  /* FIXME: We should not get here if sec->alloced is set.  */
  bool ret = bfd_get_full_section_contents (abfd, sec, buf);
  if (ret && sec->mmapped_p)
    *buf = sec->contents;
  return ret;
}

/* Mmap in section contents.  */

bool
_bfd_elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf)
{
  *buf = NULL;
  return elf_mmap_section_contents (abfd, sec, buf);
}

/* Mmap in the full section contents for the final link.  */

bool
_bfd_elf_link_mmap_section_contents (bfd *abfd, sec_ptr sec,
				     bfd_byte **buf)
{
  return elf_mmap_section_contents (abfd, sec, buf);
}

/* Munmap section contents.  */

void
_bfd_elf_munmap_section_contents (asection *sec, void *contents)
{
  /* NB: Since _bfd_elf_munmap_section_contents is called like free,
     CONTENTS may be NULL.  */
  if (contents == NULL)
    return;

  if (sec->alloced
      /* What a tangled web we weave with section contents.
	 FIXME: We shouldn't need to test anything but sec->alloced
	 here, but there are cases where a buffer is allocated for a
	 section but then another buffer is malloc'd anyway.  eg.
	 trace through ld-elf/eh4 testcase on x86_64.  */
      && (sec->contents == contents
	  || elf_section_data (sec)->this_hdr.contents == contents))
    return;

  /* Don't leave pointers to data we are about to munmap or free.  */
  if (sec->contents == contents)
    sec->contents = NULL;
  if (elf_section_data (sec)->this_hdr.contents == contents)
    elf_section_data (sec)->this_hdr.contents = NULL;

#ifdef USE_MMAP
  if (sec->mmapped_p)
    {
      /* When _bfd_elf_mmap_section_contents returns CONTENTS as
	 malloced, CONTENTS_ADDR is set to NULL.  */
      if (elf_section_data (sec)->contents_addr != NULL)
	{
	  /* NB: CONTENTS_ADDR and CONTENTS_SIZE must be valid.  */
	  if (munmap (elf_section_data (sec)->contents_addr,
		      elf_section_data (sec)->contents_size) != 0)
	    abort ();
	  sec->mmapped_p = 0;
	  elf_section_data (sec)->contents_addr = NULL;
	  elf_section_data (sec)->contents_size = 0;
	  return;
	}
    }
#endif

  free (contents);
}

/* Munmap the full section contents for the final link.  */

void
_bfd_elf_link_munmap_section_contents (asection *sec ATTRIBUTE_UNUSED)
{
#ifdef USE_MMAP
  if (sec->mmapped_p && elf_section_data (sec)->contents_addr != NULL)
    {
      /* When _bfd_elf_link_mmap_section_contents returns CONTENTS as
	 malloced, CONTENTS_ADDR is set to NULL.  */
      /* NB: CONTENTS_ADDR and CONTENTS_SIZE must be valid.  */
      if (munmap (elf_section_data (sec)->contents_addr,
		  elf_section_data (sec)->contents_size) != 0)
	abort ();
      sec->mmapped_p = 0;
      sec->contents = NULL;
      elf_section_data (sec)->this_hdr.contents = NULL;
      elf_section_data (sec)->contents_addr = NULL;
      elf_section_data (sec)->contents_size = 0;
    }
#endif
}
