/* .eh_frame section optimization.
   Copyright 2001, 2002, 2003 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

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

#define EH_FRAME_HDR_SIZE 8

static bfd_vma read_unsigned_leb128
  PARAMS ((bfd *, char *, unsigned int *));
static bfd_signed_vma read_signed_leb128
  PARAMS ((bfd *, char *, unsigned int *));
static int get_DW_EH_PE_width
  PARAMS ((int, int));
static bfd_vma read_value
  PARAMS ((bfd *, bfd_byte *, int, int));
static void write_value
  PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
static int cie_compare
  PARAMS ((struct cie *, struct cie *));
static int vma_compare
  PARAMS ((const PTR, const PTR));

/* Helper function for reading uleb128 encoded data.  */

static bfd_vma
read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
     bfd *abfd ATTRIBUTE_UNUSED;
     char *buf;
     unsigned int *bytes_read_ptr;
{
  bfd_vma  result;
  unsigned int  num_read;
  int           shift;
  unsigned char byte;

  result   = 0;
  shift    = 0;
  num_read = 0;
  do
    {
      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
      buf ++;
      num_read ++;
      result |= (((bfd_vma) byte & 0x7f) << shift);
      shift += 7;
    }
  while (byte & 0x80);
  * bytes_read_ptr = num_read;
  return result;
}

/* Helper function for reading sleb128 encoded data.  */

static bfd_signed_vma
read_signed_leb128 (abfd, buf, bytes_read_ptr)
     bfd *abfd ATTRIBUTE_UNUSED;
     char *buf;
     unsigned int * bytes_read_ptr;
{
  bfd_vma	result;
  int           shift;
  int           num_read;
  unsigned char byte;

  result = 0;
  shift = 0;
  num_read = 0;
  do
    {
      byte = bfd_get_8 (abfd, (bfd_byte *) buf);
      buf ++;
      num_read ++;
      result |= (((bfd_vma) byte & 0x7f) << shift);
      shift += 7;
    }
  while (byte & 0x80);
  if (byte & 0x40)
    result |= (((bfd_vma) -1) << (shift - 7)) << 7;
  * bytes_read_ptr = num_read;
  return result;
}

#define read_uleb128(VAR, BUF)					\
do								\
  {								\
    (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp);	\
    (BUF) += leb128_tmp;					\
  }								\
while (0)

#define read_sleb128(VAR, BUF)					\
do								\
  {								\
    (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp);	\
    (BUF) += leb128_tmp;					\
  }								\
while (0)

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

static
int get_DW_EH_PE_width (encoding, ptr_size)
     int encoding, 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 (abfd, buf, width, is_signed)
     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 (abfd, buf, value, width)
     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 zero if C1 and C2 CIEs can be merged.  */

static
int cie_compare (c1, c2)
     struct cie *c1, *c2;
{
  if (c1->hdr.length == c2->hdr.length
      && c1->version == c2->version
      && 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
      && c1->personality == c2->personality
      && 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)
      && memcmp (c1->initial_instructions,
		 c2->initial_instructions,
		 c1->initial_insn_length) == 0)
    return 0;

  return 1;
}

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

bfd_boolean
_bfd_elf_discard_section_eh_frame (abfd, info, sec,
				   reloc_symbol_deleted_p, cookie)
     bfd *abfd;
     struct bfd_link_info *info;
     asection *sec;
     bfd_boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
     struct elf_reloc_cookie *cookie;
{
  bfd_byte *ehbuf = NULL, *buf;
  bfd_byte *last_cie, *last_fde;
  struct cie_header hdr;
  struct cie cie;
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  struct eh_frame_sec_info *sec_info = NULL;
  unsigned int leb128_tmp;
  unsigned int cie_usage_count, last_cie_ndx, i, offset;
  unsigned int make_relative, make_lsda_relative;
  bfd_size_type new_size;
  unsigned int ptr_size;

  if (sec->_raw_size == 0)
    {
      /* This file does not contain .eh_frame information.  */
      return FALSE;
    }

