/* ELF executable support for BFD.

   Copyright (C) 1993-2021 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

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)
{
  const unsigned char *name = (const unsigned char *) namearg;
  unsigned long h = 0;
  unsigned long g;
  int ch;

  while ((ch = *name++) != '\0')
    {
      h = (h << 4) + ch;
      if ((g = (h & 0xf0000000)) != 0)
	{
	  h ^= g >> 24;
	  /* The ELF ABI says `h &= ~g', but this is equivalent in
	     this case and on some machines one insn instead of two.  */
	  h ^= g;
	}
    }
  return h & 0xffffffff;
}

/* 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)
{
  const unsigned char *name = (const unsigned char *) namearg;
  unsigned long h = 5381;
  unsigned char ch;

  while ((ch = *name++) != '\0')
    h = (h << 5) + h + ch;
  return h & 0xffffffff;
}

/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
   the object_id field of an elf_obj_tdata field set to OBJECT_ID.  */
bool
bfd_elf_allocate_object (bfd *abfd,
			 size_t object_size,
			 enum elf_target_id object_id)
{
  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) = object_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)
{
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
				  bed->target_id);
}

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;

      /* Allocate and clear an extra byte at the end, to prevent crashes
	 in case the string table is not terminated.  */
      if (shstrtabsize + 1 <= 1
	  || bfd_seek (abfd, offset, SEEK_SET) != 0
	  || (shstrtab = _bfd_alloc_and_read (abfd, shstrtabsize + 1,
					      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
	shstrtab[shstrtabsize] = '\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;

  /* 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);
      intsym_buf = NULL;
      goto out;
    }
  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
  if (extsym_buf == NULL)
    {
      alloc_ext = bfd_malloc (amt);
      extsym_buf = alloc_ext;
    }
  if (extsym_buf == NULL
      || bfd_seek (ibfd, pos, SEEK_SET) != 0
      || bfd_bread (extsym_buf, amt, ibfd) != amt)
    {
      intsym_buf = NULL;
      goto out;
    }

  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 out;
	}
      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
      if (extshndx_buf == NULL)
	{
	  alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
	  extshndx_buf = alloc_extshndx;
	}
      if (extshndx_buf == NULL
	  || bfd_seek (ibfd, pos, SEEK_SET) != 0
	  || bfd_bread (extshndx_buf, amt, ibfd) != amt)
	{
	  intsym_buf = NULL;
	  goto out;
	}
    }

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

  /* 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 out;
      }

 out:
  free (alloc_ext);
  free (alloc_extshndx);

  return intsym_buf;
}

/* Look up a symbol name.  */
const char *
bfd_elf_sym_name (bfd *abfd,
		  Elf_Internal_Shdr *symtab_hdr,
		  Elf_Internal_Sym *isym,
		  asection *sym_sec)
{
  const char *name;
  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;
    }

  name = bfd_elf_string_from_elf_section (abfd, shindex, iname);
  if (name == NULL)
    name = "(null)";
  else if (sym_sec && *name == '\0')
    name = bfd_section_name (sym_sec);

  return name;
}

/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
   sections.  The first element is the flags, the rest are section
   pointers.  */

typedef union elf_internal_group {
  Elf_Internal_Shdr *shdr;
  unsigned int flags;
} Elf_Internal_Group;

/* 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 (abfd, hdr, &isym, NULL);
}

/* Set next_in_group list pointer, and group name for NEWSECT.  */

static bool
setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
{
  unsigned int num_group = elf_tdata (abfd)->num_group;

  /* If num_group is zero, read in all SHT_GROUP sections.  The count
     is set to -1 if there are no SHT_GROUP sections.  */
  if (num_group == 0)
    {
      unsigned int i, shnum;

      /* First count the number of groups.  If we have a SHT_GROUP
	 section with just a flag word (ie. sh_size is 4), ignore it.  */
      shnum = elf_numsections (abfd);
      num_group = 0;

#define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize)	\
	(   (shdr)->sh_type == SHT_GROUP		\
	 && (shdr)->sh_size >= minsize			\
	 && (shdr)->sh_entsize == GRP_ENTRY_SIZE	\
	 && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)

      for (i = 0; i < shnum; i++)
	{
	  Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];

	  if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
	    num_group += 1;
	}

      if (num_group == 0)
	{
	  num_group = (unsigned) -1;
	  elf_tdata (abfd)->num_group = num_group;
	  elf_tdata (abfd)->group_sect_ptr = NULL;
	}
      else
	{
	  /* We keep a list of elf section headers for group sections,
	     so we can find them quickly.  */
	  size_t amt;

	  elf_tdata (abfd)->num_group = num_group;
	  amt = num_group * sizeof (Elf_Internal_Shdr *);
	  elf_tdata (abfd)->group_sect_ptr
	    = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
	  if (elf_tdata (abfd)->group_sect_ptr == NULL)
	    return false;
	  num_group = 0;

	  for (i = 0; i < shnum; i++)
	    {
	      Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];

	      if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
		{
		  unsigned char *src;
		  Elf_Internal_Group *dest;

		  /* Make sure the group section has a BFD section
		     attached to it.  */
		  if (!bfd_section_from_shdr (abfd, i))
		    return false;

		  /* Add to list of sections.  */
		  elf_tdata (abfd)->group_sect_ptr[num_group] = shdr;
		  num_group += 1;

		  /* Read the raw contents.  */
		  BFD_ASSERT (sizeof (*dest) >= 4 && sizeof (*dest) % 4 == 0);
		  shdr->contents = NULL;
		  if (_bfd_mul_overflow (shdr->sh_size,
					 sizeof (*dest) / 4, &amt)
		      || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
		      || !(shdr->contents
			   = _bfd_alloc_and_read (abfd, amt, shdr->sh_size)))
		    {
		      _bfd_error_handler
			/* xgettext:c-format */
			(_("%pB: invalid size field in group section"
			   " header: %#" PRIx64 ""),
			 abfd, (uint64_t) shdr->sh_size);
		      bfd_set_error (bfd_error_bad_value);
		      -- num_group;
		      continue;
		    }

		  /* Translate raw contents, a flag word followed by an
		     array of elf section indices all in target byte order,
		     to the flag word followed by an array of elf section
		     pointers.  */
		  src = shdr->contents + shdr->sh_size;
		  dest = (Elf_Internal_Group *) (shdr->contents + amt);

		  while (1)
		    {
		      unsigned int idx;

		      src -= 4;
		      --dest;
		      idx = H_GET_32 (abfd, src);
		      if (src == shdr->contents)
			{
			  dest->shdr = NULL;
			  dest->flags = idx;
			  if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
			    shdr->bfd_section->flags
			      |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
			  break;
			}
		      if (idx < shnum)
			{
			  dest->shdr = elf_elfsections (abfd)[idx];
			  /* PR binutils/23199: All sections in a
			     section group should be marked with
			     SHF_GROUP.  But some tools generate
			     broken objects without SHF_GROUP.  Fix
			     them up here.  */
			  dest->shdr->sh_flags |= SHF_GROUP;
			}
		      if (idx >= shnum
			  || dest->shdr->sh_type == SHT_GROUP)
			{
			  _bfd_error_handler
			    (_("%pB: invalid entry in SHT_GROUP section [%u]"),
			       abfd, i);
			  dest->shdr = NULL;
			}
		    }
		}
	    }

	  /* PR 17510: Corrupt binaries might contain invalid groups.  */
	  if (num_group != (unsigned) elf_tdata (abfd)->num_group)
	    {
	      elf_tdata (abfd)->num_group = num_group;

	      /* If all groups are invalid then fail.  */
	      if (num_group == 0)
		{
		  elf_tdata (abfd)->group_sect_ptr = NULL;
		  elf_tdata (abfd)->num_group = num_group = -1;
		  _bfd_error_handler
		    (_("%pB: no valid group sections found"), abfd);
		  bfd_set_error (bfd_error_bad_value);
		}
	    }
	}
    }

  if (num_group != (unsigned) -1)
    {
      unsigned int search_offset = elf_tdata (abfd)->group_search_offset;
      unsigned int j;

      for (j = 0; j < num_group; j++)
	{
	  /* Begin search from previous found group.  */
	  unsigned i = (j + search_offset) % num_group;

	  Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
	  Elf_Internal_Group *idx;
	  bfd_size_type n_elt;

	  if (shdr == NULL)
	    continue;

	  idx = (Elf_Internal_Group *) shdr->contents;
	  if (idx == NULL || shdr->sh_size < 4)
	    {
	      /* See PR 21957 for a reproducer.  */
	      /* xgettext:c-format */
	      _bfd_error_handler (_("%pB: group section '%pA' has no contents"),
				  abfd, shdr->bfd_section);
	      elf_tdata (abfd)->group_sect_ptr[i] = NULL;
	      bfd_set_error (bfd_error_bad_value);
	      return false;
	    }
	  n_elt = shdr->sh_size / 4;

	  /* Look through this group's sections to see if current
	     section is a member.  */
	  while (--n_elt != 0)
	    if ((++idx)->shdr == hdr)
	      {
		asection *s = NULL;

		/* We are a member of this group.  Go looking through
		   other members to see if any others are linked via
		   next_in_group.  */
		idx = (Elf_Internal_Group *) shdr->contents;
		n_elt = shdr->sh_size / 4;
		while (--n_elt != 0)
		  if ((++idx)->shdr != NULL
		      && (s = idx->shdr->bfd_section) != NULL
		      && elf_next_in_group (s) != NULL)
		    break;
		if (n_elt != 0)
		  {
		    /* Snarf the group name from other member, and
		       insert current section in circular list.  */
		    elf_group_name (newsect) = elf_group_name (s);
		    elf_next_in_group (newsect) = elf_next_in_group (s);
		    elf_next_in_group (s) = newsect;
		  }
		else
		  {
		    const char *gname;

		    gname = group_signature (abfd, shdr);
		    if (gname == NULL)
		      return false;
		    elf_group_name (newsect) = gname;

		    /* Start a circular list with one element.  */
		    elf_next_in_group (newsect) = newsect;
		  }

		/* If the group section has been created, point to the
		   new member.  */
		if (shdr->bfd_section != NULL)
		  elf_next_in_group (shdr->bfd_section) = newsect;

		elf_tdata (abfd)->group_search_offset = i;
		j = num_group - 1;
		break;
	      }
	}
    }

  if (elf_group_name (newsect) == NULL)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: no group info for section '%pA'"),
			  abfd, newsect);
      return false;
    }
  return true;
}

