/* .eh_frame section optimization.
   Copyright (C) 2001-2024 Free Software Foundation, Inc.
   Written by Jakub Jelinek <jakub@redhat.com>.

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

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "dwarf2.h"

#define EH_FRAME_HDR_SIZE 8

struct cie
{
  unsigned int length;
  unsigned int hash;
  unsigned char version;
  unsigned char local_personality;
  char augmentation[20];
  bfd_vma code_align;
  bfd_signed_vma data_align;
  bfd_vma ra_column;
  bfd_vma augmentation_size;
  union {
    struct elf_link_hash_entry *h;
    struct {
      unsigned int bfd_id;
      unsigned int index;
    } sym;
    unsigned int reloc_index;
  } personality;
  struct eh_cie_fde *cie_inf;
  unsigned char per_encoding;
  unsigned char lsda_encoding;
  unsigned char fde_encoding;
  unsigned char initial_insn_length;
  unsigned char can_make_lsda_relative;
  unsigned char initial_instructions[50];
};



/* If *ITER hasn't reached END yet, read the next byte into *RESULT and
   move onto the next byte.  Return true on success.  */

static inline bool
read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result)
{
  if (*iter >= end)
    return false;
  *result = *((*iter)++);
  return true;
}

/* Move *ITER over LENGTH bytes, or up to END, whichever is closer.
   Return true it was possible to move LENGTH bytes.  */

static inline bool
skip_bytes (bfd_byte **iter, bfd_byte *end, bfd_size_type length)
{
  if ((bfd_size_type) (end - *iter) < length)
    {
      *iter = end;
      return false;
    }
  *iter += length;
  return true;
}

/* Move *ITER over an leb128, stopping at END.  Return true if the end
   of the leb128 was found.  */

static bool
skip_leb128 (bfd_byte **iter, bfd_byte *end)
{
  unsigned char byte;
  do
    if (!read_byte (iter, end, &byte))
      return false;
  while (byte & 0x80);
  return true;
}

/* Like skip_leb128, but treat the leb128 as an unsigned value and
   store it in *VALUE.  */

static bool
read_uleb128 (bfd_byte **iter, bfd_byte *end, bfd_vma *value)
{
  bfd_byte *start, *p;

  start = *iter;
  if (!skip_leb128 (iter, end))
    return false;

  p = *iter;
  *value = *--p;
  while (p > start)
    *value = (*value << 7) | (*--p & 0x7f);

  return true;
}

/* Like read_uleb128, but for signed values.  */

static bool
read_sleb128 (bfd_byte **iter, bfd_byte *end, bfd_signed_vma *value)
{
  bfd_byte *start, *p;

  start = *iter;
  if (!skip_leb128 (iter, end))
    return false;

  p = *iter;
  *value = ((*--p & 0x7f) ^ 0x40) - 0x40;
  while (p > start)
    *value = (*value << 7) | (*--p & 0x7f);

  return true;
}

/* Return 0 if either encoding is variable width, or not yet known to bfd.  */

static
int get_DW_EH_PE_width (int encoding, int ptr_size)
{
  /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
     was added to bfd.  */
  if ((encoding & 0x60) == 0x60)
    return 0;

  switch (encoding & 7)
    {
    case DW_EH_PE_udata2: return 2;
    case DW_EH_PE_udata4: return 4;
    case DW_EH_PE_udata8: return 8;
    case DW_EH_PE_absptr: return ptr_size;
    default:
      break;
    }

  return 0;
}

#define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)

/* Read a width sized value from memory.  */

static bfd_vma
read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed)
{
  bfd_vma value;

  switch (width)
    {
    case 2:
      if (is_signed)
	value = bfd_get_signed_16 (abfd, buf);
      else
	value = bfd_get_16 (abfd, buf);
      break;
    case 4:
      if (is_signed)
	value = bfd_get_signed_32 (abfd, buf);
      else
	value = bfd_get_32 (abfd, buf);
      break;
    case 8:
      if (is_signed)
	value = bfd_get_signed_64 (abfd, buf);
      else
	value = bfd_get_64 (abfd, buf);
      break;
    default:
      BFD_FAIL ();
      return 0;
    }

  return value;
}

/* Store a width sized value to memory.  */

static void
write_value (bfd *abfd, bfd_byte *buf, bfd_vma value, int width)
{
  switch (width)
    {
    case 2: bfd_put_16 (abfd, value, buf); break;
    case 4: bfd_put_32 (abfd, value, buf); break;
    case 8: bfd_put_64 (abfd, value, buf); break;
    default: BFD_FAIL ();
    }
}

/* Return one if C1 and C2 CIEs can be merged.  */

static int
cie_eq (const void *e1, const void *e2)
{
  const struct cie *c1 = (const struct cie *) e1;
  const struct cie *c2 = (const struct cie *) e2;

  if (c1->hash == c2->hash
      && c1->length == c2->length
      && c1->version == c2->version
      && c1->local_personality == c2->local_personality
      && strcmp (c1->augmentation, c2->augmentation) == 0
      && strcmp (c1->augmentation, "eh") != 0
      && c1->code_align == c2->code_align
      && c1->data_align == c2->data_align
      && c1->ra_column == c2->ra_column
      && c1->augmentation_size == c2->augmentation_size
      && memcmp (&c1->personality, &c2->personality,
		 sizeof (c1->personality)) == 0
      && (c1->cie_inf->u.cie.u.sec->output_section
	  == c2->cie_inf->u.cie.u.sec->output_section)
      && c1->per_encoding == c2->per_encoding
      && c1->lsda_encoding == c2->lsda_encoding
      && c1->fde_encoding == c2->fde_encoding
      && c1->initial_insn_length == c2->initial_insn_length
      && c1->initial_insn_length <= sizeof (c1->initial_instructions)
      && memcmp (c1->initial_instructions,
		 c2->initial_instructions,
		 c1->initial_insn_length) == 0)
    return 1;

  return 0;
}

static hashval_t
cie_hash (const void *e)
{
  const struct cie *c = (const struct cie *) e;
  return c->hash;
}

static hashval_t
cie_compute_hash (struct cie *c)
{
  hashval_t h = 0;
  size_t len;
  h = iterative_hash_object (c->length, h);
  h = iterative_hash_object (c->version, h);
  h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
  h = iterative_hash_object (c->code_align, h);
  h = iterative_hash_object (c->data_align, h);
  h = iterative_hash_object (c->ra_column, h);
  h = iterative_hash_object (c->augmentation_size, h);
  h = iterative_hash_object (c->personality, h);
  h = iterative_hash_object (c->cie_inf->u.cie.u.sec->output_section, h);
  h = iterative_hash_object (c->per_encoding, h);
  h = iterative_hash_object (c->lsda_encoding, h);
  h = iterative_hash_object (c->fde_encoding, h);
  h = iterative_hash_object (c->initial_insn_length, h);
  len = c->initial_insn_length;
  if (len > sizeof (c->initial_instructions))
    len = sizeof (c->initial_instructions);
  h = iterative_hash (c->initial_instructions, len, h);
  c->hash = h;
  return h;
}

/* Return the number of extra bytes that we'll be inserting into
   ENTRY's augmentation string.  */

static inline unsigned int
extra_augmentation_string_bytes (struct eh_cie_fde *entry)
{
  unsigned int size = 0;
  if (entry->cie)
    {
      if (entry->add_augmentation_size)
	size++;
      if (entry->u.cie.add_fde_encoding)
	size++;
    }
  return size;
}

/* Likewise ENTRY's augmentation data.  */

static inline unsigned int
extra_augmentation_data_bytes (struct eh_cie_fde *entry)
{
  unsigned int size = 0;
  if (entry->add_augmentation_size)
    size++;
  if (entry->cie && entry->u.cie.add_fde_encoding)
    size++;
  return size;
}

/* Return the size that ENTRY will have in the output.  */

static unsigned int
size_of_output_cie_fde (struct eh_cie_fde *entry)
{
  if (entry->removed)
    return 0;
  if (entry->size == 4)
    return 4;
  return (entry->size
	  + extra_augmentation_string_bytes (entry)
	  + extra_augmentation_data_bytes (entry));
}

/* Return the offset of the FDE or CIE after ENT.  */

static unsigned int
next_cie_fde_offset (const struct eh_cie_fde *ent,
		     const struct eh_cie_fde *last,
		     const asection *sec)
{
  while (++ent < last)
    {
      if (!ent->removed)
	return ent->new_offset;
    }
  return sec->size;
}

/* Assume that the bytes between *ITER and END are CFA instructions.
   Try to move *ITER past the first instruction and return true on
   success.  ENCODED_PTR_WIDTH gives the width of pointer entries.  */

static bool
skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
{
  bfd_byte op;
  bfd_vma length;

  if (!read_byte (iter, end, &op))
    return false;

  switch (op & 0xc0 ? op & 0xc0 : op)
    {
    case DW_CFA_nop:
    case DW_CFA_advance_loc:
    case DW_CFA_restore:
    case DW_CFA_remember_state:
    case DW_CFA_restore_state:
    case DW_CFA_GNU_window_save:
      /* No arguments.  */
      return true;

    case DW_CFA_offset:
    case DW_CFA_restore_extended:
    case DW_CFA_undefined:
    case DW_CFA_same_value:
    case DW_CFA_def_cfa_register:
    case DW_CFA_def_cfa_offset:
    case DW_CFA_def_cfa_offset_sf:
    case DW_CFA_GNU_args_size:
      /* One leb128 argument.  */
      return skip_leb128 (iter, end);

    case DW_CFA_val_offset:
    case DW_CFA_val_offset_sf:
    case DW_CFA_offset_extended:
    case DW_CFA_register:
    case DW_CFA_def_cfa:
    case DW_CFA_offset_extended_sf:
    case DW_CFA_GNU_negative_offset_extended:
    case DW_CFA_def_cfa_sf:
      /* Two leb128 arguments.  */
      return (skip_leb128 (iter, end)
	      && skip_leb128 (iter, end));

    case DW_CFA_def_cfa_expression:
      /* A variable-length argument.  */
      return (read_uleb128 (iter, end, &length)
	      && skip_bytes (iter, end, length));

    case DW_CFA_expression:
    case DW_CFA_val_expression:
      /* A leb128 followed by a variable-length argument.  */
      return (skip_leb128 (iter, end)
	      && read_uleb128 (iter, end, &length)
	      && skip_bytes (iter, end, length));

    case DW_CFA_set_loc:
      return skip_bytes (iter, end, encoded_ptr_width);

    case DW_CFA_advance_loc1:
      return skip_bytes (iter, end, 1);

    case DW_CFA_advance_loc2:
      return skip_bytes (iter, end, 2);

    case DW_CFA_advance_loc4:
      return skip_bytes (iter, end, 4);

    case DW_CFA_MIPS_advance_loc8:
      return skip_bytes (iter, end, 8);

    default:
      return false;
    }
}