  if ((sec->output_section != NULL
       && 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 FALSE;
    }

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

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

  ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
  if (ehbuf == NULL)
    goto free_no_table;

  if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
				  sec->_raw_size))
    goto free_no_table;

  if (sec->_raw_size >= 4
      && bfd_get_32 (abfd, ehbuf) == 0
      && cookie->rel == cookie->relend)
    {
      /* Empty .eh_frame section.  */
      free (ehbuf);
      return FALSE;
    }

  /* 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).  */
  if (sec->_raw_size != (unsigned int) sec->_raw_size)
    goto free_no_table;

  ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
	      == ELFCLASS64) ? 8 : 4;
  buf = ehbuf;
  last_cie = NULL;
  last_cie_ndx = 0;
  memset (&cie, 0, sizeof (cie));
  cie_usage_count = 0;
  new_size = sec->_raw_size;
  make_relative = hdr_info->last_cie.make_relative;
  make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
  sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
			  + 99 * sizeof (struct eh_cie_fde));
  if (sec_info == NULL)
    goto free_no_table;
  sec_info->alloced = 100;

#define ENSURE_NO_RELOCS(buf)				\
  if (cookie->rel < cookie->relend			\
      && (cookie->rel->r_offset				\
	  < (bfd_size_type) ((buf) - ehbuf))		\
      && cookie->rel->r_info != 0)			\
    goto free_no_table