bool
_bfd_elf_setup_sections (bfd *abfd)
{
  unsigned int i;
  unsigned int num_group = elf_tdata (abfd)->num_group;
  bool result = true;
  asection *s;

  /* Process SHF_LINK_ORDER.  */
  for (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;
	    }
	}
      else if (this_hdr->sh_type == SHT_GROUP
	       && elf_next_in_group (s) == NULL)
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: SHT_GROUP section [index %d] has no SHF_GROUP sections"),
	     abfd, elf_section_data (s)->this_idx);
	  result = false;
	}
    }

  /* Process section groups.  */
  if (num_group == (unsigned) -1)
    return result;

  for (i = 0; i < num_group; i++)
    {
      Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
      Elf_Internal_Group *idx;
      unsigned int n_elt;

      /* PR binutils/18758: Beware of corrupt binaries with invalid group data.  */
      if (shdr == NULL || shdr->bfd_section == NULL || shdr->contents == NULL)
	{
	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("%pB: section group entry number %u is corrupt"),
	     abfd, i);
	  result = false;
	  continue;
	}

      idx = (Elf_Internal_Group *) shdr->contents;
      n_elt = shdr->sh_size / 4;

      while (--n_elt != 0)
	{
	  ++ idx;

	  if (idx->shdr == NULL)
	    continue;
	  else if (idx->shdr->bfd_section)
	    elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
	  else if (idx->shdr->sh_type != SHT_RELA
		   && idx->shdr->sh_type != SHT_REL)
	    {
	      /* There are some unknown sections in the group.  */
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unknown type [%#x] section `%s' in group [%pA]"),
		 abfd,
		 idx->shdr->sh_type,
		 bfd_elf_string_from_elf_section (abfd,
						  (elf_elfheader (abfd)
						   ->e_shstrndx),
						  idx->shdr->sh_name),
		 shdr->bfd_section);
	      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;
}

static char *
convert_debug_to_zdebug (bfd *abfd, const char *name)
{
  unsigned int len = strlen (name);
  char *new_name = bfd_alloc (abfd, len + 2);
  if (new_name == NULL)
    return NULL;
  new_name[0] = '.';
  new_name[1] = 'z';
  memcpy (new_name + 2, name + 1, len);
  return new_name;
}

static char *
convert_zdebug_to_debug (bfd *abfd, const char *name)
{
  unsigned int len = strlen (name);
  char *new_name = bfd_alloc (abfd, len);
  if (new_name == NULL)
    return NULL;
  new_name[0] = '.';
  memcpy (new_name + 1, name + 2, len - 1);
  return new_name;
}

/* This a copy of lto_section defined in GCC (lto-streamer.h).  */

struct lto_section
{
  int16_t major_version;
  int16_t minor_version;
  unsigned char slim_object;

  /* Flags is a private field that is not defined publicly.  */
  uint16_t flags;
};

/* 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;
      newsect->entsize = hdr->sh_entsize;
    }
  if ((hdr->sh_flags & SHF_STRINGS) != 0)
    flags |= SEC_STRINGS;
  if (hdr->sh_flags & SHF_GROUP)
    if (!setup_group (abfd, hdr, newsect))
      return false;
  if ((hdr->sh_flags & SHF_TLS) != 0)
    flags |= SEC_THREAD_LOCAL;
  if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
    flags |= SEC_EXCLUDE;

  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) == 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")
		   || strcmp (name, ".gdb_index") == 0)
	    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)))
    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)
    {
      bfd_byte *contents;

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

      elf_parse_notes (abfd, (char *) contents, hdr->sh_size,
		       hdr->sh_offset, hdr->sh_addralign);
      free (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_* and
     .zdebug_*, after the section flags is set.  */
  if ((newsect->flags & SEC_DEBUGGING)
      && ((name[1] == 'd' && name[6] == '_')
	  || (name[1] == 'z' && name[7] == '_')))
    {
      enum { nothing, compress, decompress } action = nothing;
      int compression_header_size;
      bfd_size_type uncompressed_size;
      unsigned int uncompressed_align_power;
      bool compressed
	= bfd_is_section_compressed_with_header (abfd, newsect,
						 &compression_header_size,
						 &uncompressed_size,
						 &uncompressed_align_power);
      if (compressed)
	{
	  /* Compressed section.  Check if we should decompress.  */
	  if ((abfd->flags & BFD_DECOMPRESS))
	    action = decompress;
	}

      /* Compress the uncompressed section or convert from/to .zdebug*
	 section.  Check if we should compress.  */
      if (action == nothing)
	{
	  if (newsect->size != 0
	      && (abfd->flags & BFD_COMPRESS)
	      && compression_header_size >= 0
	      && uncompressed_size > 0
	      && (!compressed
		  || ((compression_header_size > 0)
		      != ((abfd->flags & BFD_COMPRESS_GABI) != 0))))
	    action = compress;
	  else
	    return true;
	}

      if (action == compress)
	{
	  if (!bfd_init_section_compress_status (abfd, newsect))
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unable to initialize compress status for section %s"),
		 abfd, name);
	      return false;
	    }
	}
      else
	{
	  if (!bfd_init_section_decompress_status (abfd, newsect))
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unable to initialize decompress status for section %s"),
		 abfd, name);
	      return false;
	    }
	}

      if (abfd->is_linker_input)
	{
	  if (name[1] == 'z'
	      && (action == decompress
		  || (action == compress
		      && (abfd->flags & BFD_COMPRESS_GABI) != 0)))
	    {
	      /* Convert section name from .zdebug_* to .debug_* so
		 that linker will consider this section as a debug
		 section.  */
	      char *new_name = convert_zdebug_to_debug (abfd, name);
	      if (new_name == NULL)
		return false;
	      bfd_rename_section (newsect, new_name);
	    }
	}
      else
	/* For objdump, don't rename the section.  For objcopy, delay
	   section rename to elf_fake_sections.  */
	newsect->flags |= SEC_ELF_RENAME;
    }

  /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode information
     section.  */
  if (startswith (name, ".gnu.lto_.lto."))
    {
      struct lto_section lsection;
      if (bfd_get_section_contents (abfd, newsect, &lsection, 0,
				    sizeof (struct lto_section)))
	abfd->lto_slim_object = lsection.slim_object;
    }

  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 = (const Elf_Internal_Shdr **) elf_elfsections (ibfd);
  Elf_Internal_Shdr **oheaders = elf_elfsections (obfd);
  const struct elf_backend_data *bed;
  unsigned int i;

  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
    || bfd_get_flavour (obfd) != 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);

  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;
    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)
    {
      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_malloc_and_get_section (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;

      extdyn = dynbuf;
      /* PR 17512: file: 6f427532.  */
      if (s->size < extdynsize)
	goto error_return;
      extdynend = extdyn + s->size;
      /* PR 17512: file: id:000006,sig:06,src:000000,op:flip4,pos:5664.
	 Fix range check.  */
      for (; extdyn <= (extdynend - 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 (!strcmp (name, ""))
		{
		  sprintf (ab, "%#" BFD_VMA_FMT "x", 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_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");
	}

      free (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:
  free (dynbuf);
  return false;
}

/* 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))
    {
      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
	      || strcmp (symbol->name, nodename) != 0)
	    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;
  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      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)
	  {
	    name = symbol->name;
	    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", name);
      }
      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.  */
      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 or SHN_AFTER.  */
	  switch (bfd_get_arch (abfd))
	    {
	    case bfd_arch_i386:
	    case bfd_arch_sparc:
	      if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
		  || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
		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 != NULL; 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 != NULL; 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:
      /* *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;

	if (hdr->sh_entsize
	    != (bfd_size_type) (hdr->sh_type == SHT_REL
				? bed->s->sizeof_rel : bed->s->sizeof_rela))
	  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;
	  }

	/* For some incomprehensible reason Oracle distributes
	   libraries for Solaris in which some of the objects have
	   bogus sh_link fields.  It would be nice if we could just
	   reject them, but, unfortunately, some people need to use
	   them.  We scan through the section headers; if we find only
	   one suitable symbol table, we clobber the sh_link to point
	   to it.  I hope this doesn't break anything.

	   Don't do it on executable nor shared library.  */
	if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0
	    && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_SYMTAB
	    && elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_DYNSYM)
	  {
	    unsigned int scan;
	    int found;

	    found = 0;
	    for (scan = 1; scan < num_sec; scan++)
	      {
		if (elf_elfsections (abfd)[scan]->sh_type == SHT_SYMTAB
		    || elf_elfsections (abfd)[scan]->sh_type == SHT_DYNSYM)
		  {
		    if (found != 0)
		      {
			found = 0;
			break;
		      }
		    found = scan;
		  }
	      }
	    if (found != 0)
	      hdr->sh_link = found;
	  }

	/* 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_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:
      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:
      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 (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE))
	goto fail;

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

      goto success;

    default:
      /* Possibly an attributes section.  */
      if (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.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 (".rela"),	  -1, SHT_RELA,	    0 },
  { 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 (! 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");

    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_st_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));
  reldata->hdr = rel_hdr;

  if (delay_st_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_st_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;

  if (arg->link_info)
    {
      /* ld: compress DWARF debug sections with names: .debug_*.  */
      if ((arg->link_info->compress_debug & COMPRESS_DEBUG)
	  && (asect->flags & SEC_DEBUGGING)
	  && name[1] == 'd'
	  && name[6] == '_')
	{
	  /* Set SEC_ELF_COMPRESS to indicate this section should be
	     compressed.  */
	  asect->flags |= SEC_ELF_COMPRESS;
	  /* 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_st_name_p = true;
	}
    }
  else if ((asect->flags & SEC_ELF_RENAME))
    {
      /* objcopy: rename output DWARF debug section.  */
      if ((abfd->flags & (BFD_DECOMPRESS | BFD_COMPRESS_GABI)))
	{
	  /* When we decompress or compress with SHF_COMPRESSED,
	     convert section name from .zdebug_* to .debug_* if
	     needed.  */
	  if (name[1] == 'z')
	    {
	      char *new_name = convert_zdebug_to_debug (abfd, name);
	      if (new_name == NULL)
		{
		  arg->failed = true;
		  return;
		}
	      name = new_name;
	    }
	}
      else if (asect->compress_status == COMPRESS_SECTION_DONE)
	{
	  /* PR binutils/18087: Compression does not always make a
	     section smaller.  So only rename the section when
	     compression has actually taken place.  If input section
	     name is .zdebug_*, we should never compress it again.  */
	  char *new_name = convert_debug_to_zdebug (abfd, name);
	  if (new_name == NULL)
	    {
	      arg->failed = true;
	      return;
	    }
	  BFD_ASSERT (name[1] != 'z');
	  name = new_name;
	}
    }

  if (delay_st_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->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;
  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 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_st_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_st_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_st_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 (elf_section_syms (abfd) == 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;
	}
    }

  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;
	      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;
	      H_PUT_32 (abfd, elf_sec->rela.idx, loc);
	    }
	  loc -= 4;
	  H_PUT_32 (abfd, elf_sec->this_idx, loc);
	}
      elt = elf_next_in_group (elt);
      if (elt == first)
	break;
    }

  loc -= 4;
  BFD_ASSERT (loc == sec->contents);

  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
      && strcmp (name, ".plt") == 0)
    {
      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 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;
	}

      /* Clear HAS_RELOC if there are no relocations.  */
      if (reloc_count == 0)
	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:
	  /* A reloc section which we are treating as a normal BFD
	     section.  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.  We assume that an
	     allocated reloc section uses the dynamic symbol table.
	     FIXME: How can we be sure?  */
	  s = bfd_get_section_by_name (abfd, ".dynsym");
	  if (s != NULL)
	    d->this_hdr.sh_link = elf_section_data (s)->this_idx;

	  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")
	      && strcmp (sec->name + strlen (sec->name) - 3, "str") == 0)
	    {
	      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 section symbols for sections that are not going to be
   output, that are duplicates or there is no BFD section.  */

static bool
ignore_section_sym (bfd *abfd, asymbol *sym)
{
  elf_symbol_type *type_ptr;

  if (sym == NULL)
    return false;

  if ((sym->flags & BSF_SECTION_SYM) == 0)
    return false;

  /* Ignore the section symbol if it isn't used.  */
  if ((sym->flags & BSF_SECTION_SYM_USED) == 0)
    return true;

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

  type_ptr = elf_symbol_from (sym);
  return ((type_ptr != NULL
	   && type_ptr->internal_elf_sym.st_shndx != 0
	   && bfd_is_abs_section (sym->section))
	  || !(sym->section->owner == abfd
	       || (sym->section->output_section != NULL
		   && sym->section->output_section->owner == abfd
		   && sym->section->output_offset == 0)
	       || bfd_is_abs_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 num_locals2 = 0;
  unsigned int num_globals2 = 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_section_sym (abfd, sym)
	  && !bfd_is_abs_section (sym->section))
	{
	  asection *sec = sym->section;

	  if (sec->owner != abfd)
	    sec = sec->output_section;

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

  /* Classify all of the symbols.  */
  for (idx = 0; idx < symcount; idx++)
    {
      if (sym_is_global (abfd, syms[idx]))
	num_globals++;
      else if (!ignore_section_sym (abfd, syms[idx]))
	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_section_sym (abfd, sym)
	  && sect_syms[asect->index] == NULL)
	{
	  if (!sym_is_global (abfd, asect->symbol))
	    num_locals++;
	  else
	    num_globals++;
	}
    }

  /* 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;

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

      if (sym_is_global (abfd, sym))
	i = num_locals + num_globals2++;
      /* Don't include ignored section symbols.  */
      else if (!ignore_section_sym (abfd, sym))
	i = num_locals2++;
      else
	continue;
      new_syms[i] = sym;
      sym->udata.i = i + 1;
    }
  for (asect = abfd->sections; asect; asect = asect->next)
    {
      asymbol *sym = asect->symbol;
      if (!ignore_section_sym (abfd, sym)
	  && sect_syms[asect->index] == NULL)
	{
	  unsigned int i;

	  sect_syms[asect->index] = sym;
	  if (!sym_is_global (abfd, sym))
	    i = num_locals2++;
	  else
	    i = num_locals + num_globals2++;
	  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;
}

/* Align to the maximum file alignment that could be required for any
   ELF data structure.  */

static inline file_ptr
align_file_position (file_ptr off, int align)
{
  return (off + align - 1) & ~(align - 1);
}

/* 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)
{
  if (align && i_shdrp->sh_addralign > 1)
    offset = BFD_ALIGN (offset, i_shdrp->sh_addralign);
  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)
	return false;
    }

  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))
    return false;

  if (need_symtab)
    {
      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);

      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);
	  /* 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);

      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))
	return false;
      _bfd_elf_strtab_free (strtab);
    }

  abfd->output_has_begun = true;

  return true;
}

/* 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 (abfd))
    {
      /* We need a PT_GNU_EH_FRAME segment.  */
      ++segs;
    }

  if (elf_stack_flags (abfd))
    {
      /* We need a PT_GNU_STACK 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.  */

bool
_bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
{
  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;

  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;
      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.  */
	      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 (abfd);
      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 (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 | SEC_HAS_CONTENTS))
			  == (SEC_LOAD | SEC_HAS_CONTENTS))
			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))
    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);
}