/* Try to interpret the bytes between BUF and END as CFA instructions.
   If every byte makes sense, return a pointer to the first DW_CFA_nop
   padding byte, or END if there is no padding.  Return null otherwise.
   ENCODED_PTR_WIDTH is as for skip_cfa_op.  */

static bfd_byte *
skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width,
	       unsigned int *set_loc_count)
{
  bfd_byte *last;

  last = buf;
  while (buf < end)
    if (*buf == DW_CFA_nop)
      buf++;
    else
      {
	if (*buf == DW_CFA_set_loc)
	  ++*set_loc_count;
	if (!skip_cfa_op (&buf, end, encoded_ptr_width))
	  return 0;
	last = buf;
      }
  return last;
}

/* Convert absolute encoding ENCODING into PC-relative form.
   SIZE is the size of a pointer.  */

static unsigned char
make_pc_relative (unsigned char encoding, unsigned int ptr_size)
{
  if ((encoding & 0x7f) == DW_EH_PE_absptr)
    switch (ptr_size)
      {
      case 2:
	encoding |= DW_EH_PE_sdata2;
	break;
      case 4:
	encoding |= DW_EH_PE_sdata4;
	break;
      case 8:
	encoding |= DW_EH_PE_sdata8;
	break;
      }
  return encoding | DW_EH_PE_pcrel;
}

/*  Examine each .eh_frame_entry section and discard those
    those that are marked SEC_EXCLUDE.  */

static void
bfd_elf_discard_eh_frame_entry (struct eh_frame_hdr_info *hdr_info)
{
  unsigned int i;
  for (i = 0; i < hdr_info->array_count; i++)
    {
      if (hdr_info->u.compact.entries[i]->flags & SEC_EXCLUDE)
	{
	  unsigned int j;
	  for (j = i + 1; j < hdr_info->array_count; j++)
	    hdr_info->u.compact.entries[j-1] = hdr_info->u.compact.entries[j];

	  hdr_info->array_count--;
	  hdr_info->u.compact.entries[hdr_info->array_count] = NULL;
	  i--;
	}
    }
}

/* Add a .eh_frame_entry section.  */

static void
bfd_elf_record_eh_frame_entry (struct eh_frame_hdr_info *hdr_info,
				 asection *sec)
{
  if (hdr_info->array_count == hdr_info->u.compact.allocated_entries)
    {
      if (hdr_info->u.compact.allocated_entries == 0)
	{
	  hdr_info->frame_hdr_is_compact = true;
	  hdr_info->u.compact.allocated_entries = 2;
	  hdr_info->u.compact.entries =
	    bfd_malloc (hdr_info->u.compact.allocated_entries
			* sizeof (hdr_info->u.compact.entries[0]));
	}
      else
	{
	  hdr_info->u.compact.allocated_entries *= 2;
	  hdr_info->u.compact.entries =
	    bfd_realloc (hdr_info->u.compact.entries,
			 hdr_info->u.compact.allocated_entries
			   * sizeof (hdr_info->u.compact.entries[0]));
	}

      BFD_ASSERT (hdr_info->u.compact.entries);
    }

  hdr_info->u.compact.entries[hdr_info->array_count++] = sec;
}

/* Parse a .eh_frame_entry section.  Figure out which text section it
   references.  */

bool
_bfd_elf_parse_eh_frame_entry (struct bfd_link_info *info,
			       asection *sec, struct elf_reloc_cookie *cookie)
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  unsigned long r_symndx;
  asection *text_sec;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;

  if (sec->size == 0
      || sec->sec_info_type != SEC_INFO_TYPE_NONE)
    {
      return true;
    }

  if (sec->output_section && bfd_is_abs_section (sec->output_section))
    {
      /* At least one of the sections is being discarded from the
	 link, so we should just ignore them.  */
      return true;
    }

  if (cookie->rel == cookie->relend)
    return false;

  /* The first relocation is the function start.  */
  r_symndx = cookie->rel->r_info >> cookie->r_sym_shift;
  if (r_symndx == STN_UNDEF)
    return false;

  text_sec = _bfd_elf_section_for_symbol (cookie, r_symndx, false);

  if (text_sec == NULL)
    return false;

  elf_section_eh_frame_entry (text_sec) = sec;
  if (text_sec->output_section
      && bfd_is_abs_section (text_sec->output_section))
    sec->flags |= SEC_EXCLUDE;

  sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME_ENTRY;
  elf_section_data (sec)->sec_info = text_sec;
  bfd_elf_record_eh_frame_entry (hdr_info, sec);
  return true;
}

/* Try to parse .eh_frame section SEC, which belongs to ABFD.  Store the
   information in the section's sec_info field on success.  COOKIE
   describes the relocations in SEC.  */