#define SKIP_RELOCS(buf)				\
  while (cookie->rel < cookie->relend			\
         && (cookie->rel->r_offset			\
	     < (bfd_size_type) ((buf) - ehbuf)))	\
    cookie->rel++

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

  for (;;)
    {
      unsigned char *aug;

      if (sec_info->count == sec_info->alloced)
	{
	  sec_info = bfd_realloc (sec_info,
				  sizeof (struct eh_frame_sec_info)
				  + (sec_info->alloced + 99)
				     * sizeof (struct eh_cie_fde));
	  if (sec_info == NULL)
	    goto free_no_table;

	  memset (&sec_info->entry[sec_info->alloced], 0,
		  100 * sizeof (struct eh_cie_fde));
	  sec_info->alloced += 100;
	}

      last_fde = buf;
      /* If we are at the end of the section, we still need to decide
	 on whether to output or discard last encountered CIE (if any).  */
      if ((bfd_size_type) (buf - ehbuf) == sec->_raw_size)
	hdr.id = (unsigned int) -1;
      else
	{
	  if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
	    /* No space for CIE/FDE header length.  */
	    goto free_no_table;

	  hdr.length = bfd_get_32 (abfd, buf);
	  if (hdr.length == 0xffffffff)
	    /* 64-bit .eh_frame is not supported.  */
	    goto free_no_table;
	  buf += 4;
	  if ((bfd_size_type) (buf - ehbuf) + hdr.length > sec->_raw_size)
	    /* CIE/FDE not contained fully in this .eh_frame input section.  */
	    goto free_no_table;

	  sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
	  sec_info->entry[sec_info->count].size = 4 + hdr.length;

	  if (hdr.length == 0)
	    {
	      /* CIE with length 0 must be only the last in the section.  */
	      if ((bfd_size_type) (buf - ehbuf) < sec->_raw_size)
		goto free_no_table;
	      ENSURE_NO_RELOCS (buf);
	      sec_info->count++;
	      /* Now just finish last encountered CIE processing and break
		 the loop.  */
	      hdr.id = (unsigned int) -1;
	    }
	  else
	    {
	      hdr.id = bfd_get_32 (abfd, buf);
	      buf += 4;
	      if (hdr.id == (unsigned int) -1)
		goto free_no_table;
	    }
	}

      if (hdr.id == 0 || hdr.id == (unsigned int) -1)
	{
	  unsigned int initial_insn_length;

	  /* CIE  */
	  if (last_cie != NULL)
	    {
	      /* Now check if this CIE is identical to the last CIE,
		 in which case we can remove it provided we adjust
		 all FDEs.  Also, it can be removed if we have removed
		 all FDEs using it.  */
	      if ((!info->relocateable
		   && cie_compare (&cie, &hdr_info->last_cie) == 0)
		  || cie_usage_count == 0)
		{
		  new_size -= cie.hdr.length + 4;
		  sec_info->entry[last_cie_ndx].removed = 1;
		  sec_info->entry[last_cie_ndx].sec = hdr_info->last_cie_sec;
		  sec_info->entry[last_cie_ndx].new_offset
		    = hdr_info->last_cie_offset;
		}
	      else
		{
		  hdr_info->last_cie = cie;
		  hdr_info->last_cie_sec = sec;
		  hdr_info->last_cie_offset = last_cie - ehbuf;
		  sec_info->entry[last_cie_ndx].make_relative
		    = cie.make_relative;
		  sec_info->entry[last_cie_ndx].make_lsda_relative
		    = cie.make_lsda_relative;
		  sec_info->entry[last_cie_ndx].per_encoding_relative
		    = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
		}
	    }

	  if (hdr.id == (unsigned int) -1)
	    break;

	  last_cie_ndx = sec_info->count;
	  sec_info->entry[sec_info->count].cie = 1;

	  cie_usage_count = 0;
	  memset (&cie, 0, sizeof (cie));
	  cie.hdr = hdr;
	  cie.version = *buf++;

	  /* Cannot handle unknown versions.  */
	  if (cie.version != 1)
	    goto free_no_table;
	  if (strlen (buf) > sizeof (cie.augmentation) - 1)
	    goto free_no_table;

	  strcpy (cie.augmentation, buf);
	  buf = strchr (buf, '\0') + 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.  */
	      buf += ptr_size;
	      SKIP_RELOCS (buf);
	    }
	  read_uleb128 (cie.code_align, buf);
	  read_sleb128 (cie.data_align, buf);
	  /* Note - in DWARF2 the return address column is an unsigned byte.
	     In DWARF3 it is a ULEB128.  We are following DWARF3.  For most
	     ports this will not matter as the value will be less than 128.
	     For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
	     which conforms to the DWARF3 standard.  */
	  read_uleb128 (cie.ra_column, buf);
	  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++;
		  read_uleb128 (cie.augmentation_size, buf);
	  	  ENSURE_NO_RELOCS (buf);
		}

	      while (*aug != '\0')
		switch (*aug++)
		  {
		  case 'L':
		    cie.lsda_encoding = *buf++;
		    ENSURE_NO_RELOCS (buf);
		    if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
		      goto free_no_table;
		    break;
		  case 'R':
		    cie.fde_encoding = *buf++;
		    ENSURE_NO_RELOCS (buf);
		    if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
		      goto free_no_table;
		    break;
		  case 'P':
		    {
		      int per_width;

		      cie.per_encoding = *buf++;
		      per_width = get_DW_EH_PE_width (cie.per_encoding,
						      ptr_size);
		      if (per_width == 0)
			goto free_no_table;
		      if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
			buf = (ehbuf
			       + ((buf - ehbuf + per_width - 1)
				  & ~((bfd_size_type) per_width - 1)));
		      ENSURE_NO_RELOCS (buf);
		      /* Ensure we have a reloc here, against
			 a global symbol.  */
		      if (GET_RELOC (buf) != NULL)
			{
			  unsigned long r_symndx;

#ifdef BFD64
			  if (ptr_size == 8)
			    r_symndx = ELF64_R_SYM (cookie->rel->r_info);
			  else
#endif
			    r_symndx = ELF32_R_SYM (cookie->rel->r_info);
			  if (r_symndx >= cookie->locsymcount)
			    {
			      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;
			    }
			  cookie->rel++;
			}
		      buf += per_width;
		    }
		    break;
		  default:
		    /* Unrecognized augmentation. Better bail out.  */
		    goto free_no_table;
		  }
	    }

	  /* For shared libraries, try to get rid of as many RELATIVE relocs
	     as possible.  */
          if (info->shared
	      && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
	    cie.make_relative = 1;

	  if (info->shared
	      && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
	    cie.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 = cie.hdr.length - (buf - last_fde - 4);
	  if (initial_insn_length <= 50)
	    {
	      cie.initial_insn_length = initial_insn_length;
	      memcpy (cie.initial_instructions, buf, initial_insn_length);
	    }
	  buf += initial_insn_length;
	  ENSURE_NO_RELOCS (buf);
	  last_cie = last_fde;
	}
      else
	{
	  /* Ensure this FDE uses the last CIE encountered.  */
	  if (last_cie == NULL
	      || hdr.id != (unsigned int) (buf - 4 - last_cie))
	    goto free_no_table;

	  ENSURE_NO_RELOCS (buf);
	  if (GET_RELOC (buf) == NULL)
	    /* This should not happen.  */
	    goto free_no_table;
	  if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
	    {
	      /* This is a FDE against a discarded section.  It should
		 be deleted.  */
	      new_size -= hdr.length + 4;
	      sec_info->entry[sec_info->count].removed = 1;
	    }
	  else
	    {
	      if (info->shared
		  && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
		       && cie.make_relative == 0)
		      || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
		{
		  /* 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->table = FALSE;
		}
	      cie_usage_count++;
	      hdr_info->fde_count++;
	    }
	  if (cie.lsda_encoding != DW_EH_PE_omit)
	    {
	      unsigned int dummy;

	      aug = buf;
	      buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
	      if (cie.augmentation[0] == 'z')
		read_uleb128 (dummy, buf);
	      /* If some new augmentation data is added before LSDA
		 in FDE augmentation area, this need to be adjusted.  */
	      sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
	    }
	  buf = last_fde + 4 + hdr.length;
	  SKIP_RELOCS (buf);
	}

      sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
      sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
      sec_info->count++;
    }

  elf_section_data (sec)->sec_info = sec_info;
  sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;

  /* Ok, now we can assign new offsets.  */
  offset = 0;
  last_cie_ndx = 0;
  for (i = 0; i < sec_info->count; i++)
    {
      if (! sec_info->entry[i].removed)
	{
	  sec_info->entry[i].new_offset = offset;
	  offset += sec_info->entry[i].size;
	  if (sec_info->entry[i].cie)
	    {
	      last_cie_ndx = i;
	      make_relative = sec_info->entry[i].make_relative;
	      make_lsda_relative = sec_info->entry[i].make_lsda_relative;
	    }
	  else
	    {
	      sec_info->entry[i].make_relative = make_relative;
	      sec_info->entry[i].make_lsda_relative = make_lsda_relative;
	      sec_info->entry[i].per_encoding_relative = 0;
	    }
	}
      else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
	{
	  /* Need to adjust new_offset too.  */
	  BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
		      == sec_info->entry[i].new_offset);
	  sec_info->entry[i].new_offset
	    = sec_info->entry[last_cie_ndx].new_offset;
	}
    }
  if (hdr_info->last_cie_sec == sec)
    {
      BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
		  == hdr_info->last_cie_offset);
      hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
    }

  /* FIXME: Currently it is not possible to shrink sections to zero size at
     this point, so build a fake minimal CIE.  */
  if (new_size == 0)
    new_size = 16;

  /* Shrink the sec as needed.  */
  sec->_cooked_size = new_size;
  if (sec->_cooked_size == 0)
    sec->flags |= SEC_EXCLUDE;

  free (ehbuf);
  return new_size != sec->_raw_size;