static bool
write_zeros (bfd *abfd, file_ptr pos, bfd_size_type len)
{
  void *buf;
  bool ret;

  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
    return false;
  buf = bfd_zmalloc (len);
  if (buf == NULL)
    return false;
  ret = bfd_bwrite (buf, len, abfd) == len;
  free (buf);
  return ret;
}

/* 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))
    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;

      /* 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;

      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;

	  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)
	{
	  if (!m->includes_filehdr)
	    p->p_offset = off;
	  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 (align < maxpagesize)
		align = maxpagesize;
	    }

	  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
	       && strcmp (m->sections[0]->name, ".dynamic") != 0)
	{
	  _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)
		{
		  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)
		{
		  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;
		  p->p_offset = off % align;
		}
	    }
	  else
	    {
	      file_ptr adjust;  /* Octets.  */

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

      /* 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) and
			     zero it.  */
			  adjust = p->p_memsz - p->p_filesz;
			  if (!write_zeros (abfd, off, adjust))
			    return false;
			}
		    }
		  /* 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 (p->p_type == PT_LOAD)
		{
		  this_hdr->sh_offset = sec->filepos = off;
		  if (this_hdr->sh_type != SHT_NOBITS)
		    off += this_hdr->sh_size;
		}
	      else if (this_hdr->sh_type == SHT_NOBITS
		       && (this_hdr->sh_flags & SHF_TLS) != 0
		       && this_hdr->sh_offset == 0)
		{
		  /* This is a .tbss section that didn't get a PT_LOAD.
		     (See _bfd_elf_map_sections_to_segments "Create a
		     final PT_LOAD".)  Set sh_offset to the value it
		     would have if we had created a zero p_filesz and
		     p_memsz PT_LOAD header for the section.  This
		     also makes the PT_TLS header have the same
		     p_offset value.  */
		  bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
							  off, align);
		  this_hdr->sh_offset = sec->filepos = off + adjust;
		}

	      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 %d"),
		     abfd, sec, j);
		  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_entry *hash
	= elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
				false, false, true);
      /* 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 the other sections, except for compressed debugging
   and other 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;

      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)
	    off += vma_page_aligned_bias (hdr->sh_addr, off,
					  maxpagesize);
	  else
	    off += vma_page_aligned_bias (hdr->sh_addr, off,
					  hdr->sh_addralign);
	  off = _bfd_elf_assign_file_position_for_section (hdr, off,
							   false);
	}
      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.  */
	       || (hdr->bfd_section != NULL
		   && (hdr->bfd_section->flags & SEC_ELF_COMPRESS
		       || (bfd_section_is_ctf (hdr->bfd_section)
			   && abfd->is_linker_output)))
	       || 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);
    }
  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 (link_info != NULL)
	    BFD_ASSERT (ok);
	  if (!ok)
	    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 - m->sections[0]->filepos
				     + 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.  */
	      || (hdr->bfd_section != NULL
		  && (hdr->bfd_section->flags & SEC_ELF_COMPRESS
		      || (bfd_section_is_ctf (hdr->bfd_section)
			  && abfd->is_linker_output)))
	      || 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
	    off = _bfd_elf_assign_file_position_for_section (hdr, off, true);
	}

      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 (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;

  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;
	  bool is_rel = (shdrp->sh_type == SHT_REL
			 || shdrp->sh_type == SHT_RELA);
	  bool is_ctf = sec && bfd_section_is_ctf (sec);
	  if (is_rel
	      || is_ctf
	      || (sec != NULL && (sec->flags & SEC_ELF_COMPRESS)))
	    {
	      if (!is_rel && !is_ctf)
		{
		  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)
		    {
		      /* If section is compressed with zlib-gnu, convert
			 section name from .debug_* to .zdebug_*.  */
		      char *new_name
			= convert_debug_to_zdebug (abfd, name);
		      if (new_name == NULL)
			return false;
		      name = new_name;
		    }
		  /* Add section name to section name section.  */
		  if (shdrp->sh_name != (unsigned int) -1)
		    abort ();
		  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;
		  shdrp->bfd_section->contents = NULL;
		}
	      else if (is_ctf)
		{
		  /* Update section size and contents.	*/
		  shdrp->sh_size = sec->size;
		  shdrp->contents = sec->contents;
		}

	      off = _bfd_elf_assign_file_position_for_section (shdrp,
							       off,
							       true);
	    }
	}
    }

  /* 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);

  /* Place the section headers.  */
  i_ehdrp = elf_elfheader (abfd);
  bed = get_elf_backend_data (abfd);
  off = align_file_position (off, 1 << 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++)
    {
      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_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
	    return false;
	}
    }

  /* Write out the section header names.  */
  t = elf_tdata (abfd);
  if (elf_shstrtab (abfd) != NULL
      && (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)
    return (*t->o->build_id.after_write_object_contents) (abfd);

  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;
      int indx;

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

/* 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;

  /* Returns the end address of the segment + 1.  */
#define SEGMENT_END(segment, start)					\
  (start + (segment->p_memsz > segment->p_filesz			\
	    ? segment->p_memsz : segment->p_filesz))

#define SECTION_SIZE(section, segment)					\
  (((section->flags & (SEC_HAS_CONTENTS | SEC_THREAD_LOCAL))		\
    != SEC_THREAD_LOCAL || segment->p_type == PT_TLS)			\
   ? section->size : 0)

  /* Returns TRUE if the given section is contained within
     the given segment.  VMA addresses are compared.  */
#define IS_CONTAINED_BY_VMA(section, segment, opb)			\
  (section->vma * (opb) >= segment->p_vaddr				\
   && (section->vma * (opb) + SECTION_SIZE (section, segment)		\
       <= (SEGMENT_END (segment, segment->p_vaddr))))

  /* Returns TRUE if the given section is contained within
     the given segment.  LMA addresses are compared.  */
#define IS_CONTAINED_BY_LMA(section, segment, base, opb)		\
  (section->lma * (opb) >= base						\
   && (section->lma + SECTION_SIZE (section, segment) / (opb) >= section->lma) \
   && (section->lma * (opb) + SECTION_SIZE (section, segment)		\
       <= SEGMENT_END (segment, base)))

  /* Handle PT_NOTE segment.  */
#define IS_NOTE(p, s)							\
  (p->p_type == PT_NOTE							\
   && elf_section_type (s) == SHT_NOTE					\
   && (bfd_vma) s->filepos >= p->p_offset				\
   && ((bfd_vma) s->filepos + s->size					\
       <= p->p_offset + p->p_filesz))

  /* Special case: corefile "NOTE" section containing regs, prpsinfo
     etc.  */
#define IS_COREFILE_NOTE(p, s)						\
  (IS_NOTE (p, s)							\
   && bfd_get_format (ibfd) == bfd_core					\
   && s->vma == 0							\
   && s->lma == 0)

  /* 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, bed, opb)		\
  ((((segment->p_paddr							\
      ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr, opb)	\
      : IS_CONTAINED_BY_VMA (section, segment, opb))			\
     && (section->flags & SEC_ALLOC) != 0)				\
    || IS_NOTE (segment, section))					\
   && 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))			\
       || (strcmp (bfd_section_name (section), ".dynamic") == 0))	\
   && (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, bed, opb)		\
  (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed, opb)		\
   && 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, bed, opb))
	    {
	      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.
	     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
	      && (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, bed, opb))
	    {
	      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_LMA (output_section, segment, map->p_paddr,
				       opb)
		  || IS_COREFILE_NOTE (segment, section)
		  || (bed->want_p_paddr_set_to_zero
		      && IS_CONTAINED_BY_VMA (output_section, segment, opb)))
		{
		  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_LMA (output_section, segment, map->p_paddr,
				       opb)
		  || IS_COREFILE_NOTE (segment, section))
		{
		  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 SEGMENT_END
#undef SECTION_SIZE
#undef IS_CONTAINED_BY_VMA
#undef IS_CONTAINED_BY_LMA
#undef IS_NOTE
#undef IS_COREFILE_NOTE
#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;
}

/* 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;
  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;
      }

  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;
      map->p_align_valid = 1;
      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 (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return true;

  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, *osec;
      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;
	       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;
		}
	    }
	}

      /* 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);
}

/* Initialize private output section information from input section.  */

bool
_bfd_elf_init_private_section_data (bfd *ibfd,
				    asection *isec,
				    bfd *obfd,
				    asection *osec,
				    struct bfd_link_info *link_info)

{
  Elf_Internal_Shdr *ihdr, *ohdr;
  bool final_link = (link_info != NULL
		     && !bfd_link_relocatable (link_info));

  if (ibfd->xvec->flavour != bfd_target_elf_flavour
      || obfd->xvec->flavour != bfd_target_elf_flavour)
    return true;

  BFD_ASSERT (elf_section_data (osec) != NULL);

  /* 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.  */
  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);

  /* FIXME: Is this correct for all OS/PROC specific flags?  */
  elf_section_flags (osec) = (elf_section_flags (isec)
			      & (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);

  ihdr = &elf_section_data (isec)->this_hdr;

  /* 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 = &elf_section_data (osec)->this_hdr;
      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;
}

/* Copy private section information.  This copies over the entsize
   field, and sometimes the info field.  */

bool
_bfd_elf_copy_private_section_data (bfd *ibfd,
				    asection *isec,
				    bfd *obfd,
				    asection *osec)
{
  Elf_Internal_Shdr *ihdr, *ohdr;

  if (ibfd->xvec->flavour != bfd_target_elf_flavour
      || obfd->xvec->flavour != bfd_target_elf_flavour)
    return true;

  ihdr = &elf_section_data (isec)->this_hdr;
  ohdr = &elf_section_data (osec)->this_hdr;

  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;

  return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
					     NULL);
}

/* 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
      || bfd_get_flavour (obfd) != 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,
				   asymbol *osymarg)
{
  elf_symbol_type *isym, *osym;

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

  isym = elf_symbol_from (isymarg);
  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_strtab_sec (ibfd))
	shndx = MAP_STRTAB;
      else if (shndx == elf_shstrtab_sec (ibfd))
	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_byte *) bfd_alloc (abfd, 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[0].sym = sym;
    symstrtab[0].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;)
    {
      Elf_Internal_Sym sym;
      bfd_vma value = syms[idx]->value;
      elf_symbol_type *type_ptr;
      flagword flags = syms[idx]->flags;
      int type;

      if (!name_local_sections
	  && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
	{
	  /* Local section symbols have no name.  */
	  sym.st_name = (unsigned long) -1;
	}
      else
	{
	  /* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
	     to get the final offset for st_name.  */
	  sym.st_name
	    = (unsigned long) _bfd_elf_strtab_add (stt, syms[idx]->name,
						   false);
	  if (sym.st_name == (unsigned long) -1)
	    goto error_return;
	}

      type_ptr = elf_symbol_from (syms[idx]);

      if ((flags & BSF_SECTION_SYM) == 0
	  && bfd_is_com_section (syms[idx]->section))
	{
	  /* 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, syms[idx]->section);
	}
      else
	{
	  asection *sec = syms[idx]->section;
	  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;
	}

      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;
	}

      idx++;
      symstrtab[idx].sym = sym;
      symstrtab[idx].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 <= symcount; idx++)
    {
      struct elf_sym_strtab *elfsym = &symstrtab[idx];
      if (elfsym->sym.st_name == (unsigned long) -1)
	elfsym->sym.st_name = 0;
      else
	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)
    {
      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;
    }
  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.  */
      struct bfd_elf_section_data *d = elf_section_data (asect);
      Elf_Internal_Shdr *rel_hdr = &d->this_hdr;
      bfd_size_type ext_rel_size = rel_hdr->sh_size;
      ufile_ptr filesize = bfd_get_file_size (abfd);

      if (filesize != 0 && ext_rel_size > filesize)
	{
	  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))
      {
	ext_rel_size += s->size;
	if (ext_rel_size < s->size)
	  {
	    bfd_set_error (bfd_error_file_truncated);
	    return -1;
	  }
	count += s->size / elf_section_data (s)->this_hdr.sh_entsize;
	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))
	{
	  arelent *p;
	  long count, i;

	  if (! (*slurp_relocs) (abfd, s, syms, true))
	    return -1;
	  count = s->size / elf_section_data (s)->this_hdr.sh_entsize;
	  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;

  if (elf_dynverref (abfd) != 0)
    {
      Elf_Internal_Shdr *hdr;
      Elf_External_Verneed *everneed;
      Elf_Internal_Verneed *iverneed;
      unsigned int i;
      bfd_byte *contents_end;

      hdr = &elf_tdata (abfd)->dynverref_hdr;

      if (hdr->sh_info == 0
	  || 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 = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
      if (contents == NULL)
	goto error_return_verref;

      if (_bfd_mul_overflow (hdr->sh_info, sizeof (Elf_Internal_Verneed), &amt))
	{
	  bfd_set_error (bfd_error_file_too_big);
	  goto error_return_verref;
	}
      elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) bfd_alloc (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 + hdr->sh_size - sizeof (Elf_External_Verneed);
      everneed = (Elf_External_Verneed *) contents;
      iverneed = elf_tdata (abfd)->verref;
      for (i = 0; i < hdr->sh_info; 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;

	  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);

	      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 (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;

      free (contents);
      contents = NULL;
    }

  if (elf_dynverdef (abfd) != 0)
    {
      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;

      hdr = &elf_tdata (abfd)->dynverdef_hdr;

      if (hdr->sh_info == 0 || 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 = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
      if (contents == NULL)
	goto error_return_verdef;

      BFD_ASSERT (sizeof (Elf_External_Verdef)
		  >= sizeof (Elf_External_Verdaux));
      contents_end_def = contents + hdr->sh_size
			 - sizeof (Elf_External_Verdef);
      contents_end_aux = contents + hdr->sh_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 < hdr->sh_info; ++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;
	}
      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 < hdr->sh_info; 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);

	      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));
	}

      free (contents);
      contents = 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;
	}
      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:
  free (contents);
  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)
{
  bool found;

  if (_bfd_dwarf2_find_nearest_line (abfd, 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)
{
  return _bfd_dwarf2_find_nearest_line (abfd, symbols, symbol, NULL, 0,
					filename_ptr, NULL, line_ptr, NULL,
					dwarf_debug_sections,
					&elf_tdata (abfd)->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)
{
  bool found;
  found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
					 functionname_ptr, line_ptr,
					 & elf_tdata (abfd)->dwarf2_find_line_info);
  return found;
}

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;
  file_ptr pos;

  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 ((section->flags & SEC_ELF_COMPRESS) == 0)
	{
	  _bfd_error_handler
	    (_("%pB:%pA: error: attempting to write into an unallocated compressed section"),
	     abfd, section);
	  bfd_set_error (bfd_error_invalid_operation);
	  return false;
	}
      
      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;
    }

  pos = hdr->sh_offset + offset;
  if (bfd_seek (abfd, pos, SEEK_SET) != 0
      || bfd_bwrite (location, count, abfd) != count)
    return false;

  return true;
}

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_close_and_cleanup (bfd *abfd)
{
  struct elf_obj_tdata *tdata = elf_tdata (abfd);
  if (tdata != NULL
      && (bfd_get_format (abfd) == bfd_object
	  || bfd_get_format (abfd) == bfd_core))
    {
      if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
	_bfd_elf_strtab_free (elf_shstrtab (abfd));
      _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
    }

  return _bfd_generic_close_and_cleanup (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, ".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, ".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, ".reg-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, ".reg-xstate", note);
}

static bool
elfcore_grok_ppc_vmx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vmx", note);
}