void
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
			 asection *sec, struct elf_reloc_cookie *cookie)
{
#define REQUIRE(COND)					\
  do							\
    if (!(COND))					\
      goto free_no_table;				\
  while (0)

  bfd_byte *ehbuf = NULL, *buf, *end;
  bfd_byte *last_fde;
  struct eh_cie_fde *this_inf;
  unsigned int hdr_length, hdr_id;
  unsigned int cie_count;
  struct cie *cie, *local_cies = NULL;
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  struct eh_frame_sec_info *sec_info = NULL;
  unsigned int ptr_size;
  unsigned int num_cies;
  unsigned int num_entries;
  elf_gc_mark_hook_fn gc_mark_hook;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;

  if (sec->size == 0
      || (sec->flags & SEC_HAS_CONTENTS) == 0
      || sec->sec_info_type != SEC_INFO_TYPE_NONE)
    {
      /* This file does not contain .eh_frame information.  */
      return;
    }

  if (bfd_is_abs_section (sec->output_section))
    {
      /* At least one of the sections is being discarded from the
	 link, so we should just ignore them.  */
      return;
    }

  /* Read the frame unwind information from abfd.  */

  REQUIRE (_bfd_elf_mmap_section_contents (abfd, sec, &ehbuf));

  /* If .eh_frame section size doesn't fit into int, we cannot handle
     it (it would need to use 64-bit .eh_frame format anyway).  */
  REQUIRE (sec->size == (unsigned int) sec->size);

  ptr_size = (get_elf_backend_data (abfd)
	      ->elf_backend_eh_frame_address_size (abfd, sec));
  REQUIRE (ptr_size != 0);

  /* Go through the section contents and work out how many FDEs and
     CIEs there are.  */
  buf = ehbuf;
  end = ehbuf + sec->size;
  num_cies = 0;
  num_entries = 0;
  while (buf != end)
    {
      num_entries++;

      /* Read the length of the entry.  */
      REQUIRE (skip_bytes (&buf, end, 4));
      hdr_length = bfd_get_32 (abfd, buf - 4);

      /* 64-bit .eh_frame is not supported.  */
      REQUIRE (hdr_length != 0xffffffff);
      if (hdr_length == 0)
	break;

      REQUIRE (skip_bytes (&buf, end, 4));
      hdr_id = bfd_get_32 (abfd, buf - 4);
      if (hdr_id == 0)
	num_cies++;

      REQUIRE (skip_bytes (&buf, end, hdr_length - 4));
    }

  sec_info = (struct eh_frame_sec_info *)
      bfd_zmalloc (sizeof (struct eh_frame_sec_info)
		   + (num_entries - 1) * sizeof (struct eh_cie_fde));
  REQUIRE (sec_info);

  /* We need to have a "struct cie" for each CIE in this section.  */
  if (num_cies)
    {
      local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
      REQUIRE (local_cies);
    }

  /* FIXME: octets_per_byte.  */
#define ENSURE_NO_RELOCS(buf)				\
  while (cookie->rel < cookie->relend			\
	 && (cookie->rel->r_offset			\
	     < (bfd_size_type) ((buf) - ehbuf)))	\
    {							\
      REQUIRE (cookie->rel->r_info == 0);		\
      cookie->rel++;					\
    }

  /* FIXME: octets_per_byte.  */
#define SKIP_RELOCS(buf)				\
  while (cookie->rel < cookie->relend			\
	 && (cookie->rel->r_offset			\
	     < (bfd_size_type) ((buf) - ehbuf)))	\
    cookie->rel++

  /* FIXME: octets_per_byte.  */
#define GET_RELOC(buf)					\
  ((cookie->rel < cookie->relend			\
    && (cookie->rel->r_offset				\
	== (bfd_size_type) ((buf) - ehbuf)))		\
   ? cookie->rel : NULL)

  buf = ehbuf;
  cie_count = 0;
  gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
  while ((bfd_size_type) (buf - ehbuf) != sec->size)
    {
      char *aug;
      bfd_byte *start, *insns, *insns_end;
      bfd_size_type length;
      unsigned int set_loc_count;

      this_inf = sec_info->entry + sec_info->count;
      last_fde = buf;

      /* Read the length of the entry.  */
      REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4));
      hdr_length = bfd_get_32 (abfd, buf - 4);

      /* The CIE/FDE must be fully contained in this input section.  */
      REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size);
      end = buf + hdr_length;

      this_inf->offset = last_fde - ehbuf;
      this_inf->size = 4 + hdr_length;
      this_inf->reloc_index = cookie->rel - cookie->rels;

      if (hdr_length == 0)
	{
	  /* A zero-length CIE should only be found at the end of
	     the section, but allow multiple terminators.  */
	  while (skip_bytes (&buf, ehbuf + sec->size, 4))
	    REQUIRE (bfd_get_32 (abfd, buf - 4) == 0);
	  REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
	  ENSURE_NO_RELOCS (buf);
	  sec_info->count++;
	  break;
	}

      REQUIRE (skip_bytes (&buf, end, 4));
      hdr_id = bfd_get_32 (abfd, buf - 4);

      if (hdr_id == 0)
	{
	  unsigned int initial_insn_length;

	  /* CIE  */
	  this_inf->cie = 1;

	  /* Point CIE to one of the section-local cie structures.  */
	  cie = local_cies + cie_count++;

	  cie->cie_inf = this_inf;
	  cie->length = hdr_length;
	  start = buf;
	  REQUIRE (read_byte (&buf, end, &cie->version));

	  /* Cannot handle unknown versions.  */
	  REQUIRE (cie->version == 1
		   || cie->version == 3
		   || cie->version == 4);
	  REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));

	  strcpy (cie->augmentation, (char *) buf);
	  buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
	  this_inf->u.cie.aug_str_len = buf - start - 1;
	  ENSURE_NO_RELOCS (buf);
	  if (buf[0] == 'e' && buf[1] == 'h')
	    {
	      /* GCC < 3.0 .eh_frame CIE */
	      /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
		 is private to each CIE, so we don't need it for anything.
		 Just skip it.  */
	      REQUIRE (skip_bytes (&buf, end, ptr_size));
	      SKIP_RELOCS (buf);
	    }
	  if (cie->version >= 4)
	    {
	      REQUIRE (buf + 1 < end);
	      REQUIRE (buf[0] == ptr_size);
	      REQUIRE (buf[1] == 0);
	      buf += 2;
	    }
	  REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
	  REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
	  if (cie->version == 1)
	    {
	      REQUIRE (buf < end);
	      cie->ra_column = *buf++;
	    }
	  else
	    REQUIRE (read_uleb128 (&buf, end, &cie->ra_column));
	  ENSURE_NO_RELOCS (buf);
	  cie->lsda_encoding = DW_EH_PE_omit;
	  cie->fde_encoding = DW_EH_PE_omit;
	  cie->per_encoding = DW_EH_PE_omit;
	  aug = cie->augmentation;
	  if (aug[0] != 'e' || aug[1] != 'h')
	    {
	      if (*aug == 'z')
		{
		  aug++;
		  REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size));
		  ENSURE_NO_RELOCS (buf);
		}

	      while (*aug != '\0')
		switch (*aug++)
		  {
		  case 'B':
		    break;
		  case 'L':
		    REQUIRE (read_byte (&buf, end, &cie->lsda_encoding));
		    ENSURE_NO_RELOCS (buf);
		    REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size));
		    break;
		  case 'R':
		    REQUIRE (read_byte (&buf, end, &cie->fde_encoding));
		    ENSURE_NO_RELOCS (buf);
		    REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size));
		    break;
		  case 'S':
		    break;
		  case 'P':
		    {
		      int per_width;

		      REQUIRE (read_byte (&buf, end, &cie->per_encoding));
		      per_width = get_DW_EH_PE_width (cie->per_encoding,
						      ptr_size);
		      REQUIRE (per_width);
		      if ((cie->per_encoding & 0x70) == DW_EH_PE_aligned)
			{
			  length = -(buf - ehbuf) & (per_width - 1);
			  REQUIRE (skip_bytes (&buf, end, length));
			  if (per_width == 8)
			    this_inf->u.cie.per_encoding_aligned8 = 1;
			}
		      this_inf->u.cie.personality_offset = buf - start;
		      ENSURE_NO_RELOCS (buf);
		      /* Ensure we have a reloc here.  */
		      REQUIRE (GET_RELOC (buf));
		      cie->personality.reloc_index
			= cookie->rel - cookie->rels;
		      /* Cope with MIPS-style composite relocations.  */
		      do
			cookie->rel++;
		      while (GET_RELOC (buf) != NULL);
		      REQUIRE (skip_bytes (&buf, end, per_width));
		    }
		    break;
		  default:
		    /* Unrecognized augmentation. Better bail out.  */
		    goto free_no_table;
		  }
	    }
	  this_inf->u.cie.aug_data_len
	    = buf - start - 1 - this_inf->u.cie.aug_str_len;

	  /* For shared libraries, try to get rid of as many RELATIVE relocs
	     as possible.  */
	  if (bfd_link_pic (info)
	      && (get_elf_backend_data (abfd)
		  ->elf_backend_can_make_relative_eh_frame
		  (abfd, info, sec)))
	    {
	      if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr)
		this_inf->make_relative = 1;
	      /* If the CIE doesn't already have an 'R' entry, it's fairly
		 easy to add one, provided that there's no aligned data
		 after the augmentation string.  */
	      else if (cie->fde_encoding == DW_EH_PE_omit
		       && (cie->per_encoding & 0x70) != DW_EH_PE_aligned)
		{
		  if (*cie->augmentation == 0)
		    this_inf->add_augmentation_size = 1;
		  this_inf->u.cie.add_fde_encoding = 1;
		  this_inf->make_relative = 1;
		}

	      if ((cie->lsda_encoding & 0x70) == DW_EH_PE_absptr)
		cie->can_make_lsda_relative = 1;
	    }

	  /* If FDE encoding was not specified, it defaults to
	     DW_EH_absptr.  */
	  if (cie->fde_encoding == DW_EH_PE_omit)
	    cie->fde_encoding = DW_EH_PE_absptr;

	  initial_insn_length = end - buf;
	  cie->initial_insn_length = initial_insn_length;
	  memcpy (cie->initial_instructions, buf,
		  initial_insn_length <= sizeof (cie->initial_instructions)
		  ? initial_insn_length : sizeof (cie->initial_instructions));
	  insns = buf;
	  buf += initial_insn_length;
	  ENSURE_NO_RELOCS (buf);

	  if (!bfd_link_relocatable (info))
	    {
	      /* Keep info for merging cies.  */
	      this_inf->u.cie.u.full_cie = cie;
	      this_inf->u.cie.per_encoding_relative
		= (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
	    }
	}
      else
	{
	  /* Find the corresponding CIE.  */
	  unsigned int cie_offset = this_inf->offset + 4 - hdr_id;
	  for (cie = local_cies; cie < local_cies + cie_count; cie++)
	    if (cie_offset == cie->cie_inf->offset)
	      break;

	  /* Ensure this FDE references one of the CIEs in this input
	     section.  */
	  REQUIRE (cie != local_cies + cie_count);
	  this_inf->u.fde.cie_inf = cie->cie_inf;
	  this_inf->make_relative = cie->cie_inf->make_relative;
	  this_inf->add_augmentation_size
	    = cie->cie_inf->add_augmentation_size;

	  ENSURE_NO_RELOCS (buf);
	  if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
	    {
	      asection *rsec;

	      REQUIRE (GET_RELOC (buf));

	      /* Chain together the FDEs for each section.  */
	      rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook,
					    cookie, NULL);
	      /* RSEC will be NULL if FDE was cleared out as it was belonging to
		 a discarded SHT_GROUP.  */
	      if (rsec)
		{
		  REQUIRE (rsec->owner == abfd);
		  this_inf->u.fde.next_for_section = elf_fde_list (rsec);
		  elf_fde_list (rsec) = this_inf;
		}
	    }

	  /* Skip the initial location and address range.  */
	  start = buf;
	  length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
	  REQUIRE (skip_bytes (&buf, end, 2 * length));

	  SKIP_RELOCS (buf - length);
	  if (!GET_RELOC (buf - length)
	      && read_value (abfd, buf - length, length, false) == 0)
	    {
	      (*info->callbacks->minfo)
		/* xgettext:c-format */
		(_("discarding zero address range FDE in %pB(%pA).\n"),
		 abfd, sec);
	      this_inf->u.fde.cie_inf = NULL;
	    }

	  /* Skip the augmentation size, if present.  */
	  if (cie->augmentation[0] == 'z')
	    REQUIRE (read_uleb128 (&buf, end, &length));
	  else
	    length = 0;

	  /* Of the supported augmentation characters above, only 'L'
	     adds augmentation data to the FDE.  This code would need to
	     be adjusted if any future augmentations do the same thing.  */
	  if (cie->lsda_encoding != DW_EH_PE_omit)
	    {
	      SKIP_RELOCS (buf);
	      if (cie->can_make_lsda_relative && GET_RELOC (buf))
		cie->cie_inf->u.cie.make_lsda_relative = 1;
	      this_inf->lsda_offset = buf - start;
	      /* If there's no 'z' augmentation, we don't know where the
		 CFA insns begin.  Assume no padding.  */
	      if (cie->augmentation[0] != 'z')
		length = end - buf;
	    }

	  /* Skip over the augmentation data.  */
	  REQUIRE (skip_bytes (&buf, end, length));
	  insns = buf;

	  buf = last_fde + 4 + hdr_length;

	  /* For NULL RSEC (cleared FDE belonging to a discarded section)
	     the relocations are commonly cleared.  We do not sanity check if
	     all these relocations are cleared as (1) relocations to
	     .gcc_except_table will remain uncleared (they will get dropped
	     with the drop of this unused FDE) and (2) BFD already safely drops
	     relocations of any type to .eh_frame by
	     elf_section_ignore_discarded_relocs.
	     TODO: The .gcc_except_table entries should be also filtered as
	     .eh_frame entries; or GCC could rather use COMDAT for them.  */
	  SKIP_RELOCS (buf);
	}

      /* Try to interpret the CFA instructions and find the first
	 padding nop.  Shrink this_inf's size so that it doesn't
	 include the padding.  */
      length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
      set_loc_count = 0;
      insns_end = skip_non_nops (insns, end, length, &set_loc_count);
      /* If we don't understand the CFA instructions, we can't know
	 what needs to be adjusted there.  */
      if (insns_end == NULL
	  /* For the time being we don't support DW_CFA_set_loc in
	     CIE instructions.  */
	  || (set_loc_count && this_inf->cie))
	goto free_no_table;
      this_inf->size -= end - insns_end;
      if (insns_end != end && this_inf->cie)
	{
	  cie->initial_insn_length -= end - insns_end;
	  cie->length -= end - insns_end;
	}
      if (set_loc_count
	  && ((cie->fde_encoding & 0x70) == DW_EH_PE_pcrel
	      || this_inf->make_relative))
	{
	  unsigned int cnt;
	  bfd_byte *p;

	  this_inf->set_loc = (unsigned int *)
	      bfd_malloc ((set_loc_count + 1) * sizeof (unsigned int));
	  REQUIRE (this_inf->set_loc);
	  this_inf->set_loc[0] = set_loc_count;
	  p = insns;
	  cnt = 0;
	  while (p < end)
	    {
	      if (*p == DW_CFA_set_loc)
		this_inf->set_loc[++cnt] = p + 1 - start;
	      REQUIRE (skip_cfa_op (&p, end, length));
	    }
	}

      this_inf->removed = 1;
      this_inf->fde_encoding = cie->fde_encoding;
      this_inf->lsda_encoding = cie->lsda_encoding;
      sec_info->count++;
    }
  BFD_ASSERT (sec_info->count == num_entries);
  BFD_ASSERT (cie_count == num_cies);

  elf_section_data (sec)->sec_info = sec_info;
  sec->sec_info_type = SEC_INFO_TYPE_EH_FRAME;
  if (!bfd_link_relocatable (info))
    {
      /* Keep info for merging cies.  */
      sec_info->cies = local_cies;
      local_cies = NULL;
    }
  goto success;

 free_no_table:
  _bfd_error_handler
    /* xgettext:c-format */
    (_("error in %pB(%pA); no .eh_frame_hdr table will be created"),
     abfd, sec);
  hdr_info->u.dwarf.table = false;
  free (sec_info);
 success:
  _bfd_elf_munmap_section_contents (sec, ehbuf);
  free (local_cies);