free_no_table:
  if (ehbuf)
    free (ehbuf);
  if (sec_info)
    free (sec_info);
  hdr_info->table = FALSE;
  hdr_info->last_cie.hdr.length = 0;
  return FALSE;
}

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

bfd_boolean
_bfd_elf_discard_section_eh_frame_hdr (abfd, info)
     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 (sec == NULL)
    return FALSE;

  sec->_cooked_size = EH_FRAME_HDR_SIZE;
  if (hdr_info->table)
    sec->_cooked_size += 4 + hdr_info->fde_count * 8;

  /* Request program headers to be recalculated.  */
  elf_tdata (abfd)->program_header_size = 0;
  elf_tdata (abfd)->eh_frame_hdr = sec;
  return TRUE;
}

/* This function is called from size_dynamic_sections.
   It needs to decide whether .eh_frame_hdr should be output or not,
   because later on it is too late for calling _bfd_strip_section_from_output,
   since dynamic symbol table has been sized.  */

bfd_boolean
_bfd_elf_maybe_strip_eh_frame_hdr (info)
     struct bfd_link_info *info;
{
  asection *o;
  bfd *abfd;
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;

  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))
    {
      hdr_info->hdr_sec = NULL;
      return TRUE;
    }

  abfd = NULL;
  if (info->eh_frame_hdr)
    for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
      {
	/* Count only sections which have at least a single CIE or FDE.
	   There cannot be any CIE or FDE <= 8 bytes.  */
	o = bfd_get_section_by_name (abfd, ".eh_frame");
	if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
	  break;
      }

  if (abfd == NULL)
    {
      _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
      hdr_info->hdr_sec = NULL;
      return TRUE;
    }

  hdr_info->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 (output_bfd, sec, offset)
     bfd *output_bfd ATTRIBUTE_UNUSED;
     asection *sec;
     bfd_vma offset;
{
  struct eh_frame_sec_info *sec_info;
  unsigned int lo, hi, mid;

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

  if (offset >= sec->_raw_size)
    return offset - (sec->_cooked_size - sec->_raw_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 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].make_relative
      && ! sec_info->entry[mid].cie
      && 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].make_lsda_relative
      && ! sec_info->entry[mid].cie
      && (offset == (sec_info->entry[mid].offset + 8
		     + sec_info->entry[mid].lsda_offset)))
    return (bfd_vma) -2;

  return (offset + sec_info->entry[mid].new_offset
	  - sec_info->entry[mid].offset);
}

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

