/* Frame unwinder for frames with DWARF Call Frame Information.

   Copyright (C) 2003-2021 Free Software Foundation, Inc.

   Contributed by Mark Kettenis.

   This file is part of GDB.

   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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "dwarf2/expr.h"
#include "dwarf2.h"
#include "dwarf2/leb.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "gdbtypes.h"
#include "symtab.h"
#include "objfiles.h"
#include "regcache.h"
#include "value.h"
#include "record.h"

#include "complaints.h"
#include "dwarf2/frame.h"
#include "dwarf2/read.h"
#include "dwarf2/public.h"
#include "ax.h"
#include "dwarf2/loc.h"
#include "dwarf2/frame-tailcall.h"
#include "gdbsupport/gdb_binary_search.h"
#if GDB_SELF_TEST
#include "gdbsupport/selftest.h"
#include "selftest-arch.h"
#endif
#include <unordered_map>

#include <algorithm>

struct comp_unit;

/* Call Frame Information (CFI).  */

/* Common Information Entry (CIE).  */

struct dwarf2_cie
{
  /* Computation Unit for this CIE.  */
  struct comp_unit *unit;

  /* Offset into the .debug_frame section where this CIE was found.
     Used to identify this CIE.  */
  ULONGEST cie_pointer;

  /* Constant that is factored out of all advance location
     instructions.  */
  ULONGEST code_alignment_factor;

  /* Constants that is factored out of all offset instructions.  */
  LONGEST data_alignment_factor;

  /* Return address column.  */
  ULONGEST return_address_register;

  /* Instruction sequence to initialize a register set.  */
  const gdb_byte *initial_instructions;
  const gdb_byte *end;

  /* Saved augmentation, in case it's needed later.  */
  char *augmentation;

  /* Encoding of addresses.  */
  gdb_byte encoding;

  /* Target address size in bytes.  */
  int addr_size;

  /* Target pointer size in bytes.  */
  int ptr_size;

  /* True if a 'z' augmentation existed.  */
  unsigned char saw_z_augmentation;

  /* True if an 'S' augmentation existed.  */
  unsigned char signal_frame;

  /* The version recorded in the CIE.  */
  unsigned char version;

  /* The segment size.  */
  unsigned char segment_size;
};

/* The CIE table is used to find CIEs during parsing, but then
   discarded.  It maps from the CIE's offset to the CIE.  */
typedef std::unordered_map<ULONGEST, dwarf2_cie *> dwarf2_cie_table;

/* Frame Description Entry (FDE).  */

struct dwarf2_fde
{
  /* CIE for this FDE.  */
  struct dwarf2_cie *cie;

  /* First location associated with this FDE.  */
  CORE_ADDR initial_location;

  /* Number of bytes of program instructions described by this FDE.  */
  CORE_ADDR address_range;

  /* Instruction sequence.  */
  const gdb_byte *instructions;
  const gdb_byte *end;

  /* True if this FDE is read from a .eh_frame instead of a .debug_frame
     section.  */
  unsigned char eh_frame_p;
};

typedef std::vector<dwarf2_fde *> dwarf2_fde_table;

/* A minimal decoding of DWARF2 compilation units.  We only decode
   what's needed to get to the call frame information.  */

struct comp_unit
{
  comp_unit (struct objfile *objf)
    : abfd (objf->obfd)
  {
  }

  /* Keep the bfd convenient.  */
  bfd *abfd;

  /* Pointer to the .debug_frame section loaded into memory.  */
  const gdb_byte *dwarf_frame_buffer = nullptr;

  /* Length of the loaded .debug_frame section.  */
  bfd_size_type dwarf_frame_size = 0;

  /* Pointer to the .debug_frame section.  */
  asection *dwarf_frame_section = nullptr;

  /* Base for DW_EH_PE_datarel encodings.  */
  bfd_vma dbase = 0;

  /* Base for DW_EH_PE_textrel encodings.  */
  bfd_vma tbase = 0;

  /* The FDE table.  */
  dwarf2_fde_table fde_table;

  /* Hold data used by this module.  */
  auto_obstack obstack;
};

static struct dwarf2_fde *dwarf2_frame_find_fde
  (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile);

static int dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch, int regnum,
				       int eh_frame_p);

static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
				     int ptr_len, const gdb_byte *buf,
				     unsigned int *bytes_read_ptr,
				     CORE_ADDR func_base);


/* See dwarf2-frame.h.  */
bool dwarf2_frame_unwinders_enabled_p = true;

/* Store the length the expression for the CFA in the `cfa_reg' field,
   which is unused in that case.  */
#define cfa_exp_len cfa_reg

dwarf2_frame_state::dwarf2_frame_state (CORE_ADDR pc_, struct dwarf2_cie *cie)
  : pc (pc_), data_align (cie->data_alignment_factor),
    code_align (cie->code_alignment_factor),
    retaddr_column (cie->return_address_register)
{
}


/* Helper functions for execute_stack_op.  */

static CORE_ADDR
read_addr_from_reg (struct frame_info *this_frame, int reg)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg);

  return address_from_register (regnum, this_frame);
}

/* Execute the required actions for both the DW_CFA_restore and
DW_CFA_restore_extended instructions.  */
static void
dwarf2_restore_rule (struct gdbarch *gdbarch, ULONGEST reg_num,
		     struct dwarf2_frame_state *fs, int eh_frame_p)
{
  ULONGEST reg;

  reg = dwarf2_frame_adjust_regnum (gdbarch, reg_num, eh_frame_p);
  fs->regs.alloc_regs (reg + 1);

  /* Check if this register was explicitly initialized in the
  CIE initial instructions.  If not, default the rule to
  UNSPECIFIED.  */
  if (reg < fs->initial.reg.size ())
    fs->regs.reg[reg] = fs->initial.reg[reg];
  else
    fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNSPECIFIED;

  if (fs->regs.reg[reg].how == DWARF2_FRAME_REG_UNSPECIFIED)
    {
      int regnum = dwarf_reg_to_regnum (gdbarch, reg);

      complaint (_("\
incomplete CFI data; DW_CFA_restore unspecified\n\
register %s (#%d) at %s"),
		 gdbarch_register_name (gdbarch, regnum), regnum,
		 paddress (gdbarch, fs->pc));
    }
}

class dwarf_expr_executor : public dwarf_expr_context
{
public:

  dwarf_expr_executor (dwarf2_per_objfile *per_objfile)
    : dwarf_expr_context (per_objfile)
  {}

  struct frame_info *this_frame;

  CORE_ADDR read_addr_from_reg (int reg) override
  {
    return ::read_addr_from_reg (this_frame, reg);
  }

  struct value *get_reg_value (struct type *type, int reg) override
  {
    struct gdbarch *gdbarch = get_frame_arch (this_frame);
    int regnum = dwarf_reg_to_regnum_or_error (gdbarch, reg);

    return value_from_register (type, regnum, this_frame);
  }

  void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t len) override
  {
    read_memory (addr, buf, len);
  }

  void get_frame_base (const gdb_byte **start, size_t *length) override
  {
    invalid ("DW_OP_fbreg");
  }

  void push_dwarf_reg_entry_value (enum call_site_parameter_kind kind,
				   union call_site_parameter_u kind_u,
				   int deref_size) override
  {
    invalid ("DW_OP_entry_value");
  }

  CORE_ADDR get_object_address () override
  {
    invalid ("DW_OP_push_object_address");
  }

  CORE_ADDR get_frame_cfa () override
  {
    invalid ("DW_OP_call_frame_cfa");
  }

  CORE_ADDR get_tls_address (CORE_ADDR offset) override
  {
    invalid ("DW_OP_form_tls_address");
  }

  void dwarf_call (cu_offset die_offset) override
  {
    invalid ("DW_OP_call*");
  }

  struct value *dwarf_variable_value (sect_offset sect_off) override
  {
    invalid ("DW_OP_GNU_variable_value");
  }

  CORE_ADDR get_addr_index (unsigned int index) override
  {
    invalid ("DW_OP_addrx or DW_OP_GNU_addr_index");
  }

 private:

  void invalid (const char *op) ATTRIBUTE_NORETURN
  {
    error (_("%s is invalid in this context"), op);
  }
};

static CORE_ADDR
execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
		  struct frame_info *this_frame, CORE_ADDR initial,
		  int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
{
  CORE_ADDR result;

  dwarf_expr_executor ctx (per_objfile);
  scoped_value_mark free_values;

  ctx.this_frame = this_frame;
  ctx.gdbarch = get_frame_arch (this_frame);
  ctx.addr_size = addr_size;
  ctx.ref_addr_size = -1;

  ctx.push_address (initial, initial_in_stack_memory);
  ctx.eval (exp, len);

  if (ctx.location == DWARF_VALUE_MEMORY)
    result = ctx.fetch_address (0);
  else if (ctx.location == DWARF_VALUE_REGISTER)
    result = ctx.read_addr_from_reg (value_as_long (ctx.fetch (0)));
  else
    {
      /* This is actually invalid DWARF, but if we ever do run across
	 it somehow, we might as well support it.  So, instead, report
	 it as unimplemented.  */
      error (_("\
Not implemented: computing unwound register using explicit value operator"));
    }

  return result;
}


/* Execute FDE program from INSN_PTR possibly up to INSN_END or up to inferior
   PC.  Modify FS state accordingly.  Return current INSN_PTR where the
   execution has stopped, one can resume it on the next call.  */