#undef REQUIRE
}

/* Order eh_frame_hdr entries by the VMA of their text section.  */

static int
cmp_eh_frame_hdr (const void *a, const void *b)
{
  bfd_vma text_a;
  bfd_vma text_b;
  asection *sec;

  sec = *(asection *const *)a;
  sec = (asection *) elf_section_data (sec)->sec_info;
  text_a = sec->output_section->vma + sec->output_offset;
  sec = *(asection *const *)b;
  sec = (asection *) elf_section_data (sec)->sec_info;
  text_b = sec->output_section->vma + sec->output_offset;

  if (text_a < text_b)
    return -1;
  return text_a > text_b;

}

/* Add space for a CANTUNWIND terminator to SEC if the text sections
   referenced by it and NEXT are not contiguous, or NEXT is NULL.  */

static void
add_eh_frame_hdr_terminator (asection *sec,
			     asection *next)
{
  bfd_vma end;
  bfd_vma next_start;
  asection *text_sec;

  if (next)
    {
      /* See if there is a gap (presumably a text section without unwind info)
	 between these two entries.  */
      text_sec = (asection *) elf_section_data (sec)->sec_info;
      end = text_sec->output_section->vma + text_sec->output_offset
	    + text_sec->size;
      text_sec = (asection *) elf_section_data (next)->sec_info;
      next_start = text_sec->output_section->vma + text_sec->output_offset;
      if (end == next_start)
	return;
    }

  /* Add space for a CANTUNWIND terminator.  */
  if (!sec->rawsize)
    sec->rawsize = sec->size;

  bfd_set_section_size (sec, sec->size + 8);
}

/* Finish a pass over all .eh_frame_entry sections.  */

bool
_bfd_elf_end_eh_frame_parsing (struct bfd_link_info *info)
{
  struct eh_frame_hdr_info *hdr_info;
  unsigned int i;

  hdr_info = &elf_hash_table (info)->eh_info;

  if (info->eh_frame_hdr_type != COMPACT_EH_HDR
      || hdr_info->array_count == 0)
    return false;

  bfd_elf_discard_eh_frame_entry (hdr_info);

  qsort (hdr_info->u.compact.entries, hdr_info->array_count,
	 sizeof (asection *), cmp_eh_frame_hdr);

  for (i = 0; i < hdr_info->array_count - 1; i++)
    {
      add_eh_frame_hdr_terminator (hdr_info->u.compact.entries[i],
				   hdr_info->u.compact.entries[i + 1]);
    }

  /* Add a CANTUNWIND terminator after the last entry.  */
  add_eh_frame_hdr_terminator (hdr_info->u.compact.entries[i], NULL);
  return true;
}

/* Mark all relocations against CIE or FDE ENT, which occurs in
   .eh_frame section SEC.  COOKIE describes the relocations in SEC;
   its "rel" field can be changed freely.  */

static bool
mark_entry (struct bfd_link_info *info, asection *sec,
	    struct eh_cie_fde *ent, elf_gc_mark_hook_fn gc_mark_hook,
	    struct elf_reloc_cookie *cookie)
{
  /* FIXME: octets_per_byte.  */
  for (cookie->rel = cookie->rels + ent->reloc_index;
       cookie->rel < cookie->relend
	 && cookie->rel->r_offset < ent->offset + ent->size;
       cookie->rel++)
    if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie))
      return false;

  return true;
}

/* Mark all the relocations against FDEs that relate to code in input
   section SEC.  The FDEs belong to .eh_frame section EH_FRAME, whose
   relocations are described by COOKIE.  */

bool
_bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
		       asection *eh_frame, elf_gc_mark_hook_fn gc_mark_hook,
		       struct elf_reloc_cookie *cookie)
{
  struct eh_cie_fde *fde, *cie;

  for (fde = elf_fde_list (sec); fde; fde = fde->u.fde.next_for_section)
    {
      if (!mark_entry (info, eh_frame, fde, gc_mark_hook, cookie))
	return false;

      /* At this stage, all cie_inf fields point to local CIEs, so we
	 can use the same cookie to refer to them.  */
      cie = fde->u.fde.cie_inf;
      if (cie != NULL && !cie->u.cie.gc_mark)
	{
	  cie->u.cie.gc_mark = 1;
	  if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie))
	    return false;
	}
    }
  return true;
}

/* Input section SEC of ABFD is an .eh_frame section that contains the
   CIE described by CIE_INF.  Return a version of CIE_INF that is going
   to be kept in the output, adding CIE_INF to the output if necessary.

   HDR_INFO is the .eh_frame_hdr information and COOKIE describes the
   relocations in REL.  */

static struct eh_cie_fde *
find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
		 struct eh_frame_hdr_info *hdr_info,
		 struct elf_reloc_cookie *cookie,
		 struct eh_cie_fde *cie_inf)
{
  unsigned long r_symndx;
  struct cie *cie, *new_cie;
  Elf_Internal_Rela *rel;
  void **loc;

  /* Use CIE_INF if we have already decided to keep it.  */
  if (!cie_inf->removed)
    return cie_inf;

  /* If we have merged CIE_INF with another CIE, use that CIE instead.  */
  if (cie_inf->u.cie.merged)
    return cie_inf->u.cie.u.merged_with;

  cie = cie_inf->u.cie.u.full_cie;

  /* Assume we will need to keep CIE_INF.  */
  cie_inf->removed = 0;
  cie_inf->u.cie.u.sec = sec;

  /* If we are not merging CIEs, use CIE_INF.  */
  if (cie == NULL)
    return cie_inf;

  if (cie->per_encoding != DW_EH_PE_omit)
    {
      bool per_binds_local;

      /* Work out the address of personality routine, or at least
	 enough info that we could calculate the address had we made a
	 final section layout.  The symbol on the reloc is enough,
	 either the hash for a global, or (bfd id, index) pair for a
	 local.  The assumption here is that no one uses addends on
	 the reloc.  */
      rel = cookie->rels + cie->personality.reloc_index;
      memset (&cie->personality, 0, sizeof (cie->personality));
#ifdef BFD64
      if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
	r_symndx = ELF64_R_SYM (rel->r_info);
      else
#endif
	r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx >= cookie->locsymcount
	  || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
	{
	  struct elf_link_hash_entry *h;

	  r_symndx -= cookie->extsymoff;
	  h = cookie->sym_hashes[r_symndx];

	  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;

	  cie->personality.h = h;
	  per_binds_local = SYMBOL_REFERENCES_LOCAL (info, h);
	}
      else
	{
	  Elf_Internal_Sym *sym;
	  asection *sym_sec;

	  sym = &cookie->locsyms[r_symndx];
	  sym_sec = bfd_section_from_elf_index (abfd, sym->st_shndx);
	  if (sym_sec == NULL)
	    return cie_inf;

	  if (sym_sec->kept_section != NULL)
	    sym_sec = sym_sec->kept_section;
	  if (sym_sec->output_section == NULL)
	    return cie_inf;

	  cie->local_personality = 1;
	  cie->personality.sym.bfd_id = abfd->id;
	  cie->personality.sym.index = r_symndx;
	  per_binds_local = true;
	}

      if (per_binds_local
	  && bfd_link_pic (info)
	  && (cie->per_encoding & 0x70) == DW_EH_PE_absptr
	  && (get_elf_backend_data (abfd)
	      ->elf_backend_can_make_relative_eh_frame (abfd, info, sec)))
	{
	  cie_inf->u.cie.make_per_encoding_relative = 1;
	  cie_inf->u.cie.per_encoding_relative = 1;
	}
    }