static bool
elfcore_grok_ppc_vsx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-vsx", note);
}

static bool
elfcore_grok_ppc_tar (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tar", note);
}

static bool
elfcore_grok_ppc_ppr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ppr", note);
}

static bool
elfcore_grok_ppc_dscr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-dscr", note);
}

static bool
elfcore_grok_ppc_ebb (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-ebb", note);
}

static bool
elfcore_grok_ppc_pmu (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-pmu", note);
}

static bool
elfcore_grok_ppc_tm_cgpr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cgpr", note);
}

static bool
elfcore_grok_ppc_tm_cfpr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cfpr", note);
}

static bool
elfcore_grok_ppc_tm_cvmx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvmx", note);
}

static bool
elfcore_grok_ppc_tm_cvsx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cvsx", note);
}

static bool
elfcore_grok_ppc_tm_spr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-spr", note);
}

static bool
elfcore_grok_ppc_tm_ctar (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-ctar", note);
}

static bool
elfcore_grok_ppc_tm_cppr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cppr", note);
}

static bool
elfcore_grok_ppc_tm_cdscr (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-ppc-tm-cdscr", note);
}

static bool
elfcore_grok_s390_high_gprs (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-high-gprs", note);
}

static bool
elfcore_grok_s390_timer (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-timer", note);
}