static const gdb_byte *
execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr,
		     const gdb_byte *insn_end, struct gdbarch *gdbarch,
		     CORE_ADDR pc, struct dwarf2_frame_state *fs,
		     CORE_ADDR text_offset)
{
  int eh_frame_p = fde->eh_frame_p;
  unsigned int bytes_read;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  while (insn_ptr < insn_end && fs->pc <= pc)
    {
      gdb_byte insn = *insn_ptr++;
      uint64_t utmp, reg;
      int64_t offset;

      if ((insn & 0xc0) == DW_CFA_advance_loc)
	fs->pc += (insn & 0x3f) * fs->code_align;
      else if ((insn & 0xc0) == DW_CFA_offset)
	{
	  reg = insn & 0x3f;
	  reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	  insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	  offset = utmp * fs->data_align;
	  fs->regs.alloc_regs (reg + 1);
	  fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
	  fs->regs.reg[reg].loc.offset = offset;
	}
      else if ((insn & 0xc0) == DW_CFA_restore)
	{
	  reg = insn & 0x3f;
	  dwarf2_restore_rule (gdbarch, reg, fs, eh_frame_p);
	}
      else
	{
	  switch (insn)
	    {
	    case DW_CFA_set_loc:
	      fs->pc = read_encoded_value (fde->cie->unit, fde->cie->encoding,
					   fde->cie->ptr_size, insn_ptr,
					   &bytes_read, fde->initial_location);
	      /* Apply the text offset for relocatable objects.  */
	      fs->pc += text_offset;
	      insn_ptr += bytes_read;
	      break;

	    case DW_CFA_advance_loc1:
	      utmp = extract_unsigned_integer (insn_ptr, 1, byte_order);
	      fs->pc += utmp * fs->code_align;
	      insn_ptr++;
	      break;
	    case DW_CFA_advance_loc2:
	      utmp = extract_unsigned_integer (insn_ptr, 2, byte_order);
	      fs->pc += utmp * fs->code_align;
	      insn_ptr += 2;
	      break;
	    case DW_CFA_advance_loc4:
	      utmp = extract_unsigned_integer (insn_ptr, 4, byte_order);
	      fs->pc += utmp * fs->code_align;
	      insn_ptr += 4;
	      break;

	    case DW_CFA_offset_extended:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      offset = utmp * fs->data_align;
	      fs->regs.alloc_regs (reg + 1);
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	      break;

	    case DW_CFA_restore_extended:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      dwarf2_restore_rule (gdbarch, reg, fs, eh_frame_p);
	      break;

	    case DW_CFA_undefined:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      fs->regs.alloc_regs (reg + 1);
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_UNDEFINED;
	      break;

	    case DW_CFA_same_value:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      fs->regs.alloc_regs (reg + 1);
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAME_VALUE;
	      break;

	    case DW_CFA_register:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      utmp = dwarf2_frame_adjust_regnum (gdbarch, utmp, eh_frame_p);
	      fs->regs.alloc_regs (reg + 1);
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_REG;
	      fs->regs.reg[reg].loc.reg = utmp;
	      break;

	    case DW_CFA_remember_state:
	      {
		struct dwarf2_frame_state_reg_info *new_rs;

		new_rs = new dwarf2_frame_state_reg_info (fs->regs);
		fs->regs.prev = new_rs;
	      }
	      break;

	    case DW_CFA_restore_state:
	      {
		struct dwarf2_frame_state_reg_info *old_rs = fs->regs.prev;

		if (old_rs == NULL)
		  {
		    complaint (_("\
bad CFI data; mismatched DW_CFA_restore_state at %s"),
			       paddress (gdbarch, fs->pc));
		  }
		else
		  fs->regs = std::move (*old_rs);
	      }
	      break;

	    case DW_CFA_def_cfa:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      fs->regs.cfa_reg = reg;
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);

	      if (fs->armcc_cfa_offsets_sf)
		utmp *= fs->data_align;

	      fs->regs.cfa_offset = utmp;
	      fs->regs.cfa_how = CFA_REG_OFFSET;
	      break;

	    case DW_CFA_def_cfa_register:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, reg,
							     eh_frame_p);
	      fs->regs.cfa_how = CFA_REG_OFFSET;
	      break;

	    case DW_CFA_def_cfa_offset:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);

	      if (fs->armcc_cfa_offsets_sf)
		utmp *= fs->data_align;

	      fs->regs.cfa_offset = utmp;
	      /* cfa_how deliberately not set.  */
	      break;

	    case DW_CFA_nop:
	      break;

	    case DW_CFA_def_cfa_expression:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      fs->regs.cfa_exp_len = utmp;
	      fs->regs.cfa_exp = insn_ptr;
	      fs->regs.cfa_how = CFA_EXP;
	      insn_ptr += fs->regs.cfa_exp_len;
	      break;

	    case DW_CFA_expression:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      fs->regs.alloc_regs (reg + 1);
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      fs->regs.reg[reg].loc.exp.start = insn_ptr;
	      fs->regs.reg[reg].loc.exp.len = utmp;
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_EXP;
	      insn_ptr += utmp;
	      break;

	    case DW_CFA_offset_extended_sf:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
	      offset *= fs->data_align;
	      fs->regs.alloc_regs (reg + 1);
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	      break;

	    case DW_CFA_val_offset:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      fs->regs.alloc_regs (reg + 1);
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      offset = utmp * fs->data_align;
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	      break;

	    case DW_CFA_val_offset_sf:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      fs->regs.alloc_regs (reg + 1);
	      insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
	      offset *= fs->data_align;
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_OFFSET;
	      fs->regs.reg[reg].loc.offset = offset;
	      break;

	    case DW_CFA_val_expression:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      fs->regs.alloc_regs (reg + 1);
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      fs->regs.reg[reg].loc.exp.start = insn_ptr;
	      fs->regs.reg[reg].loc.exp.len = utmp;
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_VAL_EXP;
	      insn_ptr += utmp;
	      break;

	    case DW_CFA_def_cfa_sf:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      fs->regs.cfa_reg = dwarf2_frame_adjust_regnum (gdbarch, reg,
							     eh_frame_p);
	      insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
	      fs->regs.cfa_offset = offset * fs->data_align;
	      fs->regs.cfa_how = CFA_REG_OFFSET;
	      break;

	    case DW_CFA_def_cfa_offset_sf:
	      insn_ptr = safe_read_sleb128 (insn_ptr, insn_end, &offset);
	      fs->regs.cfa_offset = offset * fs->data_align;
	      /* cfa_how deliberately not set.  */
	      break;

	    case DW_CFA_GNU_args_size:
	      /* Ignored.  */
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      break;

	    case DW_CFA_GNU_negative_offset_extended:
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &reg);
	      reg = dwarf2_frame_adjust_regnum (gdbarch, reg, eh_frame_p);
	      insn_ptr = safe_read_uleb128 (insn_ptr, insn_end, &utmp);
	      offset = utmp * fs->data_align;
	      fs->regs.alloc_regs (reg + 1);
	      fs->regs.reg[reg].how = DWARF2_FRAME_REG_SAVED_OFFSET;
	      fs->regs.reg[reg].loc.offset = -offset;
	      break;

	    default:
	      if (insn >= DW_CFA_lo_user && insn <= DW_CFA_hi_user)
		{
		  /* Handle vendor-specific CFI for different architectures.  */
		  if (!gdbarch_execute_dwarf_cfa_vendor_op (gdbarch, insn, fs))
		    error (_("Call Frame Instruction op %d in vendor extension "
			     "space is not handled on this architecture."),
			   insn);
		}
	      else
		internal_error (__FILE__, __LINE__,
				_("Unknown CFI encountered."));
	    }
	}
    }

  if (fs->initial.reg.empty ())
    {
      /* Don't allow remember/restore between CIE and FDE programs.  */
      delete fs->regs.prev;
      fs->regs.prev = NULL;
    }

  return insn_ptr;
}

#if GDB_SELF_TEST

namespace selftests {

/* Unit test to function execute_cfa_program.  */

static void
execute_cfa_program_test (struct gdbarch *gdbarch)
{
  struct dwarf2_fde fde;
  struct dwarf2_cie cie;

  memset (&fde, 0, sizeof fde);
  memset (&cie, 0, sizeof cie);

  cie.data_alignment_factor = -4;
  cie.code_alignment_factor = 2;
  fde.cie = &cie;

  dwarf2_frame_state fs (0, fde.cie);

  gdb_byte insns[] =
    {
      DW_CFA_def_cfa, 1, 4,  /* DW_CFA_def_cfa: r1 ofs 4 */
      DW_CFA_offset | 0x2, 1,  /* DW_CFA_offset: r2 at cfa-4 */
      DW_CFA_remember_state,
      DW_CFA_restore_state,
    };

  const gdb_byte *insn_end = insns + sizeof (insns);
  const gdb_byte *out = execute_cfa_program (&fde, insns, insn_end, gdbarch,
					     0, &fs, 0);

  SELF_CHECK (out == insn_end);
  SELF_CHECK (fs.pc == 0);

  /* The instructions above only use r1 and r2, but the register numbers
     used are adjusted by dwarf2_frame_adjust_regnum.  */
  auto r1 = dwarf2_frame_adjust_regnum (gdbarch, 1, fde.eh_frame_p);
  auto r2 = dwarf2_frame_adjust_regnum (gdbarch, 2, fde.eh_frame_p);

  SELF_CHECK (fs.regs.reg.size () == (std::max (r1, r2) + 1));

  SELF_CHECK (fs.regs.reg[r2].how == DWARF2_FRAME_REG_SAVED_OFFSET);
  SELF_CHECK (fs.regs.reg[r2].loc.offset == -4);

  for (auto i = 0; i < fs.regs.reg.size (); i++)
    if (i != r2)
      SELF_CHECK (fs.regs.reg[i].how == DWARF2_FRAME_REG_UNSPECIFIED);

  SELF_CHECK (fs.regs.cfa_reg == 1);
  SELF_CHECK (fs.regs.cfa_offset == 4);
  SELF_CHECK (fs.regs.cfa_how == CFA_REG_OFFSET);
  SELF_CHECK (fs.regs.cfa_exp == NULL);
  SELF_CHECK (fs.regs.prev == NULL);
}

} // namespace selftests
#endif /* GDB_SELF_TEST */