  /* See if we can merge this CIE with an earlier one.  */
  cie_compute_hash (cie);
  if (hdr_info->u.dwarf.cies == NULL)
    {
      hdr_info->u.dwarf.cies = htab_try_create (1, cie_hash, cie_eq, free);
      if (hdr_info->u.dwarf.cies == NULL)
	return cie_inf;
    }
  loc = htab_find_slot_with_hash (hdr_info->u.dwarf.cies, cie,
				  cie->hash, INSERT);
  if (loc == NULL)
    return cie_inf;

  new_cie = (struct cie *) *loc;
  if (new_cie == NULL)
    {
      /* Keep CIE_INF and record it in the hash table.  */
      new_cie = (struct cie *) malloc (sizeof (struct cie));
      if (new_cie == NULL)
	return cie_inf;

      memcpy (new_cie, cie, sizeof (struct cie));
      *loc = new_cie;
    }
  else
    {
      /* Merge CIE_INF with NEW_CIE->CIE_INF.  */
      cie_inf->removed = 1;
      cie_inf->u.cie.merged = 1;
      cie_inf->u.cie.u.merged_with = new_cie->cie_inf;
      if (cie_inf->u.cie.make_lsda_relative)
	new_cie->cie_inf->u.cie.make_lsda_relative = 1;
    }
  return new_cie->cie_inf;
}

/* For a given OFFSET in SEC, return the delta to the new location
   after .eh_frame editing.  */

static bfd_signed_vma
offset_adjust (bfd_vma offset, const asection *sec)
{
  struct eh_frame_sec_info *sec_info
    = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
  unsigned int lo, hi, mid;
  struct eh_cie_fde *ent = NULL;
  bfd_signed_vma delta;

  lo = 0;
  hi = sec_info->count;
  if (hi == 0)
    return 0;

  while (lo < hi)
    {
      mid = (lo + hi) / 2;
      ent = &sec_info->entry[mid];
      if (offset < ent->offset)
	hi = mid;
      else if (mid + 1 >= hi)
	break;
      else if (offset >= ent[1].offset)
	lo = mid + 1;
      else
	break;
    }

  if (!ent->removed)
    delta = (bfd_vma) ent->new_offset - (bfd_vma) ent->offset;
  else if (ent->cie && ent->u.cie.merged)
    {
      struct eh_cie_fde *cie = ent->u.cie.u.merged_with;
      delta = ((bfd_vma) cie->new_offset + cie->u.cie.u.sec->output_offset
	       - (bfd_vma) ent->offset - sec->output_offset);
    }
  else
    {
      /* Is putting the symbol on the next entry best for a deleted
	 CIE/FDE?  */
      struct eh_cie_fde *last = sec_info->entry + sec_info->count;
      delta = ((bfd_vma) next_cie_fde_offset (ent, last, sec)
	       - (bfd_vma) ent->offset);
      return delta;
    }

  /* Account for editing within this CIE/FDE.  */
  offset -= ent->offset;
  if (ent->cie)
    {
      unsigned int extra
	= ent->add_augmentation_size + ent->u.cie.add_fde_encoding;
      if (extra == 0
	  || offset <= 9u + ent->u.cie.aug_str_len)
	return delta;
      delta += extra;
      if (offset <= 9u + ent->u.cie.aug_str_len + ent->u.cie.aug_data_len)
	return delta;
      delta += extra;
    }
  else
    {
      unsigned int ptr_size, width, extra = ent->add_augmentation_size;
      if (offset <= 12 || extra == 0)
	return delta;
      ptr_size = (get_elf_backend_data (sec->owner)
		  ->elf_backend_eh_frame_address_size (sec->owner, sec));
      width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
      if (offset <= 8 + 2 * width)
	return delta;
      delta += extra;
    }

  return delta;
}

/* Adjust a global symbol defined in .eh_frame, so that it stays
   relative to its original CIE/FDE.  It is assumed that a symbol
   defined at the beginning of a CIE/FDE belongs to that CIE/FDE
   rather than marking the end of the previous CIE/FDE.  This matters
   when a CIE is merged with a previous CIE, since the symbol is
   moved to the merged CIE.  */

bool
_bfd_elf_adjust_eh_frame_global_symbol (struct elf_link_hash_entry *h,
					void *arg ATTRIBUTE_UNUSED)
{
  asection *sym_sec;
  bfd_signed_vma delta;

  if (h->root.type != bfd_link_hash_defined
      && h->root.type != bfd_link_hash_defweak)
    return true;

  sym_sec = h->root.u.def.section;
  if (sym_sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME
      || elf_section_data (sym_sec)->sec_info == NULL)
    return true;

  delta = offset_adjust (h->root.u.def.value, sym_sec);
  h->root.u.def.value += delta;

  return true;
}

/* The same for all local symbols defined in .eh_frame.  Returns true
   if any symbol was changed.  */

static int
adjust_eh_frame_local_symbols (const asection *sec,
			       struct elf_reloc_cookie *cookie)
{
  int adjusted = 0;

  if (cookie->locsymcount > 1)
    {
      unsigned int shndx = elf_section_data (sec)->this_idx;
      Elf_Internal_Sym *end_sym = cookie->locsyms + cookie->locsymcount;
      Elf_Internal_Sym *sym;

      for (sym = cookie->locsyms + 1; sym < end_sym; ++sym)
	if (sym->st_info <= ELF_ST_INFO (STB_LOCAL, STT_OBJECT)
	    && sym->st_shndx == shndx)
	  {
	    bfd_signed_vma delta = offset_adjust (sym->st_value, sec);

	    if (delta != 0)
	      {
		adjusted = 1;
		sym->st_value += delta;
	      }
	  }
    }
  return adjusted;
}

/* This function is called for each input file before the .eh_frame
   section is relocated.  It discards duplicate CIEs and FDEs for discarded
   functions.  The function returns TRUE iff any entries have been
   deleted.  */

bool
_bfd_elf_discard_section_eh_frame
   (bfd *abfd, struct bfd_link_info *info, asection *sec,
    bool (*reloc_symbol_deleted_p) (bfd_vma, void *),
    struct elf_reloc_cookie *cookie)
{
  struct eh_cie_fde *ent;
  struct eh_frame_sec_info *sec_info;
  struct eh_frame_hdr_info *hdr_info;
  unsigned int ptr_size, offset, eh_alignment;
  int changed;

  if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
    return false;

  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
  if (sec_info == NULL)
    return false;

  ptr_size = (get_elf_backend_data (sec->owner)
	      ->elf_backend_eh_frame_address_size (sec->owner, sec));

  hdr_info = &elf_hash_table (info)->eh_info;
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
    if (ent->size == 4)
      /* There should only be one zero terminator, on the last input
	 file supplying .eh_frame (crtend.o).  Remove any others.  */
      ent->removed = sec->map_head.s != NULL;
    else if (!ent->cie && ent->u.fde.cie_inf != NULL)
      {
	bool keep;
	if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL)
	  {
	    unsigned int width
	      = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
	    bfd_vma value
	      = read_value (abfd, sec->contents + ent->offset + 8 + width,
			    width, get_DW_EH_PE_signed (ent->fde_encoding));
	    keep = value != 0;
	  }
	else
	  {
	    cookie->rel = cookie->rels + ent->reloc_index;
	    /* FIXME: octets_per_byte.  */
	    BFD_ASSERT (cookie->rel < cookie->relend
			&& cookie->rel->r_offset == ent->offset + 8);
	    keep = !(*reloc_symbol_deleted_p) (ent->offset + 8, cookie);
	  }
	if (keep)
	  {
	    if (bfd_link_pic (info)
		&& (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr
		     && ent->make_relative == 0)
		    || (ent->fde_encoding & 0x70) == DW_EH_PE_aligned))
	      {
		static int num_warnings_issued = 0;

		/* If a shared library uses absolute pointers
		   which we cannot turn into PC relative,
		   don't create the binary search table,
		   since it is affected by runtime relocations.  */
		hdr_info->u.dwarf.table = false;
		/* Only warn if --eh-frame-hdr was specified.  */
		if (info->eh_frame_hdr_type != 0)
		  {
		    if (num_warnings_issued < 10)
		      {
			_bfd_error_handler
			  /* xgettext:c-format */
			  (_("FDE encoding in %pB(%pA) prevents .eh_frame_hdr"
			     " table being created"), abfd, sec);
			num_warnings_issued ++;
		      }
		    else if (num_warnings_issued == 10)
		      {
			_bfd_error_handler
			  (_("further warnings about FDE encoding preventing .eh_frame_hdr generation dropped"));
			num_warnings_issued ++;
		      }
		  }
	      }
	    ent->removed = 0;
	    hdr_info->u.dwarf.fde_count++;
	    ent->u.fde.cie_inf = find_merged_cie (abfd, info, sec, hdr_info,
						  cookie, ent->u.fde.cie_inf);
	  }
      }

  free (sec_info->cies);
  sec_info->cies = NULL;

  /* It may be that some .eh_frame input section has greater alignment
     than other .eh_frame sections.  In that case we run the risk of
     padding with zeros before that section, which would be seen as a
     zero terminator.  Alignment padding must be added *inside* the
     last FDE instead.  For other FDEs we align according to their
     encoding, in order to align FDE address range entries naturally.  */
  offset = 0;
  changed = 0;
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
    if (!ent->removed)
      {
	eh_alignment = 4;
	if (ent->size == 4)
	  ;
	else if (ent->cie)
	  {
	    if (ent->u.cie.per_encoding_aligned8)
	      eh_alignment = 8;
	  }
	else
	  {
	    eh_alignment = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
	    if (eh_alignment < 4)
	      eh_alignment = 4;
	  }
	offset = (offset + eh_alignment - 1) & -eh_alignment;
	ent->new_offset = offset;
	if (ent->new_offset != ent->offset)
	  changed = 1;
	offset += size_of_output_cie_fde (ent);
      }

  eh_alignment = 4;
  offset = (offset + eh_alignment - 1) & -eh_alignment;
  sec->rawsize = sec->size;
  sec->size = offset;
  if (sec->size != sec->rawsize)
    changed = 1;

  if (changed && adjust_eh_frame_local_symbols (sec, cookie))
    {
      Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
      symtab_hdr->contents = (unsigned char *) cookie->locsyms;
    }
  return changed;
}