static bool
elfcore_grok_s390_todcmp (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-todcmp", note);
}

static bool
elfcore_grok_s390_todpreg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-todpreg", note);
}

static bool
elfcore_grok_s390_ctrs (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-ctrs", note);
}

static bool
elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
}

static bool
elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
}

static bool
elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
}

static bool
elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
}

static bool
elfcore_grok_s390_vxrs_low (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-low", note);
}

static bool
elfcore_grok_s390_vxrs_high (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-vxrs-high", note);
}

static bool
elfcore_grok_s390_gs_cb (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-cb", note);
}

static bool
elfcore_grok_s390_gs_bc (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-s390-gs-bc", note);
}

static bool
elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
}

static bool
elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note);
}

static bool
elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note);
}

static bool
elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note);
}

static bool
elfcore_grok_aarch_sve (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-sve", note);
}

static bool
elfcore_grok_aarch_pauth (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-pauth", note);
}

static bool
elfcore_grok_aarch_mte (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-mte",
					  note);
}

static bool
elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-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, ".reg-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_loongarch_cpucfg (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-cpucfg", note);
}

static bool
elfcore_grok_loongarch_lbt (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lbt", note);
}

static bool
elfcore_grok_loongarch_lsx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-loongarch-lsx", note);
}

static bool
elfcore_grok_loongarch_lasx (bfd *abfd, Elf_Internal_Note *note)
{
  return elfcore_make_note_pseudosection (abfd, ".reg-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, ".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, ".reg", sect))
    return false;

  /* Make a ".reg2/999" section */

  sprintf (buf, ".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, ".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);

  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, ".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, ".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);

  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_PRXFPREG:		/* Linux SSE extension */
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_prxfpreg (abfd, note);
      else
	return true;

    case NT_X86_XSTATE:		/* Linux XSAVE extension */
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_xstatereg (abfd, note);
      else
	return true;

    case NT_PPC_VMX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_vmx (abfd, note);
      else
	return true;

    case NT_PPC_VSX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_vsx (abfd, note);
      else
	return true;

    case NT_PPC_TAR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tar (abfd, note);
      else
	return true;

    case NT_PPC_PPR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_ppr (abfd, note);
      else
	return true;

    case NT_PPC_DSCR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_dscr (abfd, note);
      else
	return true;

    case NT_PPC_EBB:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_ebb (abfd, note);
      else
	return true;

    case NT_PPC_PMU:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_pmu (abfd, note);
      else
	return true;

    case NT_PPC_TM_CGPR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_cgpr (abfd, note);
      else
	return true;

    case NT_PPC_TM_CFPR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_cfpr (abfd, note);
      else
	return true;

    case NT_PPC_TM_CVMX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_cvmx (abfd, note);
      else
	return true;

    case NT_PPC_TM_CVSX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_cvsx (abfd, note);
      else
	return true;

    case NT_PPC_TM_SPR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_spr (abfd, note);
      else
	return true;

    case NT_PPC_TM_CTAR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_ctar (abfd, note);
      else
	return true;

    case NT_PPC_TM_CPPR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_cppr (abfd, note);
      else
	return true;

    case NT_PPC_TM_CDSCR:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_ppc_tm_cdscr (abfd, note);
      else
	return true;

    case NT_S390_HIGH_GPRS:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_high_gprs (abfd, note);
      else
	return true;

    case NT_S390_TIMER:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_timer (abfd, note);
      else
	return true;

    case NT_S390_TODCMP:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_todcmp (abfd, note);
      else
	return true;

    case NT_S390_TODPREG:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_todpreg (abfd, note);
      else
	return true;

    case NT_S390_CTRS:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_ctrs (abfd, note);
      else
	return true;

    case NT_S390_PREFIX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_prefix (abfd, note);
      else
	return true;

    case NT_S390_LAST_BREAK:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_last_break (abfd, note);
      else
	return true;

    case NT_S390_SYSTEM_CALL:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_system_call (abfd, note);
      else
	return true;

    case NT_S390_TDB:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_tdb (abfd, note);
      else
	return true;

    case NT_S390_VXRS_LOW:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_vxrs_low (abfd, note);
      else
	return true;

    case NT_S390_VXRS_HIGH:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_vxrs_high (abfd, note);
      else
	return true;

    case NT_S390_GS_CB:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_gs_cb (abfd, note);
      else
	return true;

    case NT_S390_GS_BC:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_s390_gs_bc (abfd, note);
      else
	return true;

    case NT_ARC_V2:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_arc_v2 (abfd, note);
      else
	return true;

    case NT_ARM_VFP:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_arm_vfp (abfd, note);
      else
	return true;

    case NT_ARM_TLS:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_aarch_tls (abfd, note);
      else
	return true;

    case NT_ARM_HW_BREAK:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_aarch_hw_break (abfd, note);
      else
	return true;

    case NT_ARM_HW_WATCH:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_aarch_hw_watch (abfd, note);
      else
	return true;

    case NT_ARM_SVE:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_aarch_sve (abfd, note);
      else
	return true;

    case NT_ARM_PAC_MASK:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_aarch_pauth (abfd, note);
      else
	return true;

    case NT_ARM_TAGGED_ADDR_CTRL:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_aarch_mte (abfd, note);
      else
	return true;

    case NT_GDB_TDESC:
      if (note->namesz == 4
          && strcmp (note->namedata, "GDB") == 0)
        return elfcore_grok_gdb_tdesc (abfd, note);
      else
        return true;

    case NT_RISCV_CSR:
      if (note->namesz == 4
          && strcmp (note->namedata, "GDB") == 0)
        return elfcore_grok_riscv_csr (abfd, note);
      else
	return true;

    case NT_LARCH_CPUCFG:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_loongarch_cpucfg (abfd, note);
      else
	return true;

    case NT_LARCH_LBT:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_loongarch_lbt (abfd, note);
      else
	return true;

    case NT_LARCH_LSX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_loongarch_lsx (abfd, note);
      else
	return true;

    case NT_LARCH_LASX:
      if (note->namesz == 6
	  && strcmp (note->namedata, "LINUX") == 0)
	return elfcore_grok_loongarch_lasx (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, ".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:
      if (note->namesz == 8)
	return elfcore_make_note_pseudosection (abfd, ".thrmisc", note);
      else
	return true;

    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_X86_XSTATE:
      if (note->namesz == 8)
	return elfcore_grok_xstatereg (abfd, note);
      else
	return true;

    case NT_FREEBSD_PTLWPINFO:
      return elfcore_make_note_pseudosection (abfd, ".note.freebsdcore.lwpinfo",
					      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, ".reg", note);

	case NT_NETBSDCORE_FIRSTMACH+2:
	  return elfcore_make_note_pseudosection (abfd, ".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, ".reg", note);

	case NT_NETBSDCORE_FIRSTMACH+5:
	  return elfcore_make_note_pseudosection (abfd, ".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, ".reg", note);

	case NT_NETBSDCORE_FIRSTMACH+3:
	  return elfcore_make_note_pseudosection (abfd, ".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, ".reg");
  if (sect != NULL)
    sect->size = gregset_size;

  return _bfd_elfcore_make_pseudosection (abfd, ".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", ".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, ".reg");
  if (sect != NULL)
    sect->size = gregset_size;
  else if (!_bfd_elfcore_make_pseudosection (abfd, ".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, ".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, ".reg", note);

  if (note->type == NT_OPENBSD_FPREGS)
    return elfcore_make_note_pseudosection (abfd, ".reg2", note);

  if (note->type == NT_OPENBSD_XFPREGS)
    return elfcore_make_note_pseudosection (abfd, ".reg-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;
}

#define BFD_QNT_CORE_INFO	7
#define BFD_QNT_CORE_STATUS	8
#define BFD_QNT_CORE_GREG	9
#define BFD_QNT_CORE_FPREG	10

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 BFD_QNT_CORE_INFO:
      return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
    case BFD_QNT_CORE_STATUS:
      return elfcore_grok_nto_status (abfd, note, &tid);
    case BFD_QNT_CORE_GREG:
      return elfcore_grok_nto_regs (abfd, note, tid, ".reg");
    case BFD_QNT_CORE_FPREG:
      return elfcore_grok_nto_regs (abfd, note, tid, ".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,
				 "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,
				 "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, "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, "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,
				 "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,
				 "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, "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, "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;
  const char *note_name = "CORE";

  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,
			     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)
{
  const char *note_name = "CORE";
#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,
				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,
				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)
{
  const char *note_name = "CORE";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_FPREGSET, fpregs, size);
}

char *
elfcore_write_prxfpreg (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *xfpregs,
			int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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 = "FreeBSD";
  else
    note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_X86_XSTATE, xfpregs, size);
}

char *
elfcore_write_ppc_vmx (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_vmx,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_PPC_VMX, ppc_vmx, size);
}

char *
elfcore_write_ppc_vsx (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_vsx,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_PPC_VSX, ppc_vsx, size);
}

char *
elfcore_write_ppc_tar (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_tar,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_PPC_TAR, ppc_tar, size);
}

char *
elfcore_write_ppc_ppr (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_ppr,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_PPC_PPR, ppc_ppr, size);
}