/* Architecture-specific operations.  */

/* Per-architecture data key.  */
static struct gdbarch_data *dwarf2_frame_data;

struct dwarf2_frame_ops
{
  /* Pre-initialize the register state REG for register REGNUM.  */
  void (*init_reg) (struct gdbarch *, int, struct dwarf2_frame_state_reg *,
		    struct frame_info *);

  /* Check whether the THIS_FRAME is a signal trampoline.  */
  int (*signal_frame_p) (struct gdbarch *, struct frame_info *);

  /* Convert .eh_frame register number to DWARF register number, or
     adjust .debug_frame register number.  */
  int (*adjust_regnum) (struct gdbarch *, int, int);
};

/* Default architecture-specific register state initialization
   function.  */

static void
dwarf2_frame_default_init_reg (struct gdbarch *gdbarch, int regnum,
			       struct dwarf2_frame_state_reg *reg,
			       struct frame_info *this_frame)
{
  /* If we have a register that acts as a program counter, mark it as
     a destination for the return address.  If we have a register that
     serves as the stack pointer, arrange for it to be filled with the
     call frame address (CFA).  The other registers are marked as
     unspecified.

     We copy the return address to the program counter, since many
     parts in GDB assume that it is possible to get the return address
     by unwinding the program counter register.  However, on ISA's
     with a dedicated return address register, the CFI usually only
     contains information to unwind that return address register.

     The reason we're treating the stack pointer special here is
     because in many cases GCC doesn't emit CFI for the stack pointer
     and implicitly assumes that it is equal to the CFA.  This makes
     some sense since the DWARF specification (version 3, draft 8,
     p. 102) says that:

     "Typically, the CFA is defined to be the value of the stack
     pointer at the call site in the previous frame (which may be
     different from its value on entry to the current frame)."

     However, this isn't true for all platforms supported by GCC
     (e.g. IBM S/390 and zSeries).  Those architectures should provide
     their own architecture-specific initialization function.  */

  if (regnum == gdbarch_pc_regnum (gdbarch))
    reg->how = DWARF2_FRAME_REG_RA;
  else if (regnum == gdbarch_sp_regnum (gdbarch))
    reg->how = DWARF2_FRAME_REG_CFA;
}

/* Return a default for the architecture-specific operations.  */

static void *
dwarf2_frame_init (struct obstack *obstack)
{
  struct dwarf2_frame_ops *ops;
  
  ops = OBSTACK_ZALLOC (obstack, struct dwarf2_frame_ops);
  ops->init_reg = dwarf2_frame_default_init_reg;
  return ops;
}

/* Set the architecture-specific register state initialization
   function for GDBARCH to INIT_REG.  */

void
dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
			   void (*init_reg) (struct gdbarch *, int,
					     struct dwarf2_frame_state_reg *,
					     struct frame_info *))
{
  struct dwarf2_frame_ops *ops
    = (struct dwarf2_frame_ops *) gdbarch_data (gdbarch, dwarf2_frame_data);

  ops->init_reg = init_reg;
}

/* Pre-initialize the register state REG for register REGNUM.  */

static void
dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
		       struct dwarf2_frame_state_reg *reg,
		       struct frame_info *this_frame)
{
  struct dwarf2_frame_ops *ops
    = (struct dwarf2_frame_ops *) gdbarch_data (gdbarch, dwarf2_frame_data);

  ops->init_reg (gdbarch, regnum, reg, this_frame);
}

/* Set the architecture-specific signal trampoline recognition
   function for GDBARCH to SIGNAL_FRAME_P.  */

void
dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
				 int (*signal_frame_p) (struct gdbarch *,
							struct frame_info *))
{
  struct dwarf2_frame_ops *ops
    = (struct dwarf2_frame_ops *) gdbarch_data (gdbarch, dwarf2_frame_data);

  ops->signal_frame_p = signal_frame_p;
}

/* Query the architecture-specific signal frame recognizer for
   THIS_FRAME.  */

static int
dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch,
			     struct frame_info *this_frame)
{
  struct dwarf2_frame_ops *ops
    = (struct dwarf2_frame_ops *) gdbarch_data (gdbarch, dwarf2_frame_data);

  if (ops->signal_frame_p == NULL)
    return 0;
  return ops->signal_frame_p (gdbarch, this_frame);
}

/* Set the architecture-specific adjustment of .eh_frame and .debug_frame
   register numbers.  */

void
dwarf2_frame_set_adjust_regnum (struct gdbarch *gdbarch,
				int (*adjust_regnum) (struct gdbarch *,
						      int, int))
{
  struct dwarf2_frame_ops *ops
    = (struct dwarf2_frame_ops *) gdbarch_data (gdbarch, dwarf2_frame_data);

  ops->adjust_regnum = adjust_regnum;
}

/* Translate a .eh_frame register to DWARF register, or adjust a .debug_frame
   register.  */

static int
dwarf2_frame_adjust_regnum (struct gdbarch *gdbarch,
			    int regnum, int eh_frame_p)
{
  struct dwarf2_frame_ops *ops
    = (struct dwarf2_frame_ops *) gdbarch_data (gdbarch, dwarf2_frame_data);

  if (ops->adjust_regnum == NULL)
    return regnum;
  return ops->adjust_regnum (gdbarch, regnum, eh_frame_p);
}

static void
dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs,
			  struct dwarf2_fde *fde)
{
  struct compunit_symtab *cust;

  cust = find_pc_compunit_symtab (fs->pc);
  if (cust == NULL)
    return;

  if (producer_is_realview (COMPUNIT_PRODUCER (cust)))
    {
      if (fde->cie->version == 1)
	fs->armcc_cfa_offsets_sf = 1;

      if (fde->cie->version == 1)
	fs->armcc_cfa_offsets_reversed = 1;

      /* The reversed offset problem is present in some compilers
	 using DWARF3, but it was eventually fixed.  Check the ARM
	 defined augmentations, which are in the format "armcc" followed
	 by a list of one-character options.  The "+" option means
	 this problem is fixed (no quirk needed).  If the armcc
	 augmentation is missing, the quirk is needed.  */
      if (fde->cie->version == 3
	  && (!startswith (fde->cie->augmentation, "armcc")
	      || strchr (fde->cie->augmentation + 5, '+') == NULL))
	fs->armcc_cfa_offsets_reversed = 1;

      return;
    }
}


/* See dwarf2-frame.h.  */

int
dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
		       struct dwarf2_per_cu_data *data,
		       int *regnum_out, LONGEST *offset_out,
		       CORE_ADDR *text_offset_out,
		       const gdb_byte **cfa_start_out,
		       const gdb_byte **cfa_end_out)
{
  struct dwarf2_fde *fde;
  dwarf2_per_objfile *per_objfile;
  CORE_ADDR pc1 = pc;

  /* Find the correct FDE.  */
  fde = dwarf2_frame_find_fde (&pc1, &per_objfile);
  if (fde == NULL)
    error (_("Could not compute CFA; needed to translate this expression"));

  gdb_assert (per_objfile != nullptr);

  dwarf2_frame_state fs (pc1, fde->cie);

  /* Check for "quirks" - known bugs in producers.  */
  dwarf2_frame_find_quirks (&fs, fde);

  /* First decode all the insns in the CIE.  */
  execute_cfa_program (fde, fde->cie->initial_instructions,
		       fde->cie->end, gdbarch, pc, &fs,
		       per_objfile->objfile->text_section_offset ());

  /* Save the initialized register set.  */
  fs.initial = fs.regs;

  /* Then decode the insns in the FDE up to our target PC.  */
  execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs,
		       per_objfile->objfile->text_section_offset ());

  /* Calculate the CFA.  */
  switch (fs.regs.cfa_how)
    {
    case CFA_REG_OFFSET:
      {
	int regnum = dwarf_reg_to_regnum_or_error (gdbarch, fs.regs.cfa_reg);

	*regnum_out = regnum;
	if (fs.armcc_cfa_offsets_reversed)
	  *offset_out = -fs.regs.cfa_offset;
	else
	  *offset_out = fs.regs.cfa_offset;
	return 1;
      }

    case CFA_EXP:
      *text_offset_out = per_objfile->objfile->text_section_offset ();
      *cfa_start_out = fs.regs.cfa_exp;
      *cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
      return 0;

    default:
      internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
    }
}