/* This function is called for .eh_frame_hdr section after
   _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
   input sections.  It finalizes the size of .eh_frame_hdr section.  */

bool
_bfd_elf_discard_section_eh_frame_hdr (struct bfd_link_info *info)
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  asection *sec;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;

  if (!hdr_info->frame_hdr_is_compact && hdr_info->u.dwarf.cies != NULL)
    {
      htab_delete (hdr_info->u.dwarf.cies);
      hdr_info->u.dwarf.cies = NULL;
    }

  sec = hdr_info->hdr_sec;
  if (sec == NULL)
    return false;

  if (info->eh_frame_hdr_type == COMPACT_EH_HDR)
    {
      /* For compact frames we only add the header.  The actual table comes
	 from the .eh_frame_entry sections.  */
      sec->size = 8;
    }
  else
    {
      sec->size = EH_FRAME_HDR_SIZE;
      if (hdr_info->u.dwarf.table)
	sec->size += 4 + hdr_info->u.dwarf.fde_count * 8;
    }

  return true;
}

/* Return true if there is at least one non-empty .eh_frame section in
   input files.  Can only be called after ld has mapped input to
   output sections, and before sections are stripped.  */

bool
_bfd_elf_eh_frame_present (struct bfd_link_info *info)
{
  asection *eh = bfd_get_section_by_name (info->output_bfd, ".eh_frame");

  if (eh == NULL)
    return false;

  /* Count only sections which have at least a single CIE or FDE.
     There cannot be any CIE or FDE <= 8 bytes.  */
  for (eh = eh->map_head.s; eh != NULL; eh = eh->map_head.s)
    if (eh->size > 8)
      return true;

  return false;
}

/* Return true if there is at least one .eh_frame_entry section in
   input files.  */

bool
_bfd_elf_eh_frame_entry_present (struct bfd_link_info *info)
{
  asection *o;
  bfd *abfd;

  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
    {
      for (o = abfd->sections; o; o = o->next)
	{
	  const char *name = bfd_section_name (o);

	  if (strcmp (name, ".eh_frame_entry")
	      && !bfd_is_abs_section (o->output_section))
	    return true;
	}
    }
  return false;
}

/* This function is called from size_dynamic_sections.
   It needs to decide whether .eh_frame_hdr should be output or not,
   because when the dynamic symbol table has been sized it is too late
   to strip sections.  */

bool
_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  struct bfd_link_hash_entry *bh = NULL;
  struct elf_link_hash_entry *h;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;
  if (hdr_info->hdr_sec == NULL)
    return true;

  if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)
      || info->eh_frame_hdr_type == 0
      || (info->eh_frame_hdr_type == DWARF2_EH_HDR
	  && !_bfd_elf_eh_frame_present (info))
      || (info->eh_frame_hdr_type == COMPACT_EH_HDR
	  && !_bfd_elf_eh_frame_entry_present (info)))
    {
      hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
      hdr_info->hdr_sec = NULL;
      return true;
    }

  /* Add a hidden symbol so that systems without access to PHDRs can
     find the table.  */
  if (! (_bfd_generic_link_add_one_symbol
	 (info, info->output_bfd, "__GNU_EH_FRAME_HDR", BSF_LOCAL,
	  hdr_info->hdr_sec, 0, NULL, false, false, &bh)))
    return false;

  h = (struct elf_link_hash_entry *) bh;
  h->def_regular = 1;
  h->other = STV_HIDDEN;
  get_elf_backend_data
    (info->output_bfd)->elf_backend_hide_symbol (info, h, true);

  if (!hdr_info->frame_hdr_is_compact)
    hdr_info->u.dwarf.table = true;
  return true;
}

/* Adjust an address in the .eh_frame section.  Given OFFSET within
   SEC, this returns the new offset in the adjusted .eh_frame section,
   or -1 if the address refers to a CIE/FDE which has been removed
   or to offset with dynamic relocation which is no longer needed.  */

bfd_vma
_bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
				  struct bfd_link_info *info ATTRIBUTE_UNUSED,
				  asection *sec,
				  bfd_vma offset)
{
  struct eh_frame_sec_info *sec_info;
  unsigned int lo, hi, mid;

  if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
    return offset;
  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;

  if (offset >= sec->rawsize)
    return offset - sec->rawsize + sec->size;

  lo = 0;
  hi = sec_info->count;
  mid = 0;
  while (lo < hi)
    {
      mid = (lo + hi) / 2;
      if (offset < sec_info->entry[mid].offset)
	hi = mid;
      else if (offset
	       >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
	lo = mid + 1;
      else
	break;
    }

  BFD_ASSERT (lo < hi);

  /* FDE or CIE was removed.  */
  if (sec_info->entry[mid].removed)
    return (bfd_vma) -1;

  /* If converting personality pointers to DW_EH_PE_pcrel, there will be
     no need for run-time relocation against the personality field.  */
  if (sec_info->entry[mid].cie
      && sec_info->entry[mid].u.cie.make_per_encoding_relative
      && offset == (sec_info->entry[mid].offset + 8
		    + sec_info->entry[mid].u.cie.personality_offset))
    return (bfd_vma) -2;

  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
     relocation against FDE's initial_location field.  */
  if (!sec_info->entry[mid].cie
      && sec_info->entry[mid].make_relative
      && offset == sec_info->entry[mid].offset + 8)
    return (bfd_vma) -2;

  /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
     for run-time relocation against LSDA field.  */
  if (!sec_info->entry[mid].cie
      && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
      && offset == (sec_info->entry[mid].offset + 8
		    + sec_info->entry[mid].lsda_offset))
    return (bfd_vma) -2;

  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
     relocation against DW_CFA_set_loc's arguments.  */
  if (sec_info->entry[mid].set_loc
      && sec_info->entry[mid].make_relative
      && (offset >= sec_info->entry[mid].offset + 8
		    + sec_info->entry[mid].set_loc[1]))
    {
      unsigned int cnt;

      for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++)
	if (offset == sec_info->entry[mid].offset + 8
		      + sec_info->entry[mid].set_loc[cnt])
	  return (bfd_vma) -2;
    }

  /* Any new augmentation bytes go before the first relocation.  */
  return (offset + sec_info->entry[mid].new_offset
	  - sec_info->entry[mid].offset
	  + extra_augmentation_string_bytes (sec_info->entry + mid)
	  + extra_augmentation_data_bytes (sec_info->entry + mid));
}

/* Write out .eh_frame_entry section.  Add CANTUNWIND terminator if needed.
   Also check that the contents look sane.  */

bool
_bfd_elf_write_section_eh_frame_entry (bfd *abfd, struct bfd_link_info *info,
				       asection *sec, bfd_byte *contents)
{
  const struct elf_backend_data *bed;
  bfd_byte cantunwind[8];
  bfd_vma addr;
  bfd_vma last_addr;
  bfd_vma offset;
  asection *text_sec = (asection *) elf_section_data (sec)->sec_info;

  if (!sec->rawsize)
    sec->rawsize = sec->size;

  BFD_ASSERT (sec->sec_info_type == SEC_INFO_TYPE_EH_FRAME_ENTRY);

  /* Check to make sure that the text section corresponding to this eh_frame_entry
     section has not been excluded.  In particular, mips16 stub entries will be
     excluded outside of the normal process.  */
  if (sec->flags & SEC_EXCLUDE
      || text_sec->flags & SEC_EXCLUDE)
    return true;

  if (!bfd_set_section_contents (abfd, sec->output_section, contents,
				 sec->output_offset, sec->rawsize))
      return false;

  last_addr = bfd_get_signed_32 (abfd, contents);
  /* Check that all the entries are in order.  */
  for (offset = 8; offset < sec->rawsize; offset += 8)
    {
      addr = bfd_get_signed_32 (abfd, contents + offset) + offset;
      if (addr <= last_addr)
	{
	  /* xgettext:c-format */
	  _bfd_error_handler (_("%pB: %pA not in order"), sec->owner, sec);
	  return false;
	}

      last_addr = addr;
    }

  addr = text_sec->output_section->vma + text_sec->output_offset
	 + text_sec->size;
  addr &= ~1;
  addr -= (sec->output_section->vma + sec->output_offset + sec->rawsize);
  if (addr & 1)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: %pA invalid input section size"),
			  sec->owner, sec);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }
  if (last_addr >= addr + sec->rawsize)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: %pA points past end of text section"),
			  sec->owner, sec);
      bfd_set_error (bfd_error_bad_value);
      return false;
    }

  if (sec->size == sec->rawsize)
    return true;

  bed = get_elf_backend_data (abfd);
  BFD_ASSERT (sec->size == sec->rawsize + 8);
  BFD_ASSERT ((addr & 1) == 0);
  BFD_ASSERT (bed->cant_unwind_opcode);

  bfd_put_32 (abfd, addr, cantunwind);
  bfd_put_32 (abfd, (*bed->cant_unwind_opcode) (info), cantunwind + 4);
  return bfd_set_section_contents (abfd, sec->output_section, cantunwind,
				   sec->output_offset + sec->rawsize, 8);
}

/* Write out .eh_frame section.  This is called with the relocated
   contents.  */