bfd_boolean
_bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
     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 i;
  bfd_byte *p, *buf;
  unsigned int leb128_tmp;
  unsigned int cie_offset = 0;
  unsigned int ptr_size;

  ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
	      == ELFCLASS64) ? 8 : 4;

  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
    return bfd_set_section_contents (abfd, sec->output_section,
				     contents,
				     (file_ptr) sec->output_offset,
				     sec->_raw_size);
  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->table && hdr_info->array == NULL)
    hdr_info->array
      = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
  if (hdr_info->array == NULL)
    hdr_info = NULL;

  p = contents;
  for (i = 0; i < sec_info->count; ++i)
    {
      if (sec_info->entry[i].removed)
	{
	  if (sec_info->entry[i].cie)
	    {
	      /* If CIE is removed due to no remaining FDEs referencing it
		 and there were no CIEs kept before it, sec_info->entry[i].sec
		 will be zero.  */
	      if (sec_info->entry[i].sec == NULL)
		cie_offset = 0;
	      else
		{
		  cie_offset = sec_info->entry[i].new_offset;
		  cie_offset += (sec_info->entry[i].sec->output_section->vma
				 + sec_info->entry[i].sec->output_offset
				 - sec->output_section->vma
				 - sec->output_offset);
		}
	    }
	  continue;
	}

      if (sec_info->entry[i].cie)
	{
	  /* CIE */
	  cie_offset = sec_info->entry[i].new_offset;
	  if (sec_info->entry[i].make_relative
	      || sec_info->entry[i].make_lsda_relative
	      || sec_info->entry[i].per_encoding_relative)
	    {
	      unsigned char *aug;
	      unsigned int action;
	      unsigned int dummy, per_width, per_encoding;

	      /* Need to find 'R' or 'L' augmentation's argument and modify
		 DW_EH_PE_* value.  */
	      action = (sec_info->entry[i].make_relative ? 1 : 0)
		       | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
		       | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
	      buf = contents + sec_info->entry[i].offset;
	      /* Skip length, id and version.  */
	      buf += 9;
	      aug = buf;
	      buf = strchr (buf, '\0') + 1;
	      read_uleb128 (dummy, buf);
	      read_sleb128 (dummy, buf);
	      read_uleb128 (dummy, buf);
	      if (*aug == 'z')
		{
		  read_uleb128 (dummy, buf);
		  aug++;
		}

	      while (action)
		switch (*aug++)
		  {
		  case 'L':
		    if (action & 2)
		      {
			BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
			*buf |= DW_EH_PE_pcrel;
			action &= ~2;
		      }
		    buf++;
		    break;
		  case 'P':
		    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)
				== sec_info->entry[i].per_encoding_relative);
		    if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
		      buf = (contents
			     + ((buf - contents + per_width - 1)
				& ~((bfd_size_type) per_width - 1)));
		    if (action & 4)
		      {
			bfd_vma value;

			value = read_value (abfd, buf, per_width,
					    get_DW_EH_PE_signed
					    (per_encoding));
			value += (sec_info->entry[i].offset
				  - sec_info->entry[i].new_offset);
			write_value (abfd, buf, value, per_width);
			action &= ~4;
		      }
		    buf += per_width;
		    break;
		  case 'R':
		    if (action & 1)
		      {
			BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
			*buf |= DW_EH_PE_pcrel;
			action &= ~1;
		      }
		    buf++;
		    break;
		  default:
		    BFD_FAIL ();
		  }
	    }
	}
      else if (sec_info->entry[i].size > 4)
	{
	  /* FDE */
	  bfd_vma value = 0, address;
	  unsigned int width;

	  buf = contents + sec_info->entry[i].offset;
	  /* Skip length.  */
	  buf += 4;
	  bfd_put_32 (abfd,
		      sec_info->entry[i].new_offset + 4 - cie_offset, buf);
	  buf += 4;
	  width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
				      ptr_size);
	  address = value = read_value (abfd, buf, width,
					get_DW_EH_PE_signed
					(sec_info->entry[i].fde_encoding));
	  if (value)
	    {
	      switch (sec_info->entry[i].fde_encoding & 0xf0)
		{
		case DW_EH_PE_indirect:
		case DW_EH_PE_textrel:
		  BFD_ASSERT (hdr_info == NULL);
		  break;
		case DW_EH_PE_datarel:
		  {
		    asection *got = bfd_get_section_by_name (abfd, ".got");

		    BFD_ASSERT (got != NULL);
		    address += got->vma;
		  }
		  break;
		case DW_EH_PE_pcrel:
		  value += (sec_info->entry[i].offset
			    - sec_info->entry[i].new_offset);
		  address += (sec->output_section->vma + sec->output_offset
			      + sec_info->entry[i].offset + 8);
		  break;
		}
	      if (sec_info->entry[i].make_relative)
		value -= (sec->output_section->vma + sec->output_offset
			  + sec_info->entry[i].new_offset + 8);
	      write_value (abfd, buf, value, width);
	    }

	  if (hdr_info)
	    {
	      hdr_info->array[hdr_info->array_count].initial_loc = address;
	      hdr_info->array[hdr_info->array_count++].fde
		= (sec->output_section->vma + sec->output_offset
		   + sec_info->entry[i].new_offset);
	    }

	  if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
	      || sec_info->entry[i].make_lsda_relative)
	    {
	      buf += sec_info->entry[i].lsda_offset;
	      width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
					  ptr_size);
	      value = read_value (abfd, buf, width,
				  get_DW_EH_PE_signed
				  (sec_info->entry[i].lsda_encoding));
	      if (value)
		{
		  if ((sec_info->entry[i].lsda_encoding & 0xf0)
		      == DW_EH_PE_pcrel)
		    value += (sec_info->entry[i].offset
			      - sec_info->entry[i].new_offset);
		  else if (sec_info->entry[i].make_lsda_relative)
		    value -= (sec->output_section->vma + sec->output_offset
			      + sec_info->entry[i].new_offset + 8
			      + sec_info->entry[i].lsda_offset);
		  write_value (abfd, buf, value, width);
		}
	    }
	}
      else
	/* Terminating FDE must be at the end of .eh_frame section only.  */
	BFD_ASSERT (i == sec_info->count - 1);

      BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
      memmove (p, contents + sec_info->entry[i].offset,
	       sec_info->entry[i].size);
      p += sec_info->entry[i].size;
    }

  /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
     shrink sections to zero size, this won't be needed any more.  */
  if (p == contents && sec->_cooked_size == 16)
    {
      bfd_put_32 (abfd, 12, p);		/* Fake CIE length */
      bfd_put_32 (abfd, 0, p + 4);	/* Fake CIE id */
      p[8] = 1;				/* Fake CIE version */
      memset (p + 9, 0, 7);		/* Fake CIE augmentation, 3xleb128
					   and 3xDW_CFA_nop as pad  */
      p += 16;
    }

  BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);

  return bfd_set_section_contents (abfd, sec->output_section,
                                   contents, (file_ptr) sec->output_offset,
                                   sec->_cooked_size);
}

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

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