struct dwarf2_frame_cache
{
  /* DWARF Call Frame Address.  */
  CORE_ADDR cfa;

  /* Set if the return address column was marked as unavailable
     (required non-collected memory or registers to compute).  */
  int unavailable_retaddr;

  /* Set if the return address column was marked as undefined.  */
  int undefined_retaddr;

  /* Saved registers, indexed by GDB register number, not by DWARF
     register number.  */
  struct dwarf2_frame_state_reg *reg;

  /* Return address register.  */
  struct dwarf2_frame_state_reg retaddr_reg;

  /* Target address size in bytes.  */
  int addr_size;

  /* The dwarf2_per_objfile from which this frame description came.  */
  dwarf2_per_objfile *per_objfile;

  /* If not NULL then this frame is the bottom frame of a TAILCALL_FRAME
     sequence.  If NULL then it is a normal case with no TAILCALL_FRAME
     involved.  Non-bottom frames of a virtual tail call frames chain use
     dwarf2_tailcall_frame_unwind unwinder so this field does not apply for
     them.  */
  void *tailcall_cache;
};

static struct dwarf2_frame_cache *
dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  const int num_regs = gdbarch_num_cooked_regs (gdbarch);
  struct dwarf2_frame_cache *cache;
  struct dwarf2_fde *fde;
  CORE_ADDR entry_pc;
  const gdb_byte *instr;

  if (*this_cache)
    return (struct dwarf2_frame_cache *) *this_cache;

  /* Allocate a new cache.  */
  cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache);
  cache->reg = FRAME_OBSTACK_CALLOC (num_regs, struct dwarf2_frame_state_reg);
  *this_cache = cache;

  /* Unwind the PC.

     Note that if the next frame is never supposed to return (i.e. a call
     to abort), the compiler might optimize away the instruction at
     its return address.  As a result the return address will
     point at some random instruction, and the CFI for that
     instruction is probably worthless to us.  GCC's unwinder solves
     this problem by substracting 1 from the return address to get an
     address in the middle of a presumed call instruction (or the
     instruction in the associated delay slot).  This should only be
     done for "normal" frames and not for resume-type frames (signal
     handlers, sentinel frames, dummy frames).  The function
     get_frame_address_in_block does just this.  It's not clear how
     reliable the method is though; there is the potential for the
     register state pre-call being different to that on return.  */
  CORE_ADDR pc1 = get_frame_address_in_block (this_frame);

  /* Find the correct FDE.  */
  fde = dwarf2_frame_find_fde (&pc1, &cache->per_objfile);
  gdb_assert (fde != NULL);
  gdb_assert (cache->per_objfile != nullptr);

  /* Allocate and initialize the frame state.  */
  struct dwarf2_frame_state fs (pc1, fde->cie);

  cache->addr_size = fde->cie->addr_size;

  /* Check for "quirks" - known bugs in producers.  */
  dwarf2_frame_find_quirks (&fs, fde);

  /* First decode all the insns in the CIE.  */
  execute_cfa_program (fde, fde->cie->initial_instructions,
		       fde->cie->end, gdbarch,
		       get_frame_address_in_block (this_frame), &fs,
		       cache->per_objfile->objfile->text_section_offset ());

  /* Save the initialized register set.  */
  fs.initial = fs.regs;

  /* Fetching the entry pc for THIS_FRAME won't necessarily result
     in an address that's within the range of FDE locations.  This
     is due to the possibility of the function occupying non-contiguous
     ranges.  */
  LONGEST entry_cfa_sp_offset;
  int entry_cfa_sp_offset_p = 0;
  if (get_frame_func_if_available (this_frame, &entry_pc)
      && fde->initial_location <= entry_pc
      && entry_pc < fde->initial_location + fde->address_range)
    {
      /* Decode the insns in the FDE up to the entry PC.  */
      instr = execute_cfa_program
	(fde, fde->instructions, fde->end, gdbarch, entry_pc, &fs,
	 cache->per_objfile->objfile->text_section_offset ());

      if (fs.regs.cfa_how == CFA_REG_OFFSET
	  && (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg)
	      == gdbarch_sp_regnum (gdbarch)))
	{
	  entry_cfa_sp_offset = fs.regs.cfa_offset;
	  entry_cfa_sp_offset_p = 1;
	}
    }
  else
    instr = fde->instructions;

  /* Then decode the insns in the FDE up to our target PC.  */
  execute_cfa_program (fde, instr, fde->end, gdbarch,
		       get_frame_address_in_block (this_frame), &fs,
		       cache->per_objfile->objfile->text_section_offset ());

  try
    {
      /* Calculate the CFA.  */
      switch (fs.regs.cfa_how)
	{
	case CFA_REG_OFFSET:
	  cache->cfa = read_addr_from_reg (this_frame, fs.regs.cfa_reg);
	  if (fs.armcc_cfa_offsets_reversed)
	    cache->cfa -= fs.regs.cfa_offset;
	  else
	    cache->cfa += fs.regs.cfa_offset;
	  break;

	case CFA_EXP:
	  cache->cfa =
	    execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len,
			      cache->addr_size, this_frame, 0, 0,
			      cache->per_objfile);
	  break;

	default:
	  internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
	}
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == NOT_AVAILABLE_ERROR)
	{
	  cache->unavailable_retaddr = 1;
	  return cache;
	}

      throw;
    }

  /* Initialize the register state.  */
  {
    int regnum;

    for (regnum = 0; regnum < num_regs; regnum++)
      dwarf2_frame_init_reg (gdbarch, regnum, &cache->reg[regnum], this_frame);
  }

  /* Go through the DWARF2 CFI generated table and save its register
     location information in the cache.  Note that we don't skip the
     return address column; it's perfectly all right for it to
     correspond to a real register.  */
  {
    int column;		/* CFI speak for "register number".  */

    for (column = 0; column < fs.regs.reg.size (); column++)
      {
	/* Use the GDB register number as the destination index.  */
	int regnum = dwarf_reg_to_regnum (gdbarch, column);

	/* Protect against a target returning a bad register.  */
	if (regnum < 0 || regnum >= num_regs)
	  continue;

	/* NOTE: cagney/2003-09-05: CFI should specify the disposition
	   of all debug info registers.  If it doesn't, complain (but
	   not too loudly).  It turns out that GCC assumes that an
	   unspecified register implies "same value" when CFI (draft
	   7) specifies nothing at all.  Such a register could equally
	   be interpreted as "undefined".  Also note that this check
	   isn't sufficient; it only checks that all registers in the
	   range [0 .. max column] are specified, and won't detect
	   problems when a debug info register falls outside of the
	   table.  We need a way of iterating through all the valid
	   DWARF2 register numbers.  */
	if (fs.regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
	  {
	    if (cache->reg[regnum].how == DWARF2_FRAME_REG_UNSPECIFIED)
	      complaint (_("\
incomplete CFI data; unspecified registers (e.g., %s) at %s"),
			 gdbarch_register_name (gdbarch, regnum),
			 paddress (gdbarch, fs.pc));
	  }
	else
	  cache->reg[regnum] = fs.regs.reg[column];
      }
  }

  /* Eliminate any DWARF2_FRAME_REG_RA rules, and save the information
     we need for evaluating DWARF2_FRAME_REG_RA_OFFSET rules.  */
  {
    int regnum;

    for (regnum = 0; regnum < num_regs; regnum++)
      {
	if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA
	    || cache->reg[regnum].how == DWARF2_FRAME_REG_RA_OFFSET)
	  {
	    const std::vector<struct dwarf2_frame_state_reg> &regs
	      = fs.regs.reg;
	    ULONGEST retaddr_column = fs.retaddr_column;

	    /* It seems rather bizarre to specify an "empty" column as
	       the return adress column.  However, this is exactly
	       what GCC does on some targets.  It turns out that GCC
	       assumes that the return address can be found in the
	       register corresponding to the return address column.
	       Incidentally, that's how we should treat a return
	       address column specifying "same value" too.  */
	    if (fs.retaddr_column < fs.regs.reg.size ()
		&& regs[retaddr_column].how != DWARF2_FRAME_REG_UNSPECIFIED
		&& regs[retaddr_column].how != DWARF2_FRAME_REG_SAME_VALUE)
	      {
		if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA)
		  cache->reg[regnum] = regs[retaddr_column];
		else
		  cache->retaddr_reg = regs[retaddr_column];
	      }
	    else
	      {
		if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA)
		  {
		    cache->reg[regnum].loc.reg = fs.retaddr_column;
		    cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG;
		  }
		else
		  {
		    cache->retaddr_reg.loc.reg = fs.retaddr_column;
		    cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG;
		  }
	      }
	  }
      }
  }

  if (fs.retaddr_column < fs.regs.reg.size ()
      && fs.regs.reg[fs.retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED)
    cache->undefined_retaddr = 1;

  dwarf2_tailcall_sniffer_first (this_frame, &cache->tailcall_cache,
				 (entry_cfa_sp_offset_p
				  ? &entry_cfa_sp_offset : NULL));

  return cache;
}

static enum unwind_stop_reason
dwarf2_frame_unwind_stop_reason (struct frame_info *this_frame,
				 void **this_cache)
{
  struct dwarf2_frame_cache *cache
    = dwarf2_frame_cache (this_frame, this_cache);

  if (cache->unavailable_retaddr)
    return UNWIND_UNAVAILABLE;

  if (cache->undefined_retaddr)
    return UNWIND_OUTERMOST;

  return UNWIND_NO_REASON;
}