bool
_bfd_elf_write_section_eh_frame (bfd *abfd,
				 struct bfd_link_info *info,
				 asection *sec,
				 bfd_byte *contents)
{
  struct eh_frame_sec_info *sec_info;
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  unsigned int ptr_size;
  struct eh_cie_fde *ent, *last_ent;

  if (sec->sec_info_type != SEC_INFO_TYPE_EH_FRAME)
    /* FIXME: octets_per_byte.  */
    return bfd_set_section_contents (abfd, sec->output_section, contents,
				     sec->output_offset, sec->size);

  ptr_size = (get_elf_backend_data (abfd)
	      ->elf_backend_eh_frame_address_size (abfd, sec));
  BFD_ASSERT (ptr_size != 0);

  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;

  if (hdr_info->u.dwarf.table && hdr_info->u.dwarf.array == NULL)
    {
      hdr_info->frame_hdr_is_compact = false;
      hdr_info->u.dwarf.array = (struct eh_frame_array_ent *)
	bfd_malloc (hdr_info->u.dwarf.fde_count
		    * sizeof (*hdr_info->u.dwarf.array));
    }
  if (hdr_info->u.dwarf.array == NULL)
    hdr_info = NULL;

  /* The new offsets can be bigger or smaller than the original offsets.
     We therefore need to make two passes over the section: one backward
     pass to move entries up and one forward pass to move entries down.
     The two passes won't interfere with each other because entries are
     not reordered  */
  for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
    if (!ent->removed && ent->new_offset > ent->offset)
      memmove (contents + ent->new_offset, contents + ent->offset, ent->size);

  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
    if (!ent->removed && ent->new_offset < ent->offset)
      memmove (contents + ent->new_offset, contents + ent->offset, ent->size);

  last_ent = sec_info->entry + sec_info->count;
  for (ent = sec_info->entry; ent < last_ent; ++ent)
    {
      unsigned char *buf, *end;
      unsigned int new_size;

      if (ent->removed)
	continue;

      if (ent->size == 4)
	{
	  /* Any terminating FDE must be at the end of the section.  */
	  BFD_ASSERT (ent == last_ent - 1);
	  continue;
	}

      buf = contents + ent->new_offset;
      end = buf + ent->size;
      new_size = next_cie_fde_offset (ent, last_ent, sec) - ent->new_offset;

      /* Update the size.  It may be shrinked.  */
      bfd_put_32 (abfd, new_size - 4, buf);

      /* Filling the extra bytes with DW_CFA_nops.  */
      if (new_size != ent->size)
	memset (end, 0, new_size - ent->size);

      if (ent->cie)
	{
	  /* CIE */
	  if (ent->make_relative
	      || ent->u.cie.make_lsda_relative
	      || ent->u.cie.per_encoding_relative)
	    {
	      char *aug;
	      unsigned int version, action, extra_string, extra_data;
	      unsigned int per_width, per_encoding;

	      /* Need to find 'R' or 'L' augmentation's argument and modify
		 DW_EH_PE_* value.  */
	      action = ((ent->make_relative ? 1 : 0)
			| (ent->u.cie.make_lsda_relative ? 2 : 0)
			| (ent->u.cie.per_encoding_relative ? 4 : 0));
	      extra_string = extra_augmentation_string_bytes (ent);
	      extra_data = extra_augmentation_data_bytes (ent);

	      /* Skip length, id.  */
	      buf += 8;
	      version = *buf++;
	      aug = (char *) buf;
	      buf += strlen (aug) + 1;
	      skip_leb128 (&buf, end);
	      skip_leb128 (&buf, end);
	      if (version == 1)
		skip_bytes (&buf, end, 1);
	      else
		skip_leb128 (&buf, end);
	      if (*aug == 'z')
		{
		  /* The uleb128 will always be a single byte for the kind
		     of augmentation strings that we're prepared to handle.  */
		  *buf++ += extra_data;
		  aug++;
		}

	      /* Make room for the new augmentation string and data bytes.  */
	      memmove (buf + extra_string + extra_data, buf, end - buf);
	      memmove (aug + extra_string, aug, buf - (bfd_byte *) aug);
	      buf += extra_string;
	      end += extra_string + extra_data;

	      if (ent->add_augmentation_size)
		{
		  *aug++ = 'z';
		  *buf++ = extra_data - 1;
		}
	      if (ent->u.cie.add_fde_encoding)
		{
		  BFD_ASSERT (action & 1);
		  *aug++ = 'R';
		  *buf++ = make_pc_relative (DW_EH_PE_absptr, ptr_size);
		  action &= ~1;
		}

	      while (action)
		switch (*aug++)
		  {
		  case 'L':
		    if (action & 2)
		      {
			BFD_ASSERT (*buf == ent->lsda_encoding);
			*buf = make_pc_relative (*buf, ptr_size);
			action &= ~2;
		      }
		    buf++;
		    break;
		  case 'P':
		    if (ent->u.cie.make_per_encoding_relative)
		      *buf = make_pc_relative (*buf, ptr_size);
		    per_encoding = *buf++;
		    per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
		    BFD_ASSERT (per_width != 0);
		    BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
				== ent->u.cie.per_encoding_relative);
		    if ((per_encoding & 0x70) == DW_EH_PE_aligned)
		      buf = (contents
			     + ((buf - contents + per_width - 1)
				& ~((bfd_size_type) per_width - 1)));
		    if (action & 4)
		      {
			bfd_vma val;

			val = read_value (abfd, buf, per_width,
					  get_DW_EH_PE_signed (per_encoding));
			if (ent->u.cie.make_per_encoding_relative)
			  val -= (sec->output_section->vma
				  + sec->output_offset
				  + (buf - contents));
			else
			  {
			    val += (bfd_vma) ent->offset - ent->new_offset;
			    val -= extra_string + extra_data;
			  }
			write_value (abfd, buf, val, per_width);
			action &= ~4;
		      }
		    buf += per_width;
		    break;
		  case 'R':
		    if (action & 1)
		      {
			BFD_ASSERT (*buf == ent->fde_encoding);
			*buf = make_pc_relative (*buf, ptr_size);
			action &= ~1;
		      }
		    buf++;
		    break;
		  case 'S':
		    break;
		  default:
		    BFD_FAIL ();
		  }
	    }
	}
      else
	{
	  /* FDE */
	  bfd_vma value, address;
	  unsigned int width;
	  bfd_byte *start;
	  struct eh_cie_fde *cie;

	  /* Skip length.  */
	  cie = ent->u.fde.cie_inf;
	  buf += 4;
	  value = ((ent->new_offset + sec->output_offset + 4)
		   - (cie->new_offset + cie->u.cie.u.sec->output_offset));
	  bfd_put_32 (abfd, value, buf);
	  if (bfd_link_relocatable (info))
	    continue;
	  buf += 4;
	  width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
	  value = read_value (abfd, buf, width,
			      get_DW_EH_PE_signed (ent->fde_encoding));
	  address = value;
	  if (value)
	    {
	      switch (ent->fde_encoding & 0x70)
		{
		case DW_EH_PE_textrel:
		  BFD_ASSERT (hdr_info == NULL);
		  break;
		case DW_EH_PE_datarel:
		  {
		    switch (abfd->arch_info->arch)
		      {
		      case bfd_arch_ia64:
			BFD_ASSERT (elf_gp (abfd) != 0);
			address += elf_gp (abfd);
			break;
		      default:
			_bfd_error_handler
			  (_("DW_EH_PE_datarel unspecified"
			     " for this architecture"));
			/* Fall thru */
		      case bfd_arch_frv:
		      case bfd_arch_i386:
		      case bfd_arch_nios2:
			BFD_ASSERT (htab->hgot != NULL
				    && ((htab->hgot->root.type
					 == bfd_link_hash_defined)
					|| (htab->hgot->root.type
					    == bfd_link_hash_defweak)));
			address
			  += (htab->hgot->root.u.def.value
			      + htab->hgot->root.u.def.section->output_offset
			      + (htab->hgot->root.u.def.section->output_section
				 ->vma));
			break;
		      }
		  }
		  break;
		case DW_EH_PE_pcrel:
		  value += (bfd_vma) ent->offset - ent->new_offset;
		  address += (sec->output_section->vma
			      + sec->output_offset
			      + ent->offset + 8);
		  break;
		}
	      if (ent->make_relative)
		value -= (sec->output_section->vma
			  + sec->output_offset
			  + ent->new_offset + 8);
	      write_value (abfd, buf, value, width);
	    }

	  start = buf;

	  if (hdr_info)
	    {
	      /* The address calculation may overflow, giving us a
		 value greater than 4G on a 32-bit target when
		 dwarf_vma is 64-bit.  */
	      if (sizeof (address) > 4 && ptr_size == 4)
		address &= 0xffffffff;
	      hdr_info->u.dwarf.array[hdr_info->array_count].initial_loc
		= address;
	      hdr_info->u.dwarf.array[hdr_info->array_count].range
		= read_value (abfd, buf + width, width, false);
	      hdr_info->u.dwarf.array[hdr_info->array_count++].fde
		= (sec->output_section->vma
		   + sec->output_offset
		   + ent->new_offset);
	    }

	  if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel
	      || cie->u.cie.make_lsda_relative)
	    {
	      buf += ent->lsda_offset;
	      width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
	      value = read_value (abfd, buf, width,
				  get_DW_EH_PE_signed (ent->lsda_encoding));
	      if (value)
		{
		  if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
		    value += (bfd_vma) ent->offset - ent->new_offset;
		  else if (cie->u.cie.make_lsda_relative)
		    value -= (sec->output_section->vma
			      + sec->output_offset
			      + ent->new_offset + 8 + ent->lsda_offset);
		  write_value (abfd, buf, value, width);
		}
	    }
	  else if (ent->add_augmentation_size)
	    {
	      /* Skip the PC and length and insert a zero byte for the
		 augmentation size.  */
	      buf += width * 2;
	      memmove (buf + 1, buf, end - buf);
	      *buf = 0;
	    }

	  if (ent->set_loc)
	    {
	      /* Adjust DW_CFA_set_loc.  */
	      unsigned int cnt;
	      bfd_vma new_offset;

	      width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
	      new_offset = ent->new_offset + 8
			   + extra_augmentation_string_bytes (ent)
			   + extra_augmentation_data_bytes (ent);

	      for (cnt = 1; cnt <= ent->set_loc[0]; cnt++)
		{
		  buf = start + ent->set_loc[cnt];

		  value = read_value (abfd, buf, width,
				      get_DW_EH_PE_signed (ent->fde_encoding));
		  if (!value)
		    continue;

		  if ((ent->fde_encoding & 0x70) == DW_EH_PE_pcrel)
		    value += (bfd_vma) ent->offset + 8 - new_offset;
		  if (ent->make_relative)
		    value -= (sec->output_section->vma
			      + sec->output_offset
			      + new_offset + ent->set_loc[cnt]);
		  write_value (abfd, buf, value, width);
		}
	    }
	}
    }

  /* FIXME: octets_per_byte.  */
  return bfd_set_section_contents (abfd, sec->output_section,
				   contents, (file_ptr) sec->output_offset,
				   sec->size);
}