/* 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.
   .eh_frame_hdr format:
   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).  */

bfd_boolean
_bfd_elf_write_section_eh_frame_hdr (abfd, info)
     bfd *abfd;
     struct bfd_link_info *info;
{
  struct elf_link_hash_table *htab;
  struct eh_frame_hdr_info *hdr_info;
  asection *sec;
  bfd_byte *contents;
  asection *eh_frame_sec;
  bfd_size_type size;
  bfd_boolean retval;

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

  size = EH_FRAME_HDR_SIZE;
  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
    size += 4 + hdr_info->fde_count * 8;
  contents = 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);
  contents[0] = 1;				/* Version.  */
  contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset.  */
  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
    {
      contents[2] = DW_EH_PE_udata4;		/* FDE count encoding.  */
      contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc.  */
    }
  else
    {
      contents[2] = DW_EH_PE_omit;
      contents[3] = DW_EH_PE_omit;
    }
  bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
	      contents + 4);
  if (contents[2] != DW_EH_PE_omit)
    {
      unsigned int i;

      bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
      qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
	     vma_compare);
      for (i = 0; i < hdr_info->fde_count; i++)
	{
	  bfd_put_32 (abfd,
		      hdr_info->array[i].initial_loc
		      - sec->output_section->vma,
		      contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
	  bfd_put_32 (abfd,
		      hdr_info->array[i].fde - sec->output_section->vma,
		      contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
	}
    }

  retval = bfd_set_section_contents (abfd, sec->output_section,
				     contents, (file_ptr) sec->output_offset,
				     sec->_cooked_size);
  free (contents);
  return retval;
}