static void
dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache,
		      struct frame_id *this_id)
{
  struct dwarf2_frame_cache *cache =
    dwarf2_frame_cache (this_frame, this_cache);

  if (cache->unavailable_retaddr)
    (*this_id) = frame_id_build_unavailable_stack (get_frame_func (this_frame));
  else if (cache->undefined_retaddr)
    return;
  else
    (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame));
}

static struct value *
dwarf2_frame_prev_register (struct frame_info *this_frame, void **this_cache,
			    int regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct dwarf2_frame_cache *cache =
    dwarf2_frame_cache (this_frame, this_cache);
  CORE_ADDR addr;
  int realnum;

  /* Non-bottom frames of a virtual tail call frames chain use
     dwarf2_tailcall_frame_unwind unwinder so this code does not apply for
     them.  If dwarf2_tailcall_prev_register_first does not have specific value
     unwind the register, tail call frames are assumed to have the register set
     of the top caller.  */
  if (cache->tailcall_cache)
    {
      struct value *val;
      
      val = dwarf2_tailcall_prev_register_first (this_frame,
						 &cache->tailcall_cache,
						 regnum);
      if (val)
	return val;
    }

  switch (cache->reg[regnum].how)
    {
    case DWARF2_FRAME_REG_UNDEFINED:
      /* If CFI explicitly specified that the value isn't defined,
	 mark it as optimized away; the value isn't available.  */
      return frame_unwind_got_optimized (this_frame, regnum);

    case DWARF2_FRAME_REG_SAVED_OFFSET:
      addr = cache->cfa + cache->reg[regnum].loc.offset;
      return frame_unwind_got_memory (this_frame, regnum, addr);

    case DWARF2_FRAME_REG_SAVED_REG:
      realnum = dwarf_reg_to_regnum_or_error
	(gdbarch, cache->reg[regnum].loc.reg);
      return frame_unwind_got_register (this_frame, regnum, realnum);

    case DWARF2_FRAME_REG_SAVED_EXP:
      addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
			       cache->reg[regnum].loc.exp.len,
			       cache->addr_size,
			       this_frame, cache->cfa, 1,
			       cache->per_objfile);
      return frame_unwind_got_memory (this_frame, regnum, addr);

    case DWARF2_FRAME_REG_SAVED_VAL_OFFSET:
      addr = cache->cfa + cache->reg[regnum].loc.offset;
      return frame_unwind_got_constant (this_frame, regnum, addr);

    case DWARF2_FRAME_REG_SAVED_VAL_EXP:
      addr = execute_stack_op (cache->reg[regnum].loc.exp.start,
			       cache->reg[regnum].loc.exp.len,
			       cache->addr_size,
			       this_frame, cache->cfa, 1,
			       cache->per_objfile);
      return frame_unwind_got_constant (this_frame, regnum, addr);

    case DWARF2_FRAME_REG_UNSPECIFIED:
      /* GCC, in its infinite wisdom decided to not provide unwind
	 information for registers that are "same value".  Since
	 DWARF2 (3 draft 7) doesn't define such behavior, said
	 registers are actually undefined (which is different to CFI
	 "undefined").  Code above issues a complaint about this.
	 Here just fudge the books, assume GCC, and that the value is
	 more inner on the stack.  */
      return frame_unwind_got_register (this_frame, regnum, regnum);

    case DWARF2_FRAME_REG_SAME_VALUE:
      return frame_unwind_got_register (this_frame, regnum, regnum);

    case DWARF2_FRAME_REG_CFA:
      return frame_unwind_got_address (this_frame, regnum, cache->cfa);

    case DWARF2_FRAME_REG_CFA_OFFSET:
      addr = cache->cfa + cache->reg[regnum].loc.offset;
      return frame_unwind_got_address (this_frame, regnum, addr);

    case DWARF2_FRAME_REG_RA_OFFSET:
      addr = cache->reg[regnum].loc.offset;
      regnum = dwarf_reg_to_regnum_or_error
	(gdbarch, cache->retaddr_reg.loc.reg);
      addr += get_frame_register_unsigned (this_frame, regnum);
      return frame_unwind_got_address (this_frame, regnum, addr);

    case DWARF2_FRAME_REG_FN:
      return cache->reg[regnum].loc.fn (this_frame, this_cache, regnum);

    default:
      internal_error (__FILE__, __LINE__, _("Unknown register rule."));
    }
}

/* Proxy for tailcall_frame_dealloc_cache for bottom frame of a virtual tail
   call frames chain.  */

static void
dwarf2_frame_dealloc_cache (struct frame_info *self, void *this_cache)
{
  struct dwarf2_frame_cache *cache = dwarf2_frame_cache (self, &this_cache);

  if (cache->tailcall_cache)
    dwarf2_tailcall_frame_unwind.dealloc_cache (self, cache->tailcall_cache);
}

static int
dwarf2_frame_sniffer (const struct frame_unwind *self,
		      struct frame_info *this_frame, void **this_cache)
{
  if (!dwarf2_frame_unwinders_enabled_p)
    return 0;

  /* Grab an address that is guaranteed to reside somewhere within the
     function.  get_frame_pc(), with a no-return next function, can
     end up returning something past the end of this function's body.
     If the frame we're sniffing for is a signal frame whose start
     address is placed on the stack by the OS, its FDE must
     extend one byte before its start address or we could potentially
     select the FDE of the previous function.  */
  CORE_ADDR block_addr = get_frame_address_in_block (this_frame);
  struct dwarf2_fde *fde = dwarf2_frame_find_fde (&block_addr, NULL);

  if (!fde)
    return 0;

  /* On some targets, signal trampolines may have unwind information.
     We need to recognize them so that we set the frame type
     correctly.  */

  if (fde->cie->signal_frame
      || dwarf2_frame_signal_frame_p (get_frame_arch (this_frame),
				      this_frame))
    return self->type == SIGTRAMP_FRAME;

  if (self->type != NORMAL_FRAME)
    return 0;

  return 1;
}

static const struct frame_unwind dwarf2_frame_unwind =
{
  "dwarf2",
  NORMAL_FRAME,
  dwarf2_frame_unwind_stop_reason,
  dwarf2_frame_this_id,
  dwarf2_frame_prev_register,
  NULL,
  dwarf2_frame_sniffer,
  dwarf2_frame_dealloc_cache
};

static const struct frame_unwind dwarf2_signal_frame_unwind =
{
  "dwarf2 signal",
  SIGTRAMP_FRAME,
  dwarf2_frame_unwind_stop_reason,
  dwarf2_frame_this_id,
  dwarf2_frame_prev_register,
  NULL,
  dwarf2_frame_sniffer,

  /* TAILCALL_CACHE can never be in such frame to need dealloc_cache.  */
  NULL
};

/* Append the DWARF-2 frame unwinders to GDBARCH's list.  */

void
dwarf2_append_unwinders (struct gdbarch *gdbarch)
{
  frame_unwind_append_unwinder (gdbarch, &dwarf2_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &dwarf2_signal_frame_unwind);
}


/* There is no explicitly defined relationship between the CFA and the
   location of frame's local variables and arguments/parameters.
   Therefore, frame base methods on this page should probably only be
   used as a last resort, just to avoid printing total garbage as a
   response to the "info frame" command.  */

static CORE_ADDR
dwarf2_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct dwarf2_frame_cache *cache =
    dwarf2_frame_cache (this_frame, this_cache);

  return cache->cfa;
}

static const struct frame_base dwarf2_frame_base =
{
  &dwarf2_frame_unwind,
  dwarf2_frame_base_address,
  dwarf2_frame_base_address,
  dwarf2_frame_base_address
};

const struct frame_base *
dwarf2_frame_base_sniffer (struct frame_info *this_frame)
{
  CORE_ADDR block_addr = get_frame_address_in_block (this_frame);

  if (dwarf2_frame_find_fde (&block_addr, NULL))
    return &dwarf2_frame_base;

  return NULL;
}

/* Compute the CFA for THIS_FRAME, but only if THIS_FRAME came from
   the DWARF unwinder.  This is used to implement
   DW_OP_call_frame_cfa.  */

CORE_ADDR
dwarf2_frame_cfa (struct frame_info *this_frame)
{
  if (frame_unwinder_is (this_frame, &record_btrace_tailcall_frame_unwind)
      || frame_unwinder_is (this_frame, &record_btrace_frame_unwind))
    throw_error (NOT_AVAILABLE_ERROR,
		 _("cfa not available for record btrace target"));

  while (get_frame_type (this_frame) == INLINE_FRAME)
    this_frame = get_prev_frame (this_frame);
  if (get_frame_unwind_stop_reason (this_frame) == UNWIND_UNAVAILABLE)
    throw_error (NOT_AVAILABLE_ERROR,
		_("can't compute CFA for this frame: "
		  "required registers or memory are unavailable"));

  if (get_frame_id (this_frame).stack_status != FID_STACK_VALID)
    throw_error (NOT_AVAILABLE_ERROR,
		_("can't compute CFA for this frame: "
		  "frame base not available"));

  return get_frame_base (this_frame);
}

/* We store the frame data on the BFD.  This is only done if it is
   independent of the address space and so can be shared.  */