/* Helper function used to sort .eh_frame_hdr search table by increasing
   VMA of FDE initial location.  */

static int
vma_compare (const void *a, const void *b)
{
  const struct eh_frame_array_ent *p = (const struct eh_frame_array_ent *) a;
  const struct eh_frame_array_ent *q = (const struct eh_frame_array_ent *) b;
  if (p->initial_loc > q->initial_loc)
    return 1;
  if (p->initial_loc < q->initial_loc)
    return -1;
  if (p->range > q->range)
    return 1;
  if (p->range < q->range)
    return -1;
  return 0;
}

/* Reorder .eh_frame_entry sections to match the associated text sections.
   This routine is called during the final linking step, just before writing
   the contents.  At this stage, sections in the eh_frame_hdr_info are already
   sorted in order of increasing text section address and so we simply need
   to make the .eh_frame_entrys follow that same order.  Note that it is
   invalid for a linker script to try to force a particular order of
   .eh_frame_entry sections.  */

bool
_bfd_elf_fixup_eh_frame_hdr (struct bfd_link_info *info)
{
  asection *sec = NULL;
  asection *osec;
  struct eh_frame_hdr_info *hdr_info;
  unsigned int i;
  bfd_vma offset;
  struct bfd_link_order *p;

  hdr_info = &elf_hash_table (info)->eh_info;

  if (hdr_info->hdr_sec == NULL
      || info->eh_frame_hdr_type != COMPACT_EH_HDR
      || hdr_info->array_count == 0)
    return true;

  /* Change section output offsets to be in text section order.  */
  offset = 8;
  osec = hdr_info->u.compact.entries[0]->output_section;
  for (i = 0; i < hdr_info->array_count; i++)
    {
      sec = hdr_info->u.compact.entries[i];
      if (sec->output_section != osec)
	{
	  _bfd_error_handler
	    (_("invalid output section for .eh_frame_entry: %pA"),
	     sec->output_section);
	  return false;
	}
      sec->output_offset = offset;
      offset += sec->size;
    }


  /* Fix the link_order to match.  */
  for (p = sec->output_section->map_head.link_order; p != NULL; p = p->next)
    {
      if (p->type != bfd_indirect_link_order)
	abort();

      p->offset = p->u.indirect.section->output_offset;
      if (p->next != NULL)
	i--;
    }

  if (i != 0)
    {
      _bfd_error_handler
	(_("invalid contents in %pA section"), osec);
      return false;
    }

  return true;
}

/* The .eh_frame_hdr format for Compact EH frames:
   ubyte version		(2)
   ubyte eh_ref_enc		(DW_EH_PE_* encoding of typinfo references)
   uint32_t count		(Number of entries in table)
   [array from .eh_frame_entry sections]  */

static bool
write_compact_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  asection *sec;
  const struct elf_backend_data *bed;
  bfd_vma count;
  bfd_byte contents[8];
  unsigned int i;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;
  sec = hdr_info->hdr_sec;

  if (sec->size != 8)
    abort();

  for (i = 0; i < sizeof (contents); i++)
    contents[i] = 0;

  contents[0] = COMPACT_EH_HDR;
  bed = get_elf_backend_data (abfd);

  BFD_ASSERT (bed->compact_eh_encoding);
  contents[1] = (*bed->compact_eh_encoding) (info);

  count = (sec->output_section->size - 8) / 8;
  bfd_put_32 (abfd, count, contents + 4);
  return bfd_set_section_contents (abfd, sec->output_section, contents,
				   (file_ptr) sec->output_offset, sec->size);
}

/* The .eh_frame_hdr format for DWARF frames:

   ubyte version		(currently 1)
   ubyte eh_frame_ptr_enc	(DW_EH_PE_* encoding of pointer to start of
				 .eh_frame section)
   ubyte fde_count_enc		(DW_EH_PE_* encoding of total FDE count
				 number (or DW_EH_PE_omit if there is no
				 binary search table computed))
   ubyte table_enc		(DW_EH_PE_* encoding of binary search table,
				 or DW_EH_PE_omit if not present.
				 DW_EH_PE_datarel is using address of
				 .eh_frame_hdr section start as base)
   [encoded] eh_frame_ptr	(pointer to start of .eh_frame section)
   optionally followed by:
   [encoded] fde_count		(total number of FDEs in .eh_frame section)
   fde_count x [encoded] initial_loc, fde
				(array of encoded pairs containing
				 FDE initial_location field and FDE address,
				 sorted by increasing initial_loc).  */

static bool
write_dwarf_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  asection *sec;
  bool retval = true;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;
  sec = hdr_info->hdr_sec;
  bfd_byte *contents;
  asection *eh_frame_sec;
  bfd_size_type size;
  bfd_vma encoded_eh_frame;

  size = EH_FRAME_HDR_SIZE;
  if (hdr_info->u.dwarf.array
      && hdr_info->array_count == hdr_info->u.dwarf.fde_count)
    size += 4 + hdr_info->u.dwarf.fde_count * 8;
  contents = (bfd_byte *) bfd_malloc (size);
  if (contents == NULL)
    return false;

  eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
  if (eh_frame_sec == NULL)
    {
      free (contents);
      return false;
    }

  memset (contents, 0, EH_FRAME_HDR_SIZE);
  /* Version.  */
  contents[0] = 1;
  /* .eh_frame offset.  */
  contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
    (abfd, info, eh_frame_sec, 0, sec, 4, &encoded_eh_frame);

  if (hdr_info->u.dwarf.array
      && hdr_info->array_count == hdr_info->u.dwarf.fde_count)
    {
      /* FDE count encoding.  */
      contents[2] = DW_EH_PE_udata4;
      /* Search table encoding.  */
      contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
    }
  else
    {
      contents[2] = DW_EH_PE_omit;
      contents[3] = DW_EH_PE_omit;
    }
  bfd_put_32 (abfd, encoded_eh_frame, contents + 4);

  if (contents[2] != DW_EH_PE_omit)
    {
      unsigned int i;
      bool overlap, overflow;

      bfd_put_32 (abfd, hdr_info->u.dwarf.fde_count,
		  contents + EH_FRAME_HDR_SIZE);
      qsort (hdr_info->u.dwarf.array, hdr_info->u.dwarf.fde_count,
	     sizeof (*hdr_info->u.dwarf.array), vma_compare);
      overlap = false;
      overflow = false;
      for (i = 0; i < hdr_info->u.dwarf.fde_count; i++)
	{
	  bfd_vma val;

	  val = hdr_info->u.dwarf.array[i].initial_loc
	    - sec->output_section->vma;
	  val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
	  if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64
	      && (hdr_info->u.dwarf.array[i].initial_loc
		  != sec->output_section->vma + val))
	    overflow = true;
	  bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
	  val = hdr_info->u.dwarf.array[i].fde - sec->output_section->vma;
	  val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
	  if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64
	      && (hdr_info->u.dwarf.array[i].fde
		  != sec->output_section->vma + val))
	    overflow = true;
	  bfd_put_32 (abfd, val, contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
	  if (i != 0
	      && (hdr_info->u.dwarf.array[i].initial_loc
		  < (hdr_info->u.dwarf.array[i - 1].initial_loc
		     + hdr_info->u.dwarf.array[i - 1].range)))
	    overlap = true;
	}
      if (overflow)
	_bfd_error_handler (_(".eh_frame_hdr entry overflow"));
      if (overlap)
	_bfd_error_handler (_(".eh_frame_hdr refers to overlapping FDEs"));
      if (overflow || overlap)
	{
	  bfd_set_error (bfd_error_bad_value);
	  retval = false;
	}
    }

  /* FIXME: octets_per_byte.  */
  if (!bfd_set_section_contents (abfd, sec->output_section, contents,
				 (file_ptr) sec->output_offset,
				 sec->size))
    retval = false;
  free (contents);

  free (hdr_info->u.dwarf.array);
  return retval;
}

/* Write out .eh_frame_hdr section.  This must be called after
   _bfd_elf_write_section_eh_frame has been called on all input
   .eh_frame sections.  */

bool
_bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  asection *sec;

  htab = elf_hash_table (info);
  hdr_info = &htab->eh_info;
  sec = hdr_info->hdr_sec;

  if (info->eh_frame_hdr_type == 0 || sec == NULL)
    return true;

  if (info->eh_frame_hdr_type == COMPACT_EH_HDR)
    return write_compact_eh_frame_hdr (abfd, info);
  else
    return write_dwarf_eh_frame_hdr (abfd, info);
}

/* Return the width of FDE addresses.  This is the default implementation.  */

unsigned int
_bfd_elf_eh_frame_address_size (bfd *abfd, const asection *sec ATTRIBUTE_UNUSED)
{
  return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
}

/* Decide whether we can use a PC-relative encoding within the given
   EH frame section.  This is the default implementation.  */

bool
_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
			    struct bfd_link_info *info ATTRIBUTE_UNUSED,
			    asection *eh_frame_section ATTRIBUTE_UNUSED)
{
  return true;
}

/* Select an encoding for the given address.  Preference is given to
   PC-relative addressing modes.  */

bfd_byte
_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
			    struct bfd_link_info *info ATTRIBUTE_UNUSED,
			    asection *osec, bfd_vma offset,
			    asection *loc_sec, bfd_vma loc_offset,
			    bfd_vma *encoded)
{
  *encoded = osec->vma + offset -
    (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
  return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
}