char *
elfcore_write_ppc_dscr (bfd *abfd,
			char *buf,
			int *bufsiz,
			const void *ppc_dscr,
			int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_PPC_DSCR, ppc_dscr, size);
}

char *
elfcore_write_ppc_ebb (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_ebb,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_PPC_EBB, ppc_ebb, size);
}

char *
elfcore_write_ppc_pmu (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *ppc_pmu,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_S390_TIMER, s390_timer, size);
}

char *
elfcore_write_s390_todcmp (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *s390_todcmp,
			   int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_S390_TODCMP, s390_todcmp, size);
}

char *
elfcore_write_s390_todpreg (bfd *abfd,
			    char *buf,
			    int *bufsiz,
			    const void *s390_todpreg,
			    int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_S390_TODPREG, s390_todpreg, size);
}

char *
elfcore_write_s390_ctrs (bfd *abfd,
			 char *buf,
			 int *bufsiz,
			 const void *s390_ctrs,
			 int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_S390_CTRS, s390_ctrs, size);
}

char *
elfcore_write_s390_prefix (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *s390_prefix,
			   int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_ARM_VFP, arm_vfp, size);
}

char *
elfcore_write_aarch_tls (bfd *abfd,
		       char *buf,
		       int *bufsiz,
		       const void *aarch_tls,
		       int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_ARM_SVE, aarch_sve, size);
}