static const struct bfd_key<comp_unit> dwarf2_frame_bfd_data;

/* If any BFD sections require relocations (note; really should be if
   any debug info requires relocations), then we store the frame data
   on the objfile instead, and do not share it.  */
const struct objfile_key<comp_unit> dwarf2_frame_objfile_data;


/* Pointer encoding helper functions.  */

/* GCC supports exception handling based on DWARF2 CFI.  However, for
   technical reasons, it encodes addresses in its FDE's in a different
   way.  Several "pointer encodings" are supported.  The encoding
   that's used for a particular FDE is determined by the 'R'
   augmentation in the associated CIE.  The argument of this
   augmentation is a single byte.  

   The address can be encoded as 2 bytes, 4 bytes, 8 bytes, or as a
   LEB128.  This is encoded in bits 0, 1 and 2.  Bit 3 encodes whether
   the address is signed or unsigned.  Bits 4, 5 and 6 encode how the
   address should be interpreted (absolute, relative to the current
   position in the FDE, ...).  Bit 7, indicates that the address
   should be dereferenced.  */

static gdb_byte
encoding_for_size (unsigned int size)
{
  switch (size)
    {
    case 2:
      return DW_EH_PE_udata2;
    case 4:
      return DW_EH_PE_udata4;
    case 8:
      return DW_EH_PE_udata8;
    default:
      internal_error (__FILE__, __LINE__, _("Unsupported address size"));
    }
}

static CORE_ADDR
read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
		    int ptr_len, const gdb_byte *buf,
		    unsigned int *bytes_read_ptr,
		    CORE_ADDR func_base)
{
  ptrdiff_t offset;
  CORE_ADDR base;

  /* GCC currently doesn't generate DW_EH_PE_indirect encodings for
     FDE's.  */
  if (encoding & DW_EH_PE_indirect)
    internal_error (__FILE__, __LINE__, 
		    _("Unsupported encoding: DW_EH_PE_indirect"));

  *bytes_read_ptr = 0;

  switch (encoding & 0x70)
    {
    case DW_EH_PE_absptr:
      base = 0;
      break;
    case DW_EH_PE_pcrel:
      base = bfd_section_vma (unit->dwarf_frame_section);
      base += (buf - unit->dwarf_frame_buffer);
      break;
    case DW_EH_PE_datarel:
      base = unit->dbase;
      break;
    case DW_EH_PE_textrel:
      base = unit->tbase;
      break;
    case DW_EH_PE_funcrel:
      base = func_base;
      break;
    case DW_EH_PE_aligned:
      base = 0;
      offset = buf - unit->dwarf_frame_buffer;
      if ((offset % ptr_len) != 0)
	{
	  *bytes_read_ptr = ptr_len - (offset % ptr_len);
	  buf += *bytes_read_ptr;
	}
      break;
    default:
      internal_error (__FILE__, __LINE__,
		      _("Invalid or unsupported encoding"));
    }

  if ((encoding & 0x07) == 0x00)
    {
      encoding |= encoding_for_size (ptr_len);
      if (bfd_get_sign_extend_vma (unit->abfd))
	encoding |= DW_EH_PE_signed;
    }

  switch (encoding & 0x0f)
    {
    case DW_EH_PE_uleb128:
      {
	uint64_t value;
	const gdb_byte *end_buf = buf + (sizeof (value) + 1) * 8 / 7;

	*bytes_read_ptr += safe_read_uleb128 (buf, end_buf, &value) - buf;
	return base + value;
      }
    case DW_EH_PE_udata2:
      *bytes_read_ptr += 2;
      return (base + bfd_get_16 (unit->abfd, (bfd_byte *) buf));
    case DW_EH_PE_udata4:
      *bytes_read_ptr += 4;
      return (base + bfd_get_32 (unit->abfd, (bfd_byte *) buf));
    case DW_EH_PE_udata8:
      *bytes_read_ptr += 8;
      return (base + bfd_get_64 (unit->abfd, (bfd_byte *) buf));
    case DW_EH_PE_sleb128:
      {
	int64_t value;
	const gdb_byte *end_buf = buf + (sizeof (value) + 1) * 8 / 7;

	*bytes_read_ptr += safe_read_sleb128 (buf, end_buf, &value) - buf;
	return base + value;
      }
    case DW_EH_PE_sdata2:
      *bytes_read_ptr += 2;
      return (base + bfd_get_signed_16 (unit->abfd, (bfd_byte *) buf));
    case DW_EH_PE_sdata4:
      *bytes_read_ptr += 4;
      return (base + bfd_get_signed_32 (unit->abfd, (bfd_byte *) buf));
    case DW_EH_PE_sdata8:
      *bytes_read_ptr += 8;
      return (base + bfd_get_signed_64 (unit->abfd, (bfd_byte *) buf));
    default:
      internal_error (__FILE__, __LINE__,
		      _("Invalid or unsupported encoding"));
    }
}


/* Find CIE with the given CIE_POINTER in CIE_TABLE.  */
static struct dwarf2_cie *
find_cie (const dwarf2_cie_table &cie_table, ULONGEST cie_pointer)
{
  auto iter = cie_table.find (cie_pointer);
  if (iter != cie_table.end ())
    return iter->second;
  return NULL;
}

static inline int
bsearch_fde_cmp (const dwarf2_fde *fde, CORE_ADDR seek_pc)
{
  if (fde->initial_location + fde->address_range <= seek_pc)
    return -1;
  if (fde->initial_location <= seek_pc)
    return 0;
  return 1;
}

/* Find an existing comp_unit for an objfile, if any.  */

static comp_unit *
find_comp_unit (struct objfile *objfile)
{
  bfd *abfd = objfile->obfd;
  if (gdb_bfd_requires_relocations (abfd))
    return dwarf2_frame_objfile_data.get (objfile);

  return dwarf2_frame_bfd_data.get (abfd);
}

/* Store the comp_unit on OBJFILE, or the corresponding BFD, as
   appropriate.  */

static void
set_comp_unit (struct objfile *objfile, struct comp_unit *unit)
{
  bfd *abfd = objfile->obfd;
  if (gdb_bfd_requires_relocations (abfd))
    return dwarf2_frame_objfile_data.set (objfile, unit);

  return dwarf2_frame_bfd_data.set (abfd, unit);
}

/* Find the FDE for *PC.  Return a pointer to the FDE, and store the
   initial location associated with it into *PC.  */

static struct dwarf2_fde *
dwarf2_frame_find_fde (CORE_ADDR *pc, dwarf2_per_objfile **out_per_objfile)
{
  for (objfile *objfile : current_program_space->objfiles ())
    {
      CORE_ADDR offset;
      CORE_ADDR seek_pc;

      comp_unit *unit = find_comp_unit (objfile);
      if (unit == NULL)
	{
	  dwarf2_build_frame_info (objfile);
	  unit = find_comp_unit (objfile);
	}
      gdb_assert (unit != NULL);

      dwarf2_fde_table *fde_table = &unit->fde_table;
      if (fde_table->empty ())
	continue;

      gdb_assert (!objfile->section_offsets.empty ());
      offset = objfile->text_section_offset ();

      gdb_assert (!fde_table->empty ());
      if (*pc < offset + (*fde_table)[0]->initial_location)
	continue;

      seek_pc = *pc - offset;
      auto it = gdb::binary_search (fde_table->begin (), fde_table->end (),
				    seek_pc, bsearch_fde_cmp);
      if (it != fde_table->end ())
	{
	  *pc = (*it)->initial_location + offset;
	  if (out_per_objfile != nullptr)
	    *out_per_objfile = get_dwarf2_per_objfile (objfile);

	  return *it;
	}
    }
  return NULL;
}

/* Add FDE to FDE_TABLE.  */
static void
add_fde (dwarf2_fde_table *fde_table, struct dwarf2_fde *fde)
{
  if (fde->address_range == 0)
    /* Discard useless FDEs.  */
    return;

  fde_table->push_back (fde);
}

#define DW64_CIE_ID 0xffffffffffffffffULL

/* Defines the type of eh_frames that are expected to be decoded: CIE, FDE
   or any of them.  */

enum eh_frame_type
{
  EH_CIE_TYPE_ID = 1 << 0,
  EH_FDE_TYPE_ID = 1 << 1,
  EH_CIE_OR_FDE_TYPE_ID = EH_CIE_TYPE_ID | EH_FDE_TYPE_ID
};

static const gdb_byte *decode_frame_entry (struct gdbarch *gdbarch,
					   struct comp_unit *unit,
					   const gdb_byte *start,
					   int eh_frame_p,
					   dwarf2_cie_table &cie_table,
					   dwarf2_fde_table *fde_table,
					   enum eh_frame_type entry_type);

/* Decode the next CIE or FDE, entry_type specifies the expected type.
   Return NULL if invalid input, otherwise the next byte to be processed.  */

static const gdb_byte *
decode_frame_entry_1 (struct gdbarch *gdbarch,
		      struct comp_unit *unit, const gdb_byte *start,
		      int eh_frame_p,
		      dwarf2_cie_table &cie_table,
		      dwarf2_fde_table *fde_table,
		      enum eh_frame_type entry_type)
{
  const gdb_byte *buf, *end;
  ULONGEST length;
  unsigned int bytes_read;
  int dwarf64_p;
  ULONGEST cie_id;
  ULONGEST cie_pointer;
  int64_t sleb128;
  uint64_t uleb128;