char *
elfcore_write_aarch_pauth (bfd *abfd,
			   char *buf,
			   int *bufsiz,
			   const void *aarch_pauth,
			   int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_ARM_PAC_MASK, aarch_pauth, size);
}

char *
elfcore_write_aarch_mte (bfd *abfd,
				      char *buf,
				      int *bufsiz,
				      const void *aarch_mte,
				      int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_ARM_TAGGED_ADDR_CTRL,
			     aarch_mte,
			     size);
}

char *
elfcore_write_arc_v2 (bfd *abfd,
		      char *buf,
		      int *bufsiz,
		      const void *arc_v2,
		      int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_ARC_V2, arc_v2, size);
}

char *
elfcore_write_loongarch_cpucfg (bfd *abfd,
				char *buf,
				int *bufsiz,
				const void *loongarch_cpucfg,
				int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_LARCH_CPUCFG,
			     loongarch_cpucfg, size);
}

char *
elfcore_write_loongarch_lbt (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const void *loongarch_lbt,
			     int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_LARCH_LBT, loongarch_lbt, size);
}

char *
elfcore_write_loongarch_lsx (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const void *loongarch_lsx,
			     int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, NT_LARCH_LSX, loongarch_lsx, size);
}

char *
elfcore_write_loongarch_lasx (bfd *abfd,
			      char *buf,
			      int *bufsiz,
			      const void *loongarch_lasx,
			      int size)
{
  char *note_name = "LINUX";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  const char *note_name = "GDB";
  return elfcore_write_note (abfd, buf, bufsiz,
			     note_name, 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)
{
  const char *note_name = "GDB";
  return elfcore_write_note (abfd, buf, bufsiz,
                             note_name, NT_GDB_TDESC, tdesc, size);
}

char *
elfcore_write_register_note (bfd *abfd,
			     char *buf,
			     int *bufsiz,
			     const char *section,
			     const void *data,
			     int size)
{
  if (strcmp (section, ".reg2") == 0)
    return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-xfp") == 0)
    return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-xstate") == 0)
    return elfcore_write_xstatereg (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-vmx") == 0)
    return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-vsx") == 0)
    return elfcore_write_ppc_vsx (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tar") == 0)
    return elfcore_write_ppc_tar (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-ppr") == 0)
    return elfcore_write_ppc_ppr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-dscr") == 0)
    return elfcore_write_ppc_dscr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-ebb") == 0)
    return elfcore_write_ppc_ebb (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-pmu") == 0)
    return elfcore_write_ppc_pmu (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-cgpr") == 0)
    return elfcore_write_ppc_tm_cgpr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-cfpr") == 0)
    return elfcore_write_ppc_tm_cfpr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-cvmx") == 0)
    return elfcore_write_ppc_tm_cvmx (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-cvsx") == 0)
    return elfcore_write_ppc_tm_cvsx (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-spr") == 0)
    return elfcore_write_ppc_tm_spr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-ctar") == 0)
    return elfcore_write_ppc_tm_ctar (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-cppr") == 0)
    return elfcore_write_ppc_tm_cppr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-ppc-tm-cdscr") == 0)
    return elfcore_write_ppc_tm_cdscr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-high-gprs") == 0)
    return elfcore_write_s390_high_gprs (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-timer") == 0)
    return elfcore_write_s390_timer (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-todcmp") == 0)
    return elfcore_write_s390_todcmp (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-todpreg") == 0)
    return elfcore_write_s390_todpreg (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-ctrs") == 0)
    return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-prefix") == 0)
    return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-last-break") == 0)
    return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-system-call") == 0)
    return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-tdb") == 0)
    return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-vxrs-low") == 0)
    return elfcore_write_s390_vxrs_low (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-vxrs-high") == 0)
    return elfcore_write_s390_vxrs_high (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-gs-cb") == 0)
    return elfcore_write_s390_gs_cb (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-s390-gs-bc") == 0)
    return elfcore_write_s390_gs_bc (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-arm-vfp") == 0)
    return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-aarch-tls") == 0)
    return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-aarch-hw-break") == 0)
    return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-aarch-hw-watch") == 0)
    return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-aarch-sve") == 0)
    return elfcore_write_aarch_sve (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-aarch-pauth") == 0)
    return elfcore_write_aarch_pauth (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-aarch-mte") == 0)
    return elfcore_write_aarch_mte (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-arc-v2") == 0)
    return elfcore_write_arc_v2 (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".gdb-tdesc") == 0)
    return elfcore_write_gdb_tdesc (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-riscv-csr") == 0)
    return elfcore_write_riscv_csr (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-loongarch-cpucfg") == 0)
    return elfcore_write_loongarch_cpucfg (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-loongarch-lbt") == 0)
    return elfcore_write_loongarch_lbt (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-loongarch-lsx") == 0)
    return elfcore_write_loongarch_lsx (abfd, buf, bufsiz, data, size);
  if (strcmp (section, ".reg-loongarch-lasx") == 0)
    return elfcore_write_loongarch_lasx (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,
			     "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}
	    struct
	    {
	      const char * string;
	      size_t len;
	      bool (*func) (bfd *, Elf_Internal_Note *);
	    }
	    grokers[] =
	    {
	      GROKER_ELEMENT ("", elfcore_grok_note),
	      GROKER_ELEMENT ("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 ("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
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,
				    elf_section_data (sec)->sec_info,
				    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,
				     elf_section_data (sec)->sec_info,
				     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, elf_section_data (sec)->sec_info,
				       offset);
    case SEC_INFO_TYPE_EH_FRAME:
      return _bfd_elf_eh_frame_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;
    }
}

/* Create a new BFD as if by bfd_openr.  Rather than opening a file,
   reconstruct an ELF file by reading the segments out of remote memory
   based on the ELF file header at EHDR_VMA and the ELF program headers it
   points to.  If not null, *LOADBASEP is filled in with the difference
   between the VMAs from which the segments were read, and the VMAs the
   file headers (and hence BFD's idea of each section's VMA) put them at.

   The function TARGET_READ_MEMORY is called to copy LEN bytes from the
   remote memory at target address VMA into the local buffer at MYADDR; it
   should return zero on success or an `errno' code on failure.  TEMPL must
   be a BFD for an ELF target with the word size and byte order found in
   the remote memory.  */

bfd *
bfd_elf_bfd_from_remote_memory
  (bfd *templ,
   bfd_vma ehdr_vma,
   bfd_size_type size,
   bfd_vma *loadbasep,
   int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
{
  return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
    (templ, ehdr_vma, size, loadbasep, target_read_memory);
}

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 = relplt->size / hdr->sh_entsize;
  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;
}

/* It is only used by x86-64 so far.
   ??? This repeats *COM* id of zero.  sec->id is supposed to be unique,
   but current usage would allow all of _bfd_std_section to be zero.  */
static const asymbol lcomm_sym
  = GLOBAL_SYM_INIT ("LARGE_COMMON", &_bfd_elf_large_com_section);
asection _bfd_elf_large_com_section
  = BFD_FAKE_SECTION (_bfd_elf_large_com_section, &lcomm_sym,
		      "LARGE_COMMON", 0, SEC_IS_COMMON);

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);

#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.  */
  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;
	  unsigned int i;
	  unsigned int entsize;
	  unsigned int symcount;
	  unsigned int 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;

	  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_bread (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_ptr_ptr;
		}
	      else if (r_sym (rela.r_info) > symcount)
		{
		  _bfd_error_handler
		    /* xgettext:c-format */
		    (_("%pB(%pA): relocation %d has invalid symbol index %ld"),
		     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_ptr_ptr;
		  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.  */
	  elf_section_data (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;

  esd = elf_section_data (osec);
  BFD_ASSERT (esd->sec_info == NULL);
  esd->sec_info = elf_section_data (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;
	  unsigned int reloc_count;
	  unsigned int idx;
	  unsigned int 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;
	  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;

#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 = (arelent *) esd->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 %u 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 %u 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 %u 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 %u 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;
}