  buf = start;
  length = read_initial_length (unit->abfd, buf, &bytes_read, false);
  buf += bytes_read;
  end = buf + (size_t) length;

  if (length == 0)
    return end;

  /* Are we still within the section?  */
  if (end <= buf || end > unit->dwarf_frame_buffer + unit->dwarf_frame_size)
    return NULL;

  /* Distinguish between 32 and 64-bit encoded frame info.  */
  dwarf64_p = (bytes_read == 12);

  /* In a .eh_frame section, zero is used to distinguish CIEs from FDEs.  */
  if (eh_frame_p)
    cie_id = 0;
  else if (dwarf64_p)
    cie_id = DW64_CIE_ID;
  else
    cie_id = DW_CIE_ID;

  if (dwarf64_p)
    {
      cie_pointer = read_8_bytes (unit->abfd, buf);
      buf += 8;
    }
  else
    {
      cie_pointer = read_4_bytes (unit->abfd, buf);
      buf += 4;
    }

  if (cie_pointer == cie_id)
    {
      /* This is a CIE.  */
      struct dwarf2_cie *cie;
      char *augmentation;
      unsigned int cie_version;

      /* Check that a CIE was expected.  */
      if ((entry_type & EH_CIE_TYPE_ID) == 0)
	error (_("Found a CIE when not expecting it."));

      /* Record the offset into the .debug_frame section of this CIE.  */
      cie_pointer = start - unit->dwarf_frame_buffer;

      /* Check whether we've already read it.  */
      if (find_cie (cie_table, cie_pointer))
	return end;

      cie = XOBNEW (&unit->obstack, struct dwarf2_cie);
      cie->initial_instructions = NULL;
      cie->cie_pointer = cie_pointer;

      /* The encoding for FDE's in a normal .debug_frame section
	 depends on the target address size.  */
      cie->encoding = DW_EH_PE_absptr;

      /* We'll determine the final value later, but we need to
	 initialize it conservatively.  */
      cie->signal_frame = 0;

      /* Check version number.  */
      cie_version = read_1_byte (unit->abfd, buf);
      if (cie_version != 1 && cie_version != 3 && cie_version != 4)
	return NULL;
      cie->version = cie_version;
      buf += 1;

      /* Interpret the interesting bits of the augmentation.  */
      cie->augmentation = augmentation = (char *) buf;
      buf += (strlen (augmentation) + 1);

      /* Ignore armcc augmentations.  We only use them for quirks,
	 and that doesn't happen until later.  */
      if (startswith (augmentation, "armcc"))
	augmentation += strlen (augmentation);

      /* The GCC 2.x "eh" augmentation has a pointer immediately
	 following the augmentation string, so it must be handled
	 first.  */
      if (augmentation[0] == 'e' && augmentation[1] == 'h')
	{
	  /* Skip.  */
	  buf += gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
	  augmentation += 2;
	}

      if (cie->version >= 4)
	{
	  /* FIXME: check that this is the same as from the CU header.  */
	  cie->addr_size = read_1_byte (unit->abfd, buf);
	  ++buf;
	  cie->segment_size = read_1_byte (unit->abfd, buf);
	  ++buf;
	}
      else
	{
	  cie->addr_size = gdbarch_dwarf2_addr_size (gdbarch);
	  cie->segment_size = 0;
	}
      /* Address values in .eh_frame sections are defined to have the
	 target's pointer size.  Watchout: This breaks frame info for
	 targets with pointer size < address size, unless a .debug_frame
	 section exists as well.  */
      if (eh_frame_p)
	cie->ptr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
      else
	cie->ptr_size = cie->addr_size;

      buf = gdb_read_uleb128 (buf, end, &uleb128);
      if (buf == NULL)
	return NULL;
      cie->code_alignment_factor = uleb128;

      buf = gdb_read_sleb128 (buf, end, &sleb128);
      if (buf == NULL)
	return NULL;
      cie->data_alignment_factor = sleb128;

      if (cie_version == 1)
	{
	  cie->return_address_register = read_1_byte (unit->abfd, buf);
	  ++buf;
	}
      else
	{
	  buf = gdb_read_uleb128 (buf, end, &uleb128);
	  if (buf == NULL)
	    return NULL;
	  cie->return_address_register = uleb128;
	}

      cie->return_address_register
	= dwarf2_frame_adjust_regnum (gdbarch,
				      cie->return_address_register,
				      eh_frame_p);

      cie->saw_z_augmentation = (*augmentation == 'z');
      if (cie->saw_z_augmentation)
	{
	  uint64_t uleb_length;

	  buf = gdb_read_uleb128 (buf, end, &uleb_length);
	  if (buf == NULL)
	    return NULL;
	  cie->initial_instructions = buf + uleb_length;
	  augmentation++;
	}

      while (*augmentation)
	{
	  /* "L" indicates a byte showing how the LSDA pointer is encoded.  */
	  if (*augmentation == 'L')
	    {
	      /* Skip.  */
	      buf++;
	      augmentation++;
	    }

	  /* "R" indicates a byte indicating how FDE addresses are encoded.  */
	  else if (*augmentation == 'R')
	    {
	      cie->encoding = *buf++;
	      augmentation++;
	    }

	  /* "P" indicates a personality routine in the CIE augmentation.  */
	  else if (*augmentation == 'P')
	    {
	      /* Skip.  Avoid indirection since we throw away the result.  */
	      gdb_byte encoding = (*buf++) & ~DW_EH_PE_indirect;
	      read_encoded_value (unit, encoding, cie->ptr_size,
				  buf, &bytes_read, 0);
	      buf += bytes_read;
	      augmentation++;
	    }

	  /* "S" indicates a signal frame, such that the return
	     address must not be decremented to locate the call frame
	     info for the previous frame; it might even be the first
	     instruction of a function, so decrementing it would take
	     us to a different function.  */
	  else if (*augmentation == 'S')
	    {
	      cie->signal_frame = 1;
	      augmentation++;
	    }

	  /* Otherwise we have an unknown augmentation.  Assume that either
	     there is no augmentation data, or we saw a 'z' prefix.  */
	  else
	    {
	      if (cie->initial_instructions)
		buf = cie->initial_instructions;
	      break;
	    }
	}

      cie->initial_instructions = buf;
      cie->end = end;
      cie->unit = unit;

      cie_table[cie->cie_pointer] = cie;
    }
  else
    {
      /* This is a FDE.  */
      struct dwarf2_fde *fde;
      CORE_ADDR addr;

      /* Check that an FDE was expected.  */
      if ((entry_type & EH_FDE_TYPE_ID) == 0)
	error (_("Found an FDE when not expecting it."));

      /* In an .eh_frame section, the CIE pointer is the delta between the
	 address within the FDE where the CIE pointer is stored and the
	 address of the CIE.  Convert it to an offset into the .eh_frame
	 section.  */
      if (eh_frame_p)
	{
	  cie_pointer = buf - unit->dwarf_frame_buffer - cie_pointer;
	  cie_pointer -= (dwarf64_p ? 8 : 4);
	}

      /* In either case, validate the result is still within the section.  */
      if (cie_pointer >= unit->dwarf_frame_size)
	return NULL;

      fde = XOBNEW (&unit->obstack, struct dwarf2_fde);
      fde->cie = find_cie (cie_table, cie_pointer);
      if (fde->cie == NULL)
	{
	  decode_frame_entry (gdbarch, unit,
			      unit->dwarf_frame_buffer + cie_pointer,
			      eh_frame_p, cie_table, fde_table,
			      EH_CIE_TYPE_ID);
	  fde->cie = find_cie (cie_table, cie_pointer);
	}

      gdb_assert (fde->cie != NULL);

      addr = read_encoded_value (unit, fde->cie->encoding, fde->cie->ptr_size,
				 buf, &bytes_read, 0);
      fde->initial_location = gdbarch_adjust_dwarf2_addr (gdbarch, addr);
      buf += bytes_read;

      fde->address_range =
	read_encoded_value (unit, fde->cie->encoding & 0x0f,
			    fde->cie->ptr_size, buf, &bytes_read, 0);
      addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + fde->address_range);
      fde->address_range = addr - fde->initial_location;
      buf += bytes_read;

      /* A 'z' augmentation in the CIE implies the presence of an
	 augmentation field in the FDE as well.  The only thing known
	 to be in here at present is the LSDA entry for EH.  So we
	 can skip the whole thing.  */
      if (fde->cie->saw_z_augmentation)
	{
	  uint64_t uleb_length;

	  buf = gdb_read_uleb128 (buf, end, &uleb_length);
	  if (buf == NULL)
	    return NULL;
	  buf += uleb_length;
	  if (buf > end)
	    return NULL;
	}

      fde->instructions = buf;
      fde->end = end;

      fde->eh_frame_p = eh_frame_p;

      add_fde (fde_table, fde);
    }

  return end;
}

/* Read a CIE or FDE in BUF and decode it. Entry_type specifies whether we
   expect an FDE or a CIE.  */

static const gdb_byte *
decode_frame_entry (struct gdbarch *gdbarch,
		    struct comp_unit *unit, const gdb_byte *start,
		    int eh_frame_p,
		    dwarf2_cie_table &cie_table,
		    dwarf2_fde_table *fde_table,
		    enum eh_frame_type entry_type)
{
  enum { NONE, ALIGN4, ALIGN8, FAIL } workaround = NONE;
  const gdb_byte *ret;
  ptrdiff_t start_offset;

  while (1)
    {
      ret = decode_frame_entry_1 (gdbarch, unit, start, eh_frame_p,
				  cie_table, fde_table, entry_type);
      if (ret != NULL)
	break;

      /* We have corrupt input data of some form.  */

      /* ??? Try, weakly, to work around compiler/assembler/linker bugs
	 and mismatches wrt padding and alignment of debug sections.  */
      /* Note that there is no requirement in the standard for any
	 alignment at all in the frame unwind sections.  Testing for
	 alignment before trying to interpret data would be incorrect.

	 However, GCC traditionally arranged for frame sections to be
	 sized such that the FDE length and CIE fields happen to be
	 aligned (in theory, for performance).  This, unfortunately,
	 was done with .align directives, which had the side effect of
	 forcing the section to be aligned by the linker.

	 This becomes a problem when you have some other producer that
	 creates frame sections that are not as strictly aligned.  That
	 produces a hole in the frame info that gets filled by the 
	 linker with zeros.

	 The GCC behaviour is arguably a bug, but it's effectively now
	 part of the ABI, so we're now stuck with it, at least at the
	 object file level.  A smart linker may decide, in the process
	 of compressing duplicate CIE information, that it can rewrite
	 the entire output section without this extra padding.  */

      start_offset = start - unit->dwarf_frame_buffer;
      if (workaround < ALIGN4 && (start_offset & 3) != 0)
	{
	  start += 4 - (start_offset & 3);
	  workaround = ALIGN4;
	  continue;
	}
      if (workaround < ALIGN8 && (start_offset & 7) != 0)
	{
	  start += 8 - (start_offset & 7);
	  workaround = ALIGN8;
	  continue;
	}

      /* Nothing left to try.  Arrange to return as if we've consumed
	 the entire input section.  Hopefully we'll get valid info from
	 the other of .debug_frame/.eh_frame.  */
      workaround = FAIL;
      ret = unit->dwarf_frame_buffer + unit->dwarf_frame_size;
      break;
    }

  switch (workaround)
    {
    case NONE:
      break;

    case ALIGN4:
      complaint (_("\
Corrupt data in %s:%s; align 4 workaround apparently succeeded"),
		 bfd_get_filename (unit->dwarf_frame_section->owner),
		 bfd_section_name (unit->dwarf_frame_section));
      break;

    case ALIGN8:
      complaint (_("\
Corrupt data in %s:%s; align 8 workaround apparently succeeded"),
		 bfd_get_filename (unit->dwarf_frame_section->owner),
		 bfd_section_name (unit->dwarf_frame_section));
      break;

    default:
      complaint (_("Corrupt data in %s:%s"),
		 bfd_get_filename (unit->dwarf_frame_section->owner),
		 bfd_section_name (unit->dwarf_frame_section));
      break;
    }

  return ret;
}

static bool
fde_is_less_than (const dwarf2_fde *aa, const dwarf2_fde *bb)
{
  if (aa->initial_location == bb->initial_location)
    {
      if (aa->address_range != bb->address_range
	  && aa->eh_frame_p == 0 && bb->eh_frame_p == 0)
	/* Linker bug, e.g. gold/10400.
	   Work around it by keeping stable sort order.  */
	return aa < bb;
      else
	/* Put eh_frame entries after debug_frame ones.  */
	return aa->eh_frame_p < bb->eh_frame_p;
    }

  return aa->initial_location < bb->initial_location;
}

void
dwarf2_build_frame_info (struct objfile *objfile)
{
  const gdb_byte *frame_ptr;
  dwarf2_cie_table cie_table;
  dwarf2_fde_table fde_table;

  struct gdbarch *gdbarch = objfile->arch ();

  /* Build a minimal decoding of the DWARF2 compilation unit.  */
  std::unique_ptr<comp_unit> unit (new comp_unit (objfile));

  if (objfile->separate_debug_objfile_backlink == NULL)
    {
      /* Do not read .eh_frame from separate file as they must be also
	 present in the main file.  */
      dwarf2_get_section_info (objfile, DWARF2_EH_FRAME,
			       &unit->dwarf_frame_section,
			       &unit->dwarf_frame_buffer,
			       &unit->dwarf_frame_size);
      if (unit->dwarf_frame_size)
	{
	  asection *got, *txt;

	  /* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base
	     that is used for the i386/amd64 target, which currently is
	     the only target in GCC that supports/uses the
	     DW_EH_PE_datarel encoding.  */
	  got = bfd_get_section_by_name (unit->abfd, ".got");
	  if (got)
	    unit->dbase = got->vma;

	  /* GCC emits the DW_EH_PE_textrel encoding type on sh and ia64
	     so far.  */
	  txt = bfd_get_section_by_name (unit->abfd, ".text");
	  if (txt)
	    unit->tbase = txt->vma;

	  try
	    {
	      frame_ptr = unit->dwarf_frame_buffer;
	      while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
		frame_ptr = decode_frame_entry (gdbarch, unit.get (),
						frame_ptr, 1,
						cie_table, &fde_table,
						EH_CIE_OR_FDE_TYPE_ID);
	    }

	  catch (const gdb_exception_error &e)
	    {
	      warning (_("skipping .eh_frame info of %s: %s"),
		       objfile_name (objfile), e.what ());

	      fde_table.clear ();
	      /* The cie_table is discarded below.  */
	    }

	  cie_table.clear ();
	}
    }

  dwarf2_get_section_info (objfile, DWARF2_DEBUG_FRAME,
			   &unit->dwarf_frame_section,
			   &unit->dwarf_frame_buffer,
			   &unit->dwarf_frame_size);
  if (unit->dwarf_frame_size)
    {
      size_t num_old_fde_entries = fde_table.size ();

      try
	{
	  frame_ptr = unit->dwarf_frame_buffer;
	  while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)
	    frame_ptr = decode_frame_entry (gdbarch, unit.get (), frame_ptr, 0,
					    cie_table, &fde_table,
					    EH_CIE_OR_FDE_TYPE_ID);
	}
      catch (const gdb_exception_error &e)
	{
	  warning (_("skipping .debug_frame info of %s: %s"),
		   objfile_name (objfile), e.what ());

	  fde_table.resize (num_old_fde_entries);
	}
    }

  struct dwarf2_fde *fde_prev = NULL;
  struct dwarf2_fde *first_non_zero_fde = NULL;

  /* Prepare FDE table for lookups.  */
  std::sort (fde_table.begin (), fde_table.end (), fde_is_less_than);

  /* Check for leftovers from --gc-sections.  The GNU linker sets
     the relevant symbols to zero, but doesn't zero the FDE *end*
     ranges because there's no relocation there.  It's (offset,
     length), not (start, end).  On targets where address zero is
     just another valid address this can be a problem, since the
     FDEs appear to be non-empty in the output --- we could pick
     out the wrong FDE.  To work around this, when overlaps are
     detected, we prefer FDEs that do not start at zero.

     Start by finding the first FDE with non-zero start.  Below
     we'll discard all FDEs that start at zero and overlap this
     one.  */
  for (struct dwarf2_fde *fde : fde_table)
    {
      if (fde->initial_location != 0)
	{
	  first_non_zero_fde = fde;
	  break;
	}
    }

  /* Since we'll be doing bsearch, squeeze out identical (except
     for eh_frame_p) fde entries so bsearch result is predictable.
     Also discard leftovers from --gc-sections.  */
  for (struct dwarf2_fde *fde : fde_table)
    {
      if (fde->initial_location == 0
	  && first_non_zero_fde != NULL
	  && (first_non_zero_fde->initial_location
	      < fde->initial_location + fde->address_range))
	continue;

      if (fde_prev != NULL
	  && fde_prev->initial_location == fde->initial_location)
	continue;

      unit->fde_table.push_back (fde);
      fde_prev = fde;
    }
  unit->fde_table.shrink_to_fit ();

  set_comp_unit (objfile, unit.release ());
}

/* Handle 'maintenance show dwarf unwinders'.  */

static void
show_dwarf_unwinders_enabled_p (struct ui_file *file, int from_tty,
				struct cmd_list_element *c,
				const char *value)
{
  fprintf_filtered (file,
		    _("The DWARF stack unwinders are currently %s.\n"),
		    value);
}

void _initialize_dwarf2_frame ();
void
_initialize_dwarf2_frame ()
{
  dwarf2_frame_data = gdbarch_data_register_pre_init (dwarf2_frame_init);

  add_setshow_boolean_cmd ("unwinders", class_obscure,
			   &dwarf2_frame_unwinders_enabled_p , _("\
Set whether the DWARF stack frame unwinders are used."), _("\
Show whether the DWARF stack frame unwinders are used."), _("\
When enabled the DWARF stack frame unwinders can be used for architectures\n\
that support the DWARF unwinders.  Enabling the DWARF unwinders for an\n\
architecture that doesn't support them will have no effect."),
			   NULL,
			   show_dwarf_unwinders_enabled_p,
			   &set_dwarf_cmdlist,
			   &show_dwarf_cmdlist);

#if GDB_SELF_TEST
  selftests::register_test_foreach_arch ("execute_cfa_program",
					 selftests::execute_cfa_program_test);
#endif
}
