/* Cache and manage frames for GDB, the GNU debugger.

   Copyright (C) 1986-2024 Free Software Foundation, Inc.

   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 "frame.h"
#include "target.h"
#include "value.h"
#include "inferior.h"
#include "regcache.h"
#include "user-regs.h"
#include "gdbsupport/gdb_obstack.h"
#include "dummy-frame.h"
#include "sentinel-frame.h"
#include "gdbcore.h"
#include "annotate.h"
#include "language.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "command.h"
#include "gdbcmd.h"
#include "observable.h"
#include "objfiles.h"
#include "gdbthread.h"
#include "block.h"
#include "inline-frame.h"
#include "tracepoint.h"
#include "hashtab.h"
#include "valprint.h"
#include "cli/cli-option.h"
#include "dwarf2/loc.h"

/* The sentinel frame terminates the innermost end of the frame chain.
   If unwound, it returns the information needed to construct an
   innermost frame.

   The current frame, which is the innermost frame, can be found at
   sentinel_frame->prev.

   This is an optimization to be able to find the sentinel frame quickly,
   it could otherwise be found in the frame cache.  */

static frame_info *sentinel_frame;

/* Number of calls to reinit_frame_cache.  */
static unsigned int frame_cache_generation = 0;

/* See frame.h.  */

unsigned int
get_frame_cache_generation ()
{
  return frame_cache_generation;
}

/* The values behind the global "set backtrace ..." settings.  */
set_backtrace_options user_set_backtrace_options;

static frame_info_ptr get_prev_frame_raw (const frame_info_ptr &this_frame);
static const char *frame_stop_reason_symbol_string (enum unwind_stop_reason reason);
static frame_info_ptr create_new_frame (frame_id id);

/* Status of some values cached in the frame_info object.  */

enum cached_copy_status
{
  /* Value is unknown.  */
  CC_UNKNOWN,

  /* We have a value.  */
  CC_VALUE,

  /* Value was not saved.  */
  CC_NOT_SAVED,

  /* Value is unavailable.  */
  CC_UNAVAILABLE
};

enum class frame_id_status
{
  /* Frame id is not computed.  */
  NOT_COMPUTED = 0,

  /* Frame id is being computed (compute_frame_id is active).  */
  COMPUTING,

  /* Frame id has been computed.  */
  COMPUTED,
};

/* We keep a cache of stack frames, each of which is a "struct
   frame_info".  The innermost one gets allocated (in
   wait_for_inferior) each time the inferior stops; sentinel_frame
   points to it.  Additional frames get allocated (in get_prev_frame)
   as needed, and are chained through the next and prev fields.  Any
   time that the frame cache becomes invalid (most notably when we
   execute something, but also if we change how we interpret the
   frames (e.g. "set heuristic-fence-post" in mips-tdep.c, or anything
   which reads new symbols)), we should call reinit_frame_cache.  */

struct frame_info
{
  /* Return a string representation of this frame.  */
  std::string to_string () const;

  /* Level of this frame.  The inner-most (youngest) frame is at level
     0.  As you move towards the outer-most (oldest) frame, the level
     increases.  This is a cached value.  It could just as easily be
     computed by counting back from the selected frame to the inner
     most frame.  */
  /* NOTE: cagney/2002-04-05: Perhaps a level of ``-1'' should be
     reserved to indicate a bogus frame - one that has been created
     just to keep GDB happy (GDB always needs a frame).  For the
     moment leave this as speculation.  */
  int level;

  /* The frame's program space.  */
  struct program_space *pspace;

  /* The frame's address space.  */
  const address_space *aspace;

  /* The frame's low-level unwinder and corresponding cache.  The
     low-level unwinder is responsible for unwinding register values
     for the previous frame.  The low-level unwind methods are
     selected based on the presence, or otherwise, of register unwind
     information such as CFI.  */
  void *prologue_cache;
  const struct frame_unwind *unwind;

  /* Cached copy of the previous frame's architecture.  */
  struct
  {
    bool p;
    struct gdbarch *arch;
  } prev_arch;

  /* Cached copy of the previous frame's resume address.  */
  struct {
    cached_copy_status status;
    /* Did VALUE require unmasking when being read.  */
    bool masked;
    CORE_ADDR value;
  } prev_pc;

  /* Cached copy of the previous frame's function address.  */
  struct
  {
    CORE_ADDR addr;
    cached_copy_status status;
  } prev_func;

  /* This frame's ID.  */
  struct
  {
    frame_id_status p;
    struct frame_id value;
  } this_id;

  /* The frame's high-level base methods, and corresponding cache.
     The high level base methods are selected based on the frame's
     debug info.  */
  const struct frame_base *base;
  void *base_cache;

  /* Pointers to the next (down, inner, younger) and previous (up,
     outer, older) frame_info's in the frame cache.  */
  struct frame_info *next; /* down, inner, younger */
  bool prev_p;
  struct frame_info *prev; /* up, outer, older */

  /* The reason why we could not set PREV, or UNWIND_NO_REASON if we
     could.  Only valid when PREV_P is set.  */
  enum unwind_stop_reason stop_reason;

  /* A frame specific string describing the STOP_REASON in more detail.
     Only valid when PREV_P is set, but even then may still be NULL.  */
  const char *stop_string;
};

/* See frame.h.  */

void
set_frame_previous_pc_masked (const frame_info_ptr &frame)
{
  frame->prev_pc.masked = true;
}

/* See frame.h.  */

bool
get_frame_pc_masked (const frame_info_ptr &frame)
{
  gdb_assert (frame->next != nullptr);
  gdb_assert (frame->next->prev_pc.status == CC_VALUE);

  return frame->next->prev_pc.masked;
}

/* A frame stash used to speed up frame lookups.  Create a hash table
   to stash frames previously accessed from the frame cache for
   quicker subsequent retrieval.  The hash table is emptied whenever
   the frame cache is invalidated.  */

static htab_t frame_stash;

/* Internal function to calculate a hash from the frame_id addresses,
   using as many valid addresses as possible.  Frames below level 0
   are not stored in the hash table.  */

static hashval_t
frame_addr_hash (const void *ap)
{
  const frame_info *frame = (const frame_info *) ap;
  const struct frame_id f_id = frame->this_id.value;
  hashval_t hash = 0;

  gdb_assert (f_id.stack_status != FID_STACK_INVALID
	      || f_id.code_addr_p
	      || f_id.special_addr_p);

  if (f_id.stack_status == FID_STACK_VALID)
    hash = iterative_hash (&f_id.stack_addr,
			   sizeof (f_id.stack_addr), hash);
  if (f_id.code_addr_p)
    hash = iterative_hash (&f_id.code_addr,
			   sizeof (f_id.code_addr), hash);
  if (f_id.special_addr_p)
    hash = iterative_hash (&f_id.special_addr,
			   sizeof (f_id.special_addr), hash);

  char user_created_p = f_id.user_created_p;
  hash = iterative_hash (&user_created_p, sizeof (user_created_p), hash);

  return hash;
}

/* Internal equality function for the hash table.  This function
   defers equality operations to frame_id::operator==.  */

static int
frame_addr_hash_eq (const void *a, const void *b)
{
  const frame_info *f_entry = (const frame_info *) a;
  const frame_info *f_element = (const frame_info *) b;

  return f_entry->this_id.value == f_element->this_id.value;
}

/* Deletion function for the frame cache hash table.  */

static void
frame_info_del (frame_info *frame)
{
  if (frame->prologue_cache != nullptr
      && frame->unwind->dealloc_cache != nullptr)
    frame->unwind->dealloc_cache (frame, frame->prologue_cache);

  if (frame->base_cache != nullptr
      && frame->base->unwind->dealloc_cache != nullptr)
    frame->base->unwind->dealloc_cache (frame, frame->base_cache);
}

/* Internal function to create the frame_stash hash table.  100 seems
   to be a good compromise to start the hash table at.  */

static void
frame_stash_create (void)
{
  frame_stash = htab_create
    (100, frame_addr_hash, frame_addr_hash_eq,
     [] (void *p)
       {
	 auto frame = static_cast<frame_info *> (p);
	 frame_info_del (frame);
       });
}

/* Internal function to add a frame to the frame_stash hash table.
   Returns false if a frame with the same ID was already stashed, true
   otherwise.  */

static bool
frame_stash_add (frame_info *frame)
{
  /* Valid frame levels are -1 (sentinel frames) and above.  */
  gdb_assert (frame->level >= -1);

  frame_info **slot = (frame_info **) htab_find_slot (frame_stash,
						      frame, INSERT);

  /* If we already have a frame in the stack with the same id, we
     either have a stack cycle (corrupted stack?), or some bug
     elsewhere in GDB.  In any case, ignore the duplicate and return
     an indication to the caller.  */
  if (*slot != nullptr)
    return false;

  *slot = frame;
  return true;
}

/* Internal function to search the frame stash for an entry with the
   given frame ID.  If found, return that frame.  Otherwise return
   NULL.  */

static frame_info_ptr
frame_stash_find (struct frame_id id)
{
  struct frame_info dummy;
  frame_info *frame;

  dummy.this_id.value = id;
  frame = (frame_info *) htab_find (frame_stash, &dummy);
  return frame_info_ptr (frame);
}

/* Internal function to invalidate the frame stash by removing all
   entries in it.  This only occurs when the frame cache is
   invalidated.  */

static void
frame_stash_invalidate (void)
{
  htab_empty (frame_stash);
}

/* See frame.h  */
scoped_restore_selected_frame::scoped_restore_selected_frame ()
{
  m_lang = current_language->la_language;
  save_selected_frame (&m_fid, &m_level);
}

/* See frame.h  */
scoped_restore_selected_frame::~scoped_restore_selected_frame ()
{
  restore_selected_frame (m_fid, m_level);
  set_language (m_lang);
}

/* Flag to control debugging.  */

bool frame_debug;

static void
show_frame_debug (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Frame debugging is %s.\n"), value);
}

/* Implementation of "show backtrace past-main".  */

static void
show_backtrace_past_main (struct ui_file *file, int from_tty,
			  struct cmd_list_element *c, const char *value)
{
  gdb_printf (file,
	      _("Whether backtraces should "
		"continue past \"main\" is %s.\n"),
	      value);
}

/* Implementation of "show backtrace past-entry".  */

static void
show_backtrace_past_entry (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Whether backtraces should continue past the "
		      "entry point of a program is %s.\n"),
	      value);
}

/* Implementation of "show backtrace limit".  */

static void
show_backtrace_limit (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  gdb_printf (file,
	      _("An upper bound on the number "
		"of backtrace levels is %s.\n"),
	      value);
}

/* See frame.h.  */

std::string
frame_id::to_string () const
{
  const struct frame_id &id = *this;

  std::string res = "{";

  if (id.stack_status == FID_STACK_INVALID)
    res += "!stack";
  else if (id.stack_status == FID_STACK_UNAVAILABLE)
    res += "stack=<unavailable>";
  else if (id.stack_status == FID_STACK_SENTINEL)
    res += "stack=<sentinel>";
  else if (id.stack_status == FID_STACK_OUTER)
    res += "stack=<outer>";
  else
    res += std::string ("stack=") + hex_string (id.stack_addr);

  /* Helper function to format 'N=A' if P is true, otherwise '!N'.  */
  auto field_to_string = [] (const char *n, bool p, CORE_ADDR a) -> std::string
  {
    if (p)
      return std::string (n) + "=" + core_addr_to_string (a);
    else
      return std::string ("!") + std::string (n);
  };

  res += (std::string (",")
	  + field_to_string ("code", id.code_addr_p, id.code_addr)
	  + std::string (",")
	  + field_to_string ("special", id.special_addr_p, id.special_addr));

  if (id.artificial_depth)
    res += ",artificial=" + std::to_string (id.artificial_depth);
  res += "}";
  return res;
}

/* See frame.h.  */

const char *
frame_type_str (frame_type type)
{
  switch (type)
    {
    case NORMAL_FRAME:
      return "NORMAL_FRAME";

    case DUMMY_FRAME:
      return "DUMMY_FRAME";

    case INLINE_FRAME:
      return "INLINE_FRAME";

    case TAILCALL_FRAME:
      return "TAILCALL_FRAME";

    case SIGTRAMP_FRAME:
      return "SIGTRAMP_FRAME";

    case ARCH_FRAME:
      return "ARCH_FRAME";

    case SENTINEL_FRAME:
      return "SENTINEL_FRAME";

    default:
      return "<unknown type>";
    };
}

 /* See struct frame_info.  */

std::string
frame_info::to_string () const
{
  const frame_info *fi = this;

  std::string res;

  res += string_printf ("{level=%d,", fi->level);

  if (fi->unwind != NULL)
    res += string_printf ("type=%s,", frame_type_str (fi->unwind->type));
  else
    res += "type=<unknown>,";

  if (fi->unwind != NULL)
    res += string_printf ("unwinder=\"%s\",", fi->unwind->name);
  else
    res += "unwinder=<unknown>,";

  if (fi->next == NULL || fi->next->prev_pc.status == CC_UNKNOWN)
    res += "pc=<unknown>,";
  else if (fi->next->prev_pc.status == CC_VALUE)
    res += string_printf ("pc=%s%s,", hex_string (fi->next->prev_pc.value),
			  fi->next->prev_pc.masked ? "[PAC]" : "");
  else if (fi->next->prev_pc.status == CC_NOT_SAVED)
    res += "pc=<not saved>,";
  else if (fi->next->prev_pc.status == CC_UNAVAILABLE)
    res += "pc=<unavailable>,";

  if (fi->this_id.p == frame_id_status::NOT_COMPUTED)
    res += "id=<not computed>,";
  else if (fi->this_id.p == frame_id_status::COMPUTING)
    res += "id=<computing>,";
  else
    res += string_printf ("id=%s,", fi->this_id.value.to_string ().c_str ());

  if (fi->next != NULL && fi->next->prev_func.status == CC_VALUE)
    res += string_printf ("func=%s", hex_string (fi->next->prev_func.addr));
  else
    res += "func=<unknown>";

  res += "}";

  return res;
}

/* Given FRAME, return the enclosing frame as found in real frames read-in from
   inferior memory.  Skip any previous frames which were made up by GDB.
   Return FRAME if FRAME is a non-artificial frame.
   Return NULL if FRAME is the start of an artificial-only chain.  */

static frame_info_ptr
skip_artificial_frames (const frame_info_ptr &initial_frame)
{
  /* Note we use get_prev_frame_always, and not get_prev_frame.  The
     latter will truncate the frame chain, leading to this function
     unintentionally returning a null_frame_id (e.g., when the user
     sets a backtrace limit).

     Note that for record targets we may get a frame chain that consists
     of artificial frames only.  */
  frame_info_ptr frame = initial_frame;
  while (get_frame_type (frame) == INLINE_FRAME
	 || get_frame_type (frame) == TAILCALL_FRAME)
    {
      frame = get_prev_frame_always (frame);
      if (frame == NULL)
	break;
    }

  return frame;
}

frame_info_ptr
skip_unwritable_frames (const frame_info_ptr &initial_frame)
{
  frame_info_ptr frame = initial_frame;
  while (gdbarch_code_of_frame_writable (get_frame_arch (frame), frame) == 0)
    {
      frame = get_prev_frame (frame);
      if (frame == NULL)
	break;
    }

  return frame;
}

/* See frame.h.  */

frame_info_ptr
skip_tailcall_frames (const frame_info_ptr &initial_frame)
{
  frame_info_ptr frame = initial_frame;
  while (get_frame_type (frame) == TAILCALL_FRAME)
    {
      /* Note that for record targets we may get a frame chain that consists of
	 tailcall frames only.  */
      frame = get_prev_frame (frame);
      if (frame == NULL)
	break;
    }

  return frame;
}

/* Compute the frame's uniq ID that can be used to, later, re-find the
   frame.  */

static void
compute_frame_id (const frame_info_ptr &fi)
{
  FRAME_SCOPED_DEBUG_ENTER_EXIT;

  gdb_assert (fi->this_id.p == frame_id_status::NOT_COMPUTED);

  unsigned int entry_generation = get_frame_cache_generation ();

  try
    {
      /* Mark this frame's id as "being computed.  */
      fi->this_id.p = frame_id_status::COMPUTING;

      frame_debug_printf ("fi=%d", fi->level);

      /* Find the unwinder.  */
      if (fi->unwind == NULL)
	frame_unwind_find_by_frame (fi, &fi->prologue_cache);

      /* Find THIS frame's ID.  */
      /* Default to outermost if no ID is found.  */
      fi->this_id.value = outer_frame_id;
      fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value);
      gdb_assert (frame_id_p (fi->this_id.value));

      /* Mark this frame's id as "computed".  */
      fi->this_id.p = frame_id_status::COMPUTED;

      frame_debug_printf ("  -> %s", fi->this_id.value.to_string ().c_str ());
    }
  catch (const gdb_exception &ex)
    {
      /* On error, revert the frame id status to not computed.  If the frame
	 cache generation changed, the frame object doesn't exist anymore, so
	 don't touch it.  */
      if (get_frame_cache_generation () == entry_generation)
	fi->this_id.p = frame_id_status::NOT_COMPUTED;

      throw;
    }
}

/* Return a frame uniq ID that can be used to, later, re-find the
   frame.  */

struct frame_id
get_frame_id (const frame_info_ptr &fi)
{
  if (fi == NULL)
    return null_frame_id;

  /* It's always invalid to try to get a frame's id while it is being
     computed.  */
  gdb_assert (fi->this_id.p != frame_id_status::COMPUTING);

  if (fi->this_id.p == frame_id_status::NOT_COMPUTED)
    {
      /* If we haven't computed the frame id yet, then it must be that
	 this is the current frame.  Compute it now, and stash the
	 result.  The IDs of other frames are computed as soon as
	 they're created, in order to detect cycles.  See
	 get_prev_frame_if_no_cycle.  */
      gdb_assert (fi->level == 0);

      /* Compute.  */
      compute_frame_id (fi);

      /* Since this is the first frame in the chain, this should
	 always succeed.  */
      bool stashed = frame_stash_add (fi.get ());
      gdb_assert (stashed);
    }

  return fi->this_id.value;
}

struct frame_id
get_stack_frame_id (const frame_info_ptr &next_frame)
{
  return get_frame_id (skip_artificial_frames (next_frame));
}

struct frame_id
frame_unwind_caller_id (const frame_info_ptr &initial_next_frame)
{
  /* Use get_prev_frame_always, and not get_prev_frame.  The latter
     will truncate the frame chain, leading to this function
     unintentionally returning a null_frame_id (e.g., when a caller
     requests the frame ID of "main()"s caller.  */

  frame_info_ptr next_frame = skip_artificial_frames (initial_next_frame);
  if (next_frame == NULL)
    return null_frame_id;

  frame_info_ptr this_frame = get_prev_frame_always (next_frame);
  if (this_frame)
    return get_frame_id (skip_artificial_frames (this_frame));
  else
    return null_frame_id;
}

const struct frame_id null_frame_id = { 0 }; /* All zeros.  */
const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_OUTER, 0, 1, 0 };

struct frame_id
frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr,
			CORE_ADDR special_addr)
{
  struct frame_id id = null_frame_id;

  id.stack_addr = stack_addr;
  id.stack_status = FID_STACK_VALID;
  id.code_addr = code_addr;
  id.code_addr_p = true;
  id.special_addr = special_addr;
  id.special_addr_p = true;
  return id;
}

/* See frame.h.  */

struct frame_id
frame_id_build_unavailable_stack (CORE_ADDR code_addr)
{
  struct frame_id id = null_frame_id;

  id.stack_status = FID_STACK_UNAVAILABLE;
  id.code_addr = code_addr;
  id.code_addr_p = true;
  return id;
}

/* See frame.h.  */

struct frame_id
frame_id_build_unavailable_stack_special (CORE_ADDR code_addr,
					  CORE_ADDR special_addr)
{
  struct frame_id id = null_frame_id;

  id.stack_status = FID_STACK_UNAVAILABLE;
  id.code_addr = code_addr;
  id.code_addr_p = true;
  id.special_addr = special_addr;
  id.special_addr_p = true;
  return id;
}

struct frame_id
frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr)
{
  struct frame_id id = null_frame_id;

  id.stack_addr = stack_addr;
  id.stack_status = FID_STACK_VALID;
  id.code_addr = code_addr;
  id.code_addr_p = true;
  return id;
}

struct frame_id
frame_id_build_wild (CORE_ADDR stack_addr)
{
  struct frame_id id = null_frame_id;

  id.stack_addr = stack_addr;
  id.stack_status = FID_STACK_VALID;
  return id;
}

/* See frame.h.  */

frame_id
frame_id_build_sentinel (CORE_ADDR stack_addr, CORE_ADDR code_addr)
{
  frame_id id = null_frame_id;

  id.stack_status = FID_STACK_SENTINEL;
  id.special_addr_p = 1;

  if (stack_addr != 0 || code_addr != 0)
    {
      /* The purpose of saving these in the sentinel frame ID is to be able to
	 differentiate the IDs of several sentinel frames that could exist
	 simultaneously in the frame cache.  */
      id.stack_addr = stack_addr;
      id.code_addr = code_addr;
      id.code_addr_p = 1;
    }

  return id;
}

bool
frame_id_p (frame_id l)
{
  /* The frame is valid iff it has a valid stack address.  */
  bool p = l.stack_status != FID_STACK_INVALID;

  frame_debug_printf ("l=%s -> %d", l.to_string ().c_str (), p);

  return p;
}

bool
frame_id_artificial_p (frame_id l)
{
  if (!frame_id_p (l))
    return false;

  return l.artificial_depth != 0;
}

bool
frame_id::operator== (const frame_id &r) const
{
  bool eq;

  if (stack_status == FID_STACK_INVALID
      || r.stack_status == FID_STACK_INVALID)
    /* Like a NaN, if either ID is invalid, the result is false.
       Note that a frame ID is invalid iff it is the null frame ID.  */
    eq = false;
  else if (stack_status != r.stack_status || stack_addr != r.stack_addr)
    /* If .stack addresses are different, the frames are different.  */
    eq = false;
  else if (code_addr_p && r.code_addr_p && code_addr != r.code_addr)
    /* An invalid code addr is a wild card.  If .code addresses are
       different, the frames are different.  */
    eq = false;
  else if (special_addr_p && r.special_addr_p
	   && special_addr != r.special_addr)
    /* An invalid special addr is a wild card (or unused).  Otherwise
       if special addresses are different, the frames are different.  */
    eq = false;
  else if (artificial_depth != r.artificial_depth)
    /* If artificial depths are different, the frames must be different.  */
    eq = false;
  else if (user_created_p != r.user_created_p)
    eq = false;
  else
    /* Frames are equal.  */
    eq = true;

  frame_debug_printf ("l=%s, r=%s -> %d",
		      to_string ().c_str (), r.to_string ().c_str (), eq);

  return eq;
}

/* Safety net to check whether frame ID L should be inner to
   frame ID R, according to their stack addresses.

   This method cannot be used to compare arbitrary frames, as the
   ranges of valid stack addresses may be discontiguous (e.g. due
   to sigaltstack).

   However, it can be used as safety net to discover invalid frame
   IDs in certain circumstances.  Assuming that NEXT is the immediate
   inner frame to THIS and that NEXT and THIS are both NORMAL frames:

   * The stack address of NEXT must be inner-than-or-equal to the stack
     address of THIS.

     Therefore, if frame_id_inner (THIS, NEXT) holds, some unwind
     error has occurred.

   * If NEXT and THIS have different stack addresses, no other frame
     in the frame chain may have a stack address in between.

     Therefore, if frame_id_inner (TEST, THIS) holds, but
     frame_id_inner (TEST, NEXT) does not hold, TEST cannot refer
     to a valid frame in the frame chain.

   The sanity checks above cannot be performed when a SIGTRAMP frame
   is involved, because signal handlers might be executed on a different
   stack than the stack used by the routine that caused the signal
   to be raised.  This can happen for instance when a thread exceeds
   its maximum stack size.  In this case, certain compilers implement
   a stack overflow strategy that cause the handler to be run on a
   different stack.  */

static bool
frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
{
  bool inner;

  if (l.stack_status != FID_STACK_VALID || r.stack_status != FID_STACK_VALID)
    /* Like NaN, any operation involving an invalid ID always fails.
       Likewise if either ID has an unavailable stack address.  */
    inner = false;
  else if (l.artificial_depth > r.artificial_depth
	   && l.stack_addr == r.stack_addr
	   && l.code_addr_p == r.code_addr_p
	   && l.special_addr_p == r.special_addr_p
	   && l.special_addr == r.special_addr)
    {
      /* Same function, different inlined functions.  */
      const struct block *lb, *rb;

      gdb_assert (l.code_addr_p && r.code_addr_p);

      lb = block_for_pc (l.code_addr);
      rb = block_for_pc (r.code_addr);

      if (lb == NULL || rb == NULL)
	/* Something's gone wrong.  */
	inner = false;
      else
	/* This will return true if LB and RB are the same block, or
	   if the block with the smaller depth lexically encloses the
	   block with the greater depth.  */
	inner = rb->contains (lb);
    }
  else
    /* Only return non-zero when strictly inner than.  Note that, per
       comment in "frame.h", there is some fuzz here.  Frameless
       functions are not strictly inner than (same .stack but
       different .code and/or .special address).  */
    inner = gdbarch_inner_than (gdbarch, l.stack_addr, r.stack_addr);

  frame_debug_printf ("is l=%s inner than r=%s? %d",
		      l.to_string ().c_str (), r.to_string ().c_str (),
		      inner);

  return inner;
}

frame_info_ptr
frame_find_by_id (struct frame_id id)
{
  frame_info_ptr frame, prev_frame;

  /* ZERO denotes the null frame, let the caller decide what to do
     about it.  Should it instead return get_current_frame()?  */
  if (!frame_id_p (id))
    return NULL;

  /* Check for the sentinel frame.  */
  if (id == frame_id_build_sentinel (0, 0))
    return frame_info_ptr (sentinel_frame);

  /* Try using the frame stash first.  Finding it there removes the need
     to perform the search by looping over all frames, which can be very
     CPU-intensive if the number of frames is very high (the loop is O(n)
     and get_prev_frame performs a series of checks that are relatively
     expensive).  This optimization is particularly useful when this function
     is called from another function (such as value_fetch_lazy, case
     val->lval () == lval_register) which already loops over all frames,
     making the overall behavior O(n^2).  */
  frame = frame_stash_find (id);
  if (frame)
    return frame;

  for (frame = get_current_frame (); ; frame = prev_frame)
    {
      struct frame_id self = get_frame_id (frame);

      if (id == self)
	/* An exact match.  */
	return frame;

      prev_frame = get_prev_frame (frame);
      if (!prev_frame)
	return NULL;

      /* As a safety net to avoid unnecessary backtracing while trying
	 to find an invalid ID, we check for a common situation where
	 we can detect from comparing stack addresses that no other
	 frame in the current frame chain can have this ID.  See the
	 comment at frame_id_inner for details.   */
      if (get_frame_type (frame) == NORMAL_FRAME
	  && !frame_id_inner (get_frame_arch (frame), id, self)
	  && frame_id_inner (get_frame_arch (prev_frame), id,
			     get_frame_id (prev_frame)))
	return NULL;
    }
  return NULL;
}

static CORE_ADDR
frame_unwind_pc (const frame_info_ptr &this_frame)
{
  if (this_frame->prev_pc.status == CC_UNKNOWN)
    {
      struct gdbarch *prev_gdbarch;
      CORE_ADDR pc = 0;
      bool pc_p = false;

      /* The right way.  The `pure' way.  The one true way.  This
	 method depends solely on the register-unwind code to
	 determine the value of registers in THIS frame, and hence
	 the value of this frame's PC (resume address).  A typical
	 implementation is no more than:

	 frame_unwind_register (this_frame, ISA_PC_REGNUM, buf);
	 return extract_unsigned_integer (buf, size of ISA_PC_REGNUM);

	 Note: this method is very heavily dependent on a correct
	 register-unwind implementation, it pays to fix that
	 method first; this method is frame type agnostic, since
	 it only deals with register values, it works with any
	 frame.  This is all in stark contrast to the old
	 FRAME_SAVED_PC which would try to directly handle all the
	 different ways that a PC could be unwound.  */
      prev_gdbarch = frame_unwind_arch (this_frame);

      try
	{
	  pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
	  pc_p = true;
	}
      catch (const gdb_exception_error &ex)
	{
	  if (ex.error == NOT_AVAILABLE_ERROR)
	    {
	      this_frame->prev_pc.status = CC_UNAVAILABLE;

	      frame_debug_printf ("this_frame=%d -> <unavailable>",
				  this_frame->level);
	    }
	  else if (ex.error == OPTIMIZED_OUT_ERROR)
	    {
	      this_frame->prev_pc.status = CC_NOT_SAVED;

	      frame_debug_printf ("this_frame=%d -> <not saved>",
				  this_frame->level);
	    }
	  else
	    throw;
	}

      if (pc_p)
	{
	  this_frame->prev_pc.value = pc;
	  this_frame->prev_pc.status = CC_VALUE;

	  frame_debug_printf ("this_frame=%d -> %s",
			      this_frame->level,
			      hex_string (this_frame->prev_pc.value));
	}
    }

  if (this_frame->prev_pc.status == CC_VALUE)
    return this_frame->prev_pc.value;
  else if (this_frame->prev_pc.status == CC_UNAVAILABLE)
    throw_error (NOT_AVAILABLE_ERROR, _("PC not available"));
  else if (this_frame->prev_pc.status == CC_NOT_SAVED)
    throw_error (OPTIMIZED_OUT_ERROR, _("PC not saved"));
  else
    internal_error ("unexpected prev_pc status: %d",
		    (int) this_frame->prev_pc.status);
}

CORE_ADDR
frame_unwind_caller_pc (const frame_info_ptr &initial_this_frame)
{
  frame_info_ptr this_frame = skip_artificial_frames (initial_this_frame);

  /* We must have a non-artificial frame.  The caller is supposed to check
     the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID
     in this case.  */
  gdb_assert (this_frame != nullptr);

  return frame_unwind_pc (this_frame);
}

bool
get_frame_func_if_available (const frame_info_ptr &this_frame, CORE_ADDR *pc)
{
  frame_info *next_frame = this_frame->next;

  if (next_frame->prev_func.status == CC_UNKNOWN)
    {
      CORE_ADDR addr_in_block;

      /* Make certain that this, and not the adjacent, function is
	 found.  */
      if (!get_frame_address_in_block_if_available (this_frame, &addr_in_block))
	{
	  next_frame->prev_func.status = CC_UNAVAILABLE;

	  frame_debug_printf ("this_frame=%d -> unavailable",
			      this_frame->level);
	}
      else
	{
	  next_frame->prev_func.status = CC_VALUE;
	  next_frame->prev_func.addr = get_pc_function_start (addr_in_block);

	  frame_debug_printf ("this_frame=%d -> %s",
			      this_frame->level,
			      hex_string (next_frame->prev_func.addr));
	}
    }

  if (next_frame->prev_func.status == CC_UNAVAILABLE)
    {
      *pc = -1;
      return false;
    }
  else
    {
      gdb_assert (next_frame->prev_func.status == CC_VALUE);

      *pc = next_frame->prev_func.addr;
      return true;
    }
}

CORE_ADDR
get_frame_func (const frame_info_ptr &this_frame)
{
  CORE_ADDR pc;

  if (!get_frame_func_if_available (this_frame, &pc))
    throw_error (NOT_AVAILABLE_ERROR, _("PC not available"));

  return pc;
}

std::unique_ptr<readonly_detached_regcache>
frame_save_as_regcache (const frame_info_ptr &this_frame)
{
  auto cooked_read = [this_frame] (int regnum, gdb::array_view<gdb_byte> buf)
    {
      if (!deprecated_frame_register_read (this_frame, regnum, buf.data ()))
	return REG_UNAVAILABLE;
      else
	return REG_VALID;
    };

  std::unique_ptr<readonly_detached_regcache> regcache
    (new readonly_detached_regcache (get_frame_arch (this_frame), cooked_read));

  return regcache;
}

void
frame_pop (const frame_info_ptr &this_frame)
{
  frame_info_ptr prev_frame;

  if (get_frame_type (this_frame) == DUMMY_FRAME)
    {
      /* Popping a dummy frame involves restoring more than just registers.
	 dummy_frame_pop does all the work.  */
      dummy_frame_pop (get_frame_id (this_frame), inferior_thread ());
      return;
    }

  /* Ensure that we have a frame to pop to.  */
  prev_frame = get_prev_frame_always (this_frame);

  if (!prev_frame)
    error (_("Cannot pop the initial frame."));

  /* Ignore TAILCALL_FRAME type frames, they were executed already before
     entering THISFRAME.  */
  prev_frame = skip_tailcall_frames (prev_frame);

  if (prev_frame == NULL)
    error (_("Cannot find the caller frame."));

  /* Make a copy of all the register values unwound from this frame.
     Save them in a scratch buffer so that there isn't a race between
     trying to extract the old values from the current regcache while
     at the same time writing new values into that same cache.  */
  std::unique_ptr<readonly_detached_regcache> scratch
    = frame_save_as_regcache (prev_frame);

  /* FIXME: cagney/2003-03-16: It should be possible to tell the
     target's register cache that it is about to be hit with a burst
     register transfer and that the sequence of register writes should
     be batched.  The pair target_prepare_to_store() and
     target_store_registers() kind of suggest this functionality.
     Unfortunately, they don't implement it.  Their lack of a formal
     definition can lead to targets writing back bogus values
     (arguably a bug in the target code mind).  */
  /* Now copy those saved registers into the current regcache.  */
  get_thread_regcache (inferior_thread ())->restore (scratch.get ());

  /* We've made right mess of GDB's local state, just discard
     everything.  */
  reinit_frame_cache ();
}

void
frame_register_unwind (const frame_info_ptr &next_frame, int regnum,
		       int *optimizedp, int *unavailablep,
		       enum lval_type *lvalp, CORE_ADDR *addrp,
		       int *realnump, gdb_byte *bufferp)
{
  struct value *value;

  /* Require all but BUFFERP to be valid.  A NULL BUFFERP indicates
     that the value proper does not need to be fetched.  */
  gdb_assert (optimizedp != NULL);
  gdb_assert (lvalp != NULL);
  gdb_assert (addrp != NULL);
  gdb_assert (realnump != NULL);
  /* gdb_assert (bufferp != NULL); */

  value = frame_unwind_register_value (next_frame, regnum);

  gdb_assert (value != NULL);

  *optimizedp = value->optimized_out ();
  *unavailablep = !value->entirely_available ();
  *lvalp = value->lval ();
  *addrp = value->address ();
  if (*lvalp == lval_register)
    *realnump = value->regnum ();
  else
    *realnump = -1;

  if (bufferp)
    {
      if (!*optimizedp && !*unavailablep)
	memcpy (bufferp, value->contents_all ().data (),
		value->type ()->length ());
      else
	memset (bufferp, 0, value->type ()->length ());
    }

  /* Dispose of the new value.  This prevents watchpoints from
     trying to watch the saved frame pointer.  */
  release_value (value);
}

void
frame_unwind_register (const frame_info_ptr &next_frame, int regnum, gdb_byte *buf)
{
  int optimized;
  int unavailable;
  CORE_ADDR addr;
  int realnum;
  enum lval_type lval;

  frame_register_unwind (next_frame, regnum, &optimized, &unavailable,
			 &lval, &addr, &realnum, buf);

  if (optimized)
    throw_error (OPTIMIZED_OUT_ERROR,
		 _("Register %d was not saved"), regnum);
  if (unavailable)
    throw_error (NOT_AVAILABLE_ERROR,
		 _("Register %d is not available"), regnum);
}

void
get_frame_register (const frame_info_ptr &frame,
		    int regnum, gdb_byte *buf)
{
  frame_unwind_register (frame_info_ptr (frame->next), regnum, buf);
}

struct value *
frame_unwind_register_value (const frame_info_ptr &next_frame, int regnum)
{
  FRAME_SCOPED_DEBUG_ENTER_EXIT;

  gdb_assert (next_frame != NULL);
  gdbarch *gdbarch = frame_unwind_arch (next_frame);
  frame_debug_printf ("frame=%d, regnum=%d(%s)",
		      next_frame->level, regnum,
		      user_reg_map_regnum_to_name (gdbarch, regnum));

  /* Find the unwinder.  */
  if (next_frame->unwind == NULL)
    frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache);

  /* Ask this frame to unwind its register.  */
  value *value
    = next_frame->unwind->prev_register (next_frame,
					 &next_frame->prologue_cache, regnum);
  if (value == nullptr)
    {
      if (gdbarch_pseudo_register_read_value_p (gdbarch))
	{
	  /* This is a pseudo register, we don't know how how what raw registers
	     this pseudo register is made of.  Ask the gdbarch to read the
	     value, it will itself ask the next frame to unwind the values of
	     the raw registers it needs to compose the value of the pseudo
	     register.  */
	  value = gdbarch_pseudo_register_read_value
	    (gdbarch, next_frame, regnum);
	}
      else if (gdbarch_pseudo_register_read_p (gdbarch))
	{
	  value = value::allocate_register (next_frame, regnum);

	  /* Passing the current regcache is known to be broken, the pseudo
	     register value will be constructed using the current raw registers,
	     rather than reading them using NEXT_FRAME.  Architectures should be
	     migrated to gdbarch_pseudo_register_read_value.  */
	  register_status status = gdbarch_pseudo_register_read
	    (gdbarch, get_thread_regcache (inferior_thread ()), regnum,
	     value->contents_writeable ().data ());
	  if (status == REG_UNAVAILABLE)
	    value->mark_bytes_unavailable (0, value->type ()->length ());
	}
      else
	error (_("Can't unwind value of register %d (%s)"), regnum,
	       user_reg_map_regnum_to_name (gdbarch, regnum));
    }

  if (frame_debug)
    {
      string_file debug_file;

      gdb_printf (&debug_file, "  ->");
      if (value->optimized_out ())
	{
	  gdb_printf (&debug_file, " ");
	  val_print_not_saved (&debug_file);
	}
      else
	{
	  if (value->lval () == lval_register)
	    gdb_printf (&debug_file, " register=%d", value->regnum ());
	  else if (value->lval () == lval_memory)
	    gdb_printf (&debug_file, " address=%s",
			paddress (gdbarch,
				  value->address ()));
	  else
	    gdb_printf (&debug_file, " computed");

	  if (value->lazy ())
	    gdb_printf (&debug_file, " lazy");
	  else if (value->entirely_available ())
	    {
	      int i;
	      gdb::array_view<const gdb_byte> buf = value->contents ();

	      gdb_printf (&debug_file, " bytes=");
	      gdb_printf (&debug_file, "[");
	      for (i = 0; i < register_size (gdbarch, regnum); i++)
		gdb_printf (&debug_file, "%02x", buf[i]);
	      gdb_printf (&debug_file, "]");
	    }
	  else if (value->entirely_unavailable ())
	    gdb_printf (&debug_file, " unavailable");
	  else
	    gdb_printf (&debug_file, " partly unavailable");
	}

      frame_debug_printf ("%s", debug_file.c_str ());
    }

  return value;
}

struct value *
get_frame_register_value (const frame_info_ptr &frame, int regnum)
{
  return frame_unwind_register_value (frame_info_ptr (frame->next), regnum);
}

LONGEST
frame_unwind_register_signed (const frame_info_ptr &next_frame, int regnum)
{
  struct gdbarch *gdbarch = frame_unwind_arch (next_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct value *value = frame_unwind_register_value (next_frame, regnum);

  gdb_assert (value != NULL);

  if (value->optimized_out ())
    {
      throw_error (OPTIMIZED_OUT_ERROR,
		   _("Register %d was not saved"), regnum);
    }
  if (!value->entirely_available ())
    {
      throw_error (NOT_AVAILABLE_ERROR,
		   _("Register %d is not available"), regnum);
    }

  LONGEST r = extract_signed_integer (value->contents_all (), byte_order);

  release_value (value);
  return r;
}

LONGEST
get_frame_register_signed (const frame_info_ptr &frame, int regnum)
{
  return frame_unwind_register_signed (frame_info_ptr (frame->next), regnum);
}

ULONGEST
frame_unwind_register_unsigned (const frame_info_ptr &next_frame, int regnum)
{
  struct gdbarch *gdbarch = frame_unwind_arch (next_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int size = register_size (gdbarch, regnum);
  struct value *value = frame_unwind_register_value (next_frame, regnum);

  gdb_assert (value != NULL);

  if (value->optimized_out ())
    {
      throw_error (OPTIMIZED_OUT_ERROR,
		   _("Register %d was not saved"), regnum);
    }
  if (!value->entirely_available ())
    {
      throw_error (NOT_AVAILABLE_ERROR,
		   _("Register %d is not available"), regnum);
    }

  ULONGEST r = extract_unsigned_integer (value->contents_all ().data (),
					 size, byte_order);

  release_value (value);
  return r;
}

ULONGEST
get_frame_register_unsigned (const frame_info_ptr &frame, int regnum)
{
  return frame_unwind_register_unsigned (frame_info_ptr (frame->next), regnum);
}

bool
read_frame_register_unsigned (const frame_info_ptr &frame, int regnum,
			      ULONGEST *val)
{
  struct value *regval = get_frame_register_value (frame, regnum);

  if (!regval->optimized_out ()
      && regval->entirely_available ())
    {
      struct gdbarch *gdbarch = get_frame_arch (frame);
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
      int size = register_size (gdbarch, regval->regnum ());

      *val = extract_unsigned_integer (regval->contents ().data (), size,
				       byte_order);
      return true;
    }

  return false;
}

void
put_frame_register (const frame_info_ptr &next_frame, int regnum,
		     gdb::array_view<const gdb_byte> buf)
{
  gdbarch *gdbarch = frame_unwind_arch (next_frame);
  int realnum;
  int optim;
  int unavail;
  enum lval_type lval;
  CORE_ADDR addr;
  int size = register_size (gdbarch, regnum);

  gdb_assert (buf.size () == size);

  frame_register_unwind (next_frame, regnum, &optim, &unavail, &lval, &addr,
			 &realnum, nullptr);
  if (optim)
    error (_("Attempt to assign to a register that was not saved."));
  switch (lval)
    {
    case lval_memory:
      {
	write_memory (addr, buf.data (), size);
	break;
      }
    case lval_register:
      /* Not sure if that's always true... but we have a problem if not.  */
      gdb_assert (size == register_size (gdbarch, realnum));

      if (realnum < gdbarch_num_regs (gdbarch)
	  || !gdbarch_pseudo_register_write_p (gdbarch))
	get_thread_regcache (inferior_thread ())->cooked_write (realnum, buf);
      else
	gdbarch_pseudo_register_write (gdbarch, next_frame, realnum, buf);
      break;
    default:
      error (_("Attempt to assign to an unmodifiable value."));
    }
}

/* This function is deprecated.  Use get_frame_register_value instead,
   which provides more accurate information.

   Find and return the value of REGNUM for the specified stack frame.
   The number of bytes copied is REGISTER_SIZE (REGNUM).

   Returns 0 if the register value could not be found.  */

bool
deprecated_frame_register_read (const frame_info_ptr &frame, int regnum,
				gdb_byte *myaddr)
{
  int optimized;
  int unavailable;
  enum lval_type lval;
  CORE_ADDR addr;
  int realnum;

  frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum,
			 &optimized, &unavailable, &lval, &addr, &realnum,
			 myaddr);

  return !optimized && !unavailable;
}

bool
get_frame_register_bytes (const frame_info_ptr &next_frame, int regnum,
			  CORE_ADDR offset, gdb::array_view<gdb_byte> buffer,
			  int *optimizedp, int *unavailablep)
{
  gdbarch *gdbarch = frame_unwind_arch (next_frame);

  /* Skip registers wholly inside of OFFSET.  */
  while (offset >= register_size (gdbarch, regnum))
    {
      offset -= register_size (gdbarch, regnum);
      regnum++;
    }

  /* Ensure that we will not read beyond the end of the register file.
     This can only ever happen if the debug information is bad.  */
  int maxsize = -offset;
  int numregs = gdbarch_num_cooked_regs (gdbarch);
  for (int i = regnum; i < numregs; i++)
    {
      int thissize = register_size (gdbarch, i);

      if (thissize == 0)
	break;	/* This register is not available on this architecture.  */
      maxsize += thissize;
    }

  if (buffer.size () > maxsize)
    error (_("Bad debug information detected: "
	     "Attempt to read %zu bytes from registers."), buffer.size ());

  /* Copy the data.  */
  while (!buffer.empty ())
    {
      int curr_len = std::min<int> (register_size (gdbarch, regnum) - offset,
				    buffer.size ());

      if (curr_len == register_size (gdbarch, regnum))
	{
	  enum lval_type lval;
	  CORE_ADDR addr;
	  int realnum;

	  frame_register_unwind (next_frame, regnum, optimizedp, unavailablep,
				 &lval, &addr, &realnum, buffer.data ());
	  if (*optimizedp || *unavailablep)
	    return false;
	}
      else
	{
	  value *value = frame_unwind_register_value (next_frame, regnum);
	  gdb_assert (value != NULL);
	  *optimizedp = value->optimized_out ();
	  *unavailablep = !value->entirely_available ();

	  if (*optimizedp || *unavailablep)
	    {
	      release_value (value);
	      return false;
	    }

	  copy (value->contents_all ().slice (offset, curr_len),
		buffer.slice (0, curr_len));
	  release_value (value);
	}

      buffer = buffer.slice (curr_len);
      offset = 0;
      regnum++;
    }

  *optimizedp = 0;
  *unavailablep = 0;

  return true;
}

void
put_frame_register_bytes (const frame_info_ptr &next_frame, int regnum,
			  CORE_ADDR offset,
			  gdb::array_view<const gdb_byte> buffer)
{
  gdbarch *gdbarch = frame_unwind_arch (next_frame);

  /* Skip registers wholly inside of OFFSET.  */
  while (offset >= register_size (gdbarch, regnum))
    {
      offset -= register_size (gdbarch, regnum);
      regnum++;
    }

  /* Copy the data.  */
  while (!buffer.empty ())
    {
      int curr_len = std::min<int> (register_size (gdbarch, regnum) - offset,
				    buffer.size ());

      if (curr_len == register_size (gdbarch, regnum))
	put_frame_register (next_frame, regnum, buffer.slice (0, curr_len));
      else
	{
	  value *value = frame_unwind_register_value (next_frame, regnum);
	  gdb_assert (value != nullptr);

	  copy (buffer.slice (0, curr_len),
		value->contents_writeable ().slice (offset, curr_len));
	  put_frame_register (next_frame, regnum, value->contents_raw ());
	  release_value (value);
	}

      buffer = buffer.slice (curr_len);
      offset = 0;
      regnum++;
    }
}

/* Create a sentinel frame.

   See frame_id_build_sentinel for the description of STACK_ADDR and
   CODE_ADDR.  */

static frame_info_ptr
create_sentinel_frame (program_space *pspace, address_space *aspace,
		       regcache *regcache, CORE_ADDR stack_addr,
		       CORE_ADDR code_addr)
{
  frame_info *frame = FRAME_OBSTACK_ZALLOC (struct frame_info);

  frame->level = -1;
  frame->pspace = pspace;
  frame->aspace = aspace;
  /* Explicitly initialize the sentinel frame's cache.  Provide it
     with the underlying regcache.  In the future additional
     information, such as the frame's thread will be added.  */
  frame->prologue_cache = sentinel_frame_cache (regcache);
  /* For the moment there is only one sentinel frame implementation.  */
  frame->unwind = &sentinel_frame_unwind;
  /* Link this frame back to itself.  The frame is self referential
     (the unwound PC is the same as the pc), so make it so.  */
  frame->next = frame;
  /* The sentinel frame has a special ID.  */
  frame->this_id.p = frame_id_status::COMPUTED;
  frame->this_id.value = frame_id_build_sentinel (stack_addr, code_addr);

  bool added = frame_stash_add (frame);
  gdb_assert (added);

  frame_debug_printf ("  -> %s", frame->to_string ().c_str ());

  return frame_info_ptr (frame);
}

/* Cache for frame addresses already read by gdb.  Valid only while
   inferior is stopped.  Control variables for the frame cache should
   be local to this module.  */

static struct obstack frame_cache_obstack;

void *
frame_obstack_zalloc (unsigned long size)
{
  void *data = obstack_alloc (&frame_cache_obstack, size);

  memset (data, 0, size);
  return data;
}

static frame_info_ptr get_prev_frame_always_1 (const frame_info_ptr &this_frame);

frame_info_ptr
get_current_frame (void)
{
  frame_info_ptr current_frame;

  /* First check, and report, the lack of registers.  Having GDB
     report "No stack!" or "No memory" when the target doesn't even
     have registers is very confusing.  Besides, "printcmd.exp"
     explicitly checks that ``print $pc'' with no registers prints "No
     registers".  */
  if (!target_has_registers ())
    error (_("No registers."));
  if (!target_has_stack ())
    error (_("No stack."));
  if (!target_has_memory ())
    error (_("No memory."));
  /* Traceframes are effectively a substitute for the live inferior.  */
  if (get_traceframe_number () < 0)
    validate_registers_access ();

  if (sentinel_frame == NULL)
    sentinel_frame =
      create_sentinel_frame (current_program_space,
			     current_inferior ()->aspace.get (),
			     get_thread_regcache (inferior_thread ()),
			     0, 0).get ();

  /* Set the current frame before computing the frame id, to avoid
     recursion inside compute_frame_id, in case the frame's
     unwinder decides to do a symbol lookup (which depends on the
     selected frame's block).

     This call must always succeed.  In particular, nothing inside
     get_prev_frame_always_1 should try to unwind from the
     sentinel frame, because that could fail/throw, and we always
     want to leave with the current frame created and linked in --
     we should never end up with the sentinel frame as outermost
     frame.  */
  current_frame = get_prev_frame_always_1 (frame_info_ptr (sentinel_frame));
  gdb_assert (current_frame != NULL);

  return current_frame;
}

/* The "selected" stack frame is used by default for local and arg
   access.

   The "single source of truth" for the selected frame is the
   SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL pair.

   Frame IDs can be saved/restored across reinitializing the frame
   cache, while frame_info pointers can't (frame_info objects are
   invalidated).  If we know the corresponding frame_info object, it
   is cached in SELECTED_FRAME.

   If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
   and the target has stack and is stopped, the selected frame is the
   current (innermost) target frame.  SELECTED_FRAME_ID is never the ID
   of the current (innermost) target frame.  SELECTED_FRAME_LEVEL may
   only be 0 if the selected frame is a user-created one (created and
   selected through the "select-frame view" command), in which case
   SELECTED_FRAME_ID is the frame id derived from the user-provided
   addresses.

   If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
   and the target has no stack or is executing, then there's no
   selected frame.  */
static frame_id selected_frame_id = null_frame_id;
static int selected_frame_level = -1;

/* See frame.h.  This definition should come before any definition of a static
   frame_info_ptr, to ensure that frame_list is destroyed after any static
   frame_info_ptr.  This is necessary because the destructor of frame_info_ptr
   uses frame_list.  */

intrusive_list<frame_info_ptr> frame_info_ptr::frame_list;

/* The cached frame_info object pointing to the selected frame.
   Looked up on demand by get_selected_frame.  */
static frame_info_ptr selected_frame;

/* See frame.h.  */

void
save_selected_frame (frame_id *frame_id, int *frame_level)
  noexcept
{
  *frame_id = selected_frame_id;
  *frame_level = selected_frame_level;
}

/* See frame.h.  */

void
restore_selected_frame (frame_id frame_id, int frame_level)
  noexcept
{
  /* Unless it is a user-created frame, save_selected_frame never returns
     level == 0, so we shouldn't see it here either.  */
  gdb_assert (frame_level != 0 || frame_id.user_created_p);

  /* FRAME_ID can be null_frame_id only IFF frame_level is -1.  */
  gdb_assert ((frame_level == -1 && !frame_id_p (frame_id))
	      || (frame_level != -1 && frame_id_p (frame_id)));

  selected_frame_id = frame_id;
  selected_frame_level = frame_level;

  /* Will be looked up later by get_selected_frame.  */
  selected_frame = nullptr;
}

/* Lookup the frame_info object for the selected frame FRAME_ID /
   FRAME_LEVEL and cache the result.

   If FRAME_LEVEL > 0 and the originally selected frame isn't found,
   warn and select the innermost (current) frame.  */

static void
lookup_selected_frame (struct frame_id a_frame_id, int frame_level)
{
  frame_info_ptr frame = NULL;
  int count;

  /* This either means there was no selected frame, or the selected
     frame was the current frame.  In either case, select the current
     frame.  */
  if (frame_level == -1)
    {
      select_frame (get_current_frame ());
      return;
    }

  /* This means the selected frame was a user-created one.  Create a new one
     using the user-provided addresses, which happen to be in the frame id.  */
  if (frame_level == 0)
    {
      gdb_assert (a_frame_id.user_created_p);
      select_frame (create_new_frame (a_frame_id));
      return;
    }

  /* select_frame never saves 0 in SELECTED_FRAME_LEVEL, so we
     shouldn't see it here.  */
  gdb_assert (frame_level > 0);

  /* Restore by level first, check if the frame id is the same as
     expected.  If that fails, try restoring by frame id.  If that
     fails, nothing to do, just warn the user.  */

  count = frame_level;
  frame = find_relative_frame (get_current_frame (), &count);
  if (count == 0
      && frame != NULL
      /* The frame ids must match - either both valid or both
	 outer_frame_id.  The latter case is not failsafe, but since
	 it's highly unlikely the search by level finds the wrong
	 frame, it's 99.9(9)% of the time (for all practical purposes)
	 safe.  */
      && get_frame_id (frame) == a_frame_id)
    {
      /* Cool, all is fine.  */
      select_frame (frame);
      return;
    }

  frame = frame_find_by_id (a_frame_id);
  if (frame != NULL)
    {
      /* Cool, refound it.  */
      select_frame (frame);
      return;
    }

  /* Nothing else to do, the frame layout really changed.  Select the
     innermost stack frame.  */
  select_frame (get_current_frame ());

  /* Warn the user.  */
  if (frame_level > 0 && !current_uiout->is_mi_like_p ())
    {
      warning (_("Couldn't restore frame #%d in "
		 "current thread.  Bottom (innermost) frame selected:"),
	       frame_level);
      /* For MI, we should probably have a notification about current
	 frame change.  But this error is not very likely, so don't
	 bother for now.  */
      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
    }
}

bool
has_stack_frames ()
{
  if (!target_has_registers () || !target_has_stack ()
      || !target_has_memory ())
    return false;

  /* Traceframes are effectively a substitute for the live inferior.  */
  if (get_traceframe_number () < 0)
    {
      /* No current inferior, no frame.  */
      if (inferior_ptid == null_ptid)
	return false;

      thread_info *tp = inferior_thread ();
      /* Don't try to read from a dead thread.  */
      if (tp->state == THREAD_EXITED)
	return false;

      /* ... or from a spinning thread.  */
      if (tp->executing ())
	return false;
    }

  return true;
}

/* See frame.h.  */

frame_info_ptr
get_selected_frame (const char *message)
{
  if (selected_frame == NULL)
    {
      if (message != NULL && !has_stack_frames ())
	error (("%s"), message);

      lookup_selected_frame (selected_frame_id, selected_frame_level);
    }
  /* There is always a frame.  */
  gdb_assert (selected_frame != NULL);
  return selected_frame;
}

/* This is a variant of get_selected_frame() which can be called when
   the inferior does not have a frame; in that case it will return
   NULL instead of calling error().  */

frame_info_ptr
deprecated_safe_get_selected_frame (void)
{
  if (!has_stack_frames ())
    return NULL;
  return get_selected_frame (NULL);
}

/* Invalidate the selected frame.  */

static void
invalidate_selected_frame ()
{
  selected_frame = nullptr;
  selected_frame_level = -1;
  selected_frame_id = null_frame_id;
}

/* See frame.h.  */

void
select_frame (const frame_info_ptr &fi)
{
  gdb_assert (fi != nullptr);

  selected_frame = fi;
  selected_frame_level = frame_relative_level (fi);

  /* If the frame is a user-created one, save its level and frame id just like
     any other non-level-0 frame.  */
  if (selected_frame_level == 0 && !fi->this_id.value.user_created_p)
    {
      /* Treat the current frame especially -- we want to always
	 save/restore it without warning, even if the frame ID changes
	 (see lookup_selected_frame).  E.g.:

	  // The current frame is selected, the target had just stopped.
	  {
	    scoped_restore_selected_frame restore_frame;
	    some_operation_that_changes_the_stack ();
	  }
	  // scoped_restore_selected_frame's dtor runs, but the
	  // original frame_id can't be found.  No matter whether it
	  // is found or not, we still end up with the now-current
	  // frame selected.  Warning in lookup_selected_frame in this
	  // case seems pointless.

	 Also get_frame_id may access the target's registers/memory,
	 and thus skipping get_frame_id optimizes the common case.

	 Saving the selected frame this way makes get_selected_frame
	 and restore_current_frame return/re-select whatever frame is
	 the innermost (current) then.  */
      selected_frame_level = -1;
      selected_frame_id = null_frame_id;
    }
  else
    selected_frame_id = get_frame_id (fi);

  /* NOTE: cagney/2002-05-04: FI can be NULL.  This occurs when the
     frame is being invalidated.  */

  /* FIXME: kseitz/2002-08-28: It would be nice to call
     selected_frame_level_changed_event() right here, but due to limitations
     in the current interfaces, we would end up flooding UIs with events
     because select_frame() is used extensively internally.

     Once we have frame-parameterized frame (and frame-related) commands,
     the event notification can be moved here, since this function will only
     be called when the user's selected frame is being changed.  */

  /* Ensure that symbols for this frame are read in.  Also, determine the
     source language of this frame, and switch to it if desired.  */
  if (fi)
    {
      CORE_ADDR pc;

      /* We retrieve the frame's symtab by using the frame PC.
	 However we cannot use the frame PC as-is, because it usually
	 points to the instruction following the "call", which is
	 sometimes the first instruction of another function.  So we
	 rely on get_frame_address_in_block() which provides us with a
	 PC which is guaranteed to be inside the frame's code
	 block.  */
      if (get_frame_address_in_block_if_available (fi, &pc))
	{
	  struct compunit_symtab *cust = find_pc_compunit_symtab (pc);

	  if (cust != NULL
	      && cust->language () != current_language->la_language
	      && cust->language () != language_unknown
	      && language_mode == language_mode_auto)
	    set_language (cust->language ());
	}
    }
}

/* Create an arbitrary (i.e. address specified by user) or innermost frame.
   Always returns a non-NULL value.  */

static frame_info_ptr
create_new_frame (frame_id id)
{
  gdb_assert (id.user_created_p);
  gdb_assert (id.stack_status == frame_id_stack_status::FID_STACK_VALID);
  gdb_assert (id.code_addr_p);

  frame_debug_printf ("stack_addr=%s, core_addr=%s",
		      hex_string (id.stack_addr), hex_string (id.code_addr));

  /* Avoid creating duplicate frames, search for an existing frame with that id
     in the stash.  */
  frame_info_ptr frame = frame_stash_find (id);
  if (frame != nullptr)
    return frame;

  frame_info *fi = FRAME_OBSTACK_ZALLOC (struct frame_info);

  fi->next = create_sentinel_frame (current_program_space,
				    current_inferior ()->aspace.get (),
				    get_thread_regcache (inferior_thread ()),
				    id.stack_addr, id.code_addr).get ();

  /* Set/update this frame's cached PC value, found in the next frame.
     Do this before looking for this frame's unwinder.  A sniffer is
     very likely to read this, and the corresponding unwinder is
     entitled to rely that the PC doesn't magically change.  */
  fi->next->prev_pc.value = id.code_addr;
  fi->next->prev_pc.status = CC_VALUE;

  /* We currently assume that frame chain's can't cross spaces.  */
  fi->pspace = fi->next->pspace;
  fi->aspace = fi->next->aspace;

  /* Select/initialize both the unwind function and the frame's type
     based on the PC.  */
  frame_unwind_find_by_frame (frame_info_ptr (fi), &fi->prologue_cache);

  fi->this_id.p = frame_id_status::COMPUTED;
  fi->this_id.value = id;

  bool added = frame_stash_add (fi);
  gdb_assert (added);

  frame_debug_printf ("  -> %s", fi->to_string ().c_str ());

  return frame_info_ptr (fi);
}

frame_info_ptr
create_new_frame (CORE_ADDR stack, CORE_ADDR pc)
{
  frame_id id = frame_id_build (stack, pc);
  id.user_created_p = 1;

  return create_new_frame (id);
}

/* Return the frame that THIS_FRAME calls (NULL if THIS_FRAME is the
   innermost frame).  Be careful to not fall off the bottom of the
   frame chain and onto the sentinel frame.  */

frame_info_ptr
get_next_frame (const frame_info_ptr &this_frame)
{
  if (this_frame->level > 0)
    return frame_info_ptr (this_frame->next);
  else
    return NULL;
}

/* Return the frame that THIS_FRAME calls.  If THIS_FRAME is the
   innermost (i.e. current) frame, return the sentinel frame.  Thus,
   unlike get_next_frame(), NULL will never be returned.  */

frame_info_ptr
get_next_frame_sentinel_okay (const frame_info_ptr &this_frame)
{
  gdb_assert (this_frame != NULL);

  /* Note that, due to the manner in which the sentinel frame is
     constructed, this_frame->next still works even when this_frame
     is the sentinel frame.  But we disallow it here anyway because
     calling get_next_frame_sentinel_okay() on the sentinel frame
     is likely a coding error.  */
  if (this_frame->this_id.p == frame_id_status::COMPUTED)
    gdb_assert (!is_sentinel_frame_id (this_frame->this_id.value));

  return frame_info_ptr (this_frame->next);
}

/* Observer for the target_changed event.  */

static void
frame_observer_target_changed (struct target_ops *target)
{
  reinit_frame_cache ();
}

/* Flush the entire frame cache.  */

void
reinit_frame_cache (void)
{
  ++frame_cache_generation;

  if (htab_elements (frame_stash) > 0)
    annotate_frames_invalid ();

  invalidate_selected_frame ();

  /* Invalidate cache.  */
  if (sentinel_frame != nullptr)
    {
      /* If frame 0's id is not computed, it is not in the frame stash, so its
	 dealloc functions will not be called when emptying the frame stash.
	 Call frame_info_del manually in that case.  */
      frame_info *current_frame = sentinel_frame->prev;
      if (current_frame != nullptr
	  && current_frame->this_id.p == frame_id_status::NOT_COMPUTED)
	frame_info_del (current_frame);

      sentinel_frame = nullptr;
    }

  frame_stash_invalidate ();

  /* Since we can't really be sure what the first object allocated was.  */
  obstack_free (&frame_cache_obstack, 0);
  obstack_init (&frame_cache_obstack);

  for (frame_info_ptr &iter : frame_info_ptr::frame_list)
    iter.invalidate ();

  frame_debug_printf ("generation=%d", frame_cache_generation);
}

/* Find where a register is saved (in memory or another register).
   The result of frame_register_unwind is just where it is saved
   relative to this particular frame.  */

static void
frame_register_unwind_location (const frame_info_ptr &initial_this_frame,
				int regnum, int *optimizedp, lval_type *lvalp,
				CORE_ADDR *addrp, int *realnump)
{
  gdb_assert (initial_this_frame == nullptr || initial_this_frame->level >= 0);

  frame_info_ptr this_frame = initial_this_frame;
  while (this_frame != NULL)
    {
      int unavailable;

      frame_register_unwind (this_frame, regnum, optimizedp, &unavailable,
			     lvalp, addrp, realnump, NULL);

      if (*optimizedp)
	break;

      if (*lvalp != lval_register)
	break;

      regnum = *realnump;
      this_frame = get_next_frame (this_frame);
    }
}

/* Get the previous raw frame, and check that it is not identical to
   same other frame frame already in the chain.  If it is, there is
   most likely a stack cycle, so we discard it, and mark THIS_FRAME as
   outermost, with UNWIND_SAME_ID stop reason.  Unlike the other
   validity tests, that compare THIS_FRAME and the next frame, we do
   this right after creating the previous frame, to avoid ever ending
   up with two frames with the same id in the frame chain.

   There is however, one case where this cycle detection is not desirable,
   when asking for the previous frame of an inline frame, in this case, if
   the previous frame is a duplicate and we return nullptr then we will be
   unable to calculate the frame_id of the inline frame, this in turn
   causes inline_frame_this_id() to fail.  So for inline frames (and only
   for inline frames), the previous frame will always be returned, even when it
   has a duplicate frame_id.  We're not worried about cycles in the frame
   chain as, if the previous frame returned here has a duplicate frame_id,
   then the frame_id of the inline frame, calculated based off the frame_id
   of the previous frame, should also be a duplicate.  */

static frame_info_ptr
get_prev_frame_maybe_check_cycle (const frame_info_ptr &this_frame)
{
  frame_info_ptr prev_frame = get_prev_frame_raw (this_frame);

  /* Don't compute the frame id of the current frame yet.  Unwinding
     the sentinel frame can fail (e.g., if the thread is gone and we
     can't thus read its registers).  If we let the cycle detection
     code below try to compute a frame ID, then an error thrown from
     within the frame ID computation would result in the sentinel
     frame as outermost frame, which is bogus.  Instead, we'll compute
     the current frame's ID lazily in get_frame_id.  Note that there's
     no point in doing cycle detection when there's only one frame, so
     nothing is lost here.  */
  if (prev_frame->level == 0)
    return prev_frame;

  unsigned int entry_generation = get_frame_cache_generation ();

  try
    {
      compute_frame_id (prev_frame);

      bool cycle_detection_p = get_frame_type (this_frame) != INLINE_FRAME;

      /* This assert checks GDB's state with respect to calculating the
	 frame-id of THIS_FRAME, in the case where THIS_FRAME is an inline
	 frame.

	 If THIS_FRAME is frame #0, and is an inline frame, then we put off
	 calculating the frame_id until we specifically make a call to
	 get_frame_id().  As a result we can enter this function in two
	 possible states.  If GDB asked for the previous frame of frame #0
	 then THIS_FRAME will be frame #0 (an inline frame), and the
	 frame_id will be in the NOT_COMPUTED state.  However, if GDB asked
	 for the frame_id of frame #0, then, as getting the frame_id of an
	 inline frame requires us to get the frame_id of the previous
	 frame, we will still end up in here, and the frame_id status will
	 be COMPUTING.

	 If, instead, THIS_FRAME is at a level greater than #0 then things
	 are simpler.  For these frames we immediately compute the frame_id
	 when the frame is initially created, and so, for those frames, we
	 will always enter this function with the frame_id status of
	 COMPUTING.  */
      gdb_assert (cycle_detection_p
		  || (this_frame->level > 0
		      && (this_frame->this_id.p
			  == frame_id_status::COMPUTING))
		  || (this_frame->level == 0
		      && (this_frame->this_id.p
			  != frame_id_status::COMPUTED)));

      /* We must do the CYCLE_DETECTION_P check after attempting to add
	 PREV_FRAME into the cache; if PREV_FRAME is unique then we do want
	 it in the cache, but if it is a duplicate and CYCLE_DETECTION_P is
	 false, then we don't want to unlink it.  */
      if (!frame_stash_add (prev_frame.get ()) && cycle_detection_p)
	{
	  /* Another frame with the same id was already in the stash.  We just
	     detected a cycle.  */
	  frame_debug_printf ("  -> nullptr // this frame has same ID");

	  this_frame->stop_reason = UNWIND_SAME_ID;
	  /* Unlink.  */
	  prev_frame->next = NULL;
	  this_frame->prev = NULL;
	  prev_frame = NULL;
	}
    }
  catch (const gdb_exception &ex)
    {
      if (get_frame_cache_generation () == entry_generation)
	{
	  prev_frame->next = NULL;
	  this_frame->prev = NULL;
	}

      throw;
    }

  return prev_frame;
}

/* Helper function for get_prev_frame_always, this is called inside a
   TRY_CATCH block.  Return the frame that called THIS_FRAME or NULL if
   there is no such frame.  This may throw an exception.  */

static frame_info_ptr
get_prev_frame_always_1 (const frame_info_ptr &this_frame)
{
  FRAME_SCOPED_DEBUG_ENTER_EXIT;

  gdb_assert (this_frame != NULL);

  if (frame_debug)
    {
      if (this_frame != NULL)
	frame_debug_printf ("this_frame=%d", this_frame->level);
      else
	frame_debug_printf ("this_frame=nullptr");
    }

  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  /* Only try to do the unwind once.  */
  if (this_frame->prev_p)
    {
      if (this_frame->prev != nullptr)
	frame_debug_printf ("  -> %s // cached",
			    this_frame->prev->to_string ().c_str ());
      else
	frame_debug_printf
	  ("  -> nullptr // %s // cached",
	   frame_stop_reason_symbol_string (this_frame->stop_reason));
      return frame_info_ptr (this_frame->prev);
    }

  /* If the frame unwinder hasn't been selected yet, we must do so
     before setting prev_p; otherwise the check for misbehaved
     sniffers will think that this frame's sniffer tried to unwind
     further (see frame_cleanup_after_sniffer).  */
  if (this_frame->unwind == NULL)
    frame_unwind_find_by_frame (this_frame, &this_frame->prologue_cache);

  this_frame->prev_p = true;
  this_frame->stop_reason = UNWIND_NO_REASON;

  /* If we are unwinding from an inline frame, all of the below tests
     were already performed when we unwound from the next non-inline
     frame.  We must skip them, since we can not get THIS_FRAME's ID
     until we have unwound all the way down to the previous non-inline
     frame.  */
  if (get_frame_type (this_frame) == INLINE_FRAME)
    return get_prev_frame_maybe_check_cycle (this_frame);

  /* If this_frame is the current frame, then compute and stash its
     frame id prior to fetching and computing the frame id of the
     previous frame.  Otherwise, the cycle detection code in
     get_prev_frame_if_no_cycle() will not work correctly.  When
     get_frame_id() is called later on, an assertion error will be
     triggered in the event of a cycle between the current frame and
     its previous frame.

     Note we do this after the INLINE_FRAME check above.  That is
     because the inline frame's frame id computation needs to fetch
     the frame id of its previous real stack frame.  I.e., we need to
     avoid recursion in that case.  This is OK since we're sure the
     inline frame won't create a cycle with the real stack frame.  See
     inline_frame_this_id.  */
  if (this_frame->level == 0)
    get_frame_id (this_frame);

  /* Check that this frame is unwindable.  If it isn't, don't try to
     unwind to the prev frame.  */
  this_frame->stop_reason
    = this_frame->unwind->stop_reason (this_frame,
				       &this_frame->prologue_cache);

  if (this_frame->stop_reason != UNWIND_NO_REASON)
    {
      frame_debug_printf
	("  -> nullptr // %s",
	 frame_stop_reason_symbol_string (this_frame->stop_reason));
      return NULL;
    }

  /* Check that this frame's ID isn't inner to (younger, below, next)
     the next frame.  This happens when a frame unwind goes backwards.
     This check is valid only if this frame and the next frame are NORMAL.
     See the comment at frame_id_inner for details.  */
  if (get_frame_type (this_frame) == NORMAL_FRAME
      && this_frame->next->unwind->type == NORMAL_FRAME
      && frame_id_inner (get_frame_arch (frame_info_ptr (this_frame->next)),
			 get_frame_id (this_frame),
			 get_frame_id (frame_info_ptr (this_frame->next))))
    {
      CORE_ADDR this_pc_in_block;
      struct minimal_symbol *morestack_msym;
      const char *morestack_name = NULL;

      /* gcc -fsplit-stack __morestack can continue the stack anywhere.  */
      this_pc_in_block = get_frame_address_in_block (this_frame);
      morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block).minsym;
      if (morestack_msym)
	morestack_name = morestack_msym->linkage_name ();
      if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)
	{
	  frame_debug_printf ("  -> nullptr // this frame ID is inner");
	  this_frame->stop_reason = UNWIND_INNER_ID;
	  return NULL;
	}
    }

  /* Check that this and the next frame do not unwind the PC register
     to the same memory location.  If they do, then even though they
     have different frame IDs, the new frame will be bogus; two
     functions can't share a register save slot for the PC.  This can
     happen when the prologue analyzer finds a stack adjustment, but
     no PC save.

     This check does assume that the "PC register" is roughly a
     traditional PC, even if the gdbarch_unwind_pc method adjusts
     it (we do not rely on the value, only on the unwound PC being
     dependent on this value).  A potential improvement would be
     to have the frame prev_pc method and the gdbarch unwind_pc
     method set the same lval and location information as
     frame_register_unwind.  */
  if (this_frame->level > 0
      && gdbarch_pc_regnum (gdbarch) >= 0
      && get_frame_type (this_frame) == NORMAL_FRAME
      && (get_frame_type (frame_info_ptr (this_frame->next)) == NORMAL_FRAME
	  || get_frame_type (frame_info_ptr (this_frame->next)) == INLINE_FRAME))
    {
      int optimized, realnum, nrealnum;
      enum lval_type lval, nlval;
      CORE_ADDR addr, naddr;

      frame_register_unwind_location (this_frame,
				      gdbarch_pc_regnum (gdbarch),
				      &optimized, &lval, &addr, &realnum);
      frame_register_unwind_location (get_next_frame (this_frame),
				      gdbarch_pc_regnum (gdbarch),
				      &optimized, &nlval, &naddr, &nrealnum);

      if ((lval == lval_memory && lval == nlval && addr == naddr)
	  || (lval == lval_register && lval == nlval && realnum == nrealnum))
	{
	  frame_debug_printf ("  -> nullptr // no saved PC");
	  this_frame->stop_reason = UNWIND_NO_SAVED_PC;
	  this_frame->prev = NULL;
	  return NULL;
	}
    }

  /* Ensure we can unwind the program counter of THIS_FRAME.  */
  try
    {
      /* Calling frame_unwind_pc for the sentinel frame relies on the
	 current_frame being set, which at this point it might not be if we
	 are in the process of setting the current_frame after a stop (see
	 get_current_frame).

	 The point of this check is to ensure that the unwinder for
	 THIS_FRAME can actually unwind the $pc, which we assume the
	 sentinel frame unwinder can always do (it's just a read from the
	 machine state), so we only call frame_unwind_pc for frames other
	 than the sentinel (level -1) frame.

	 Additionally, we don't actually care about the value of the
	 unwound $pc, just that the call completed successfully.  */
      if (this_frame->level >= 0)
	frame_unwind_pc (this_frame);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == NOT_AVAILABLE_ERROR || ex.error == OPTIMIZED_OUT_ERROR)
	{
	  frame_debug_printf ("  -> nullptr // no saved PC");
	  this_frame->stop_reason = UNWIND_NO_SAVED_PC;
	  this_frame->prev = nullptr;
	  return nullptr;
	}

      throw;
    }

  return get_prev_frame_maybe_check_cycle (this_frame);
}

/* Return a "struct frame_info" corresponding to the frame that called
   THIS_FRAME.  Returns NULL if there is no such frame.

   Unlike get_prev_frame, this function always tries to unwind the
   frame.  */

frame_info_ptr
get_prev_frame_always (const frame_info_ptr &this_frame)
{
  frame_info_ptr prev_frame = NULL;

  try
    {
      prev_frame = get_prev_frame_always_1 (this_frame);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == MEMORY_ERROR)
	{
	  this_frame->stop_reason = UNWIND_MEMORY_ERROR;
	  if (ex.message != NULL)
	    {
	      char *stop_string;
	      size_t size;

	      /* The error needs to live as long as the frame does.
		 Allocate using stack local STOP_STRING then assign the
		 pointer to the frame, this allows the STOP_STRING on the
		 frame to be of type 'const char *'.  */
	      size = ex.message->size () + 1;
	      stop_string = (char *) frame_obstack_zalloc (size);
	      memcpy (stop_string, ex.what (), size);
	      this_frame->stop_string = stop_string;
	    }
	  prev_frame = NULL;
	}
      else
	throw;
    }

  return prev_frame;
}

/* Construct a new "struct frame_info" and link it previous to
   this_frame.  */

static frame_info_ptr
get_prev_frame_raw (const frame_info_ptr &this_frame)
{
  frame_info *prev_frame;

  /* Allocate the new frame but do not wire it in to the frame chain.
     Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along
     frame->next to pull some fancy tricks (of course such code is, by
     definition, recursive).  Try to prevent it.

     There is no reason to worry about memory leaks, should the
     remainder of the function fail.  The allocated memory will be
     quickly reclaimed when the frame cache is flushed, and the `we've
     been here before' check above will stop repeated memory
     allocation calls.  */
  prev_frame = FRAME_OBSTACK_ZALLOC (struct frame_info);
  prev_frame->level = this_frame->level + 1;

  /* For now, assume we don't have frame chains crossing address
     spaces.  */
  prev_frame->pspace = this_frame->pspace;
  prev_frame->aspace = this_frame->aspace;

  /* Don't yet compute ->unwind (and hence ->type).  It is computed
     on-demand in get_frame_type, frame_register_unwind, and
     get_frame_id.  */

  /* Don't yet compute the frame's ID.  It is computed on-demand by
     get_frame_id().  */

  /* The unwound frame ID is validate at the start of this function,
     as part of the logic to decide if that frame should be further
     unwound, and not here while the prev frame is being created.
     Doing this makes it possible for the user to examine a frame that
     has an invalid frame ID.

     Some very old VAX code noted: [...]  For the sake of argument,
     suppose that the stack is somewhat trashed (which is one reason
     that "info frame" exists).  So, return 0 (indicating we don't
     know the address of the arglist) if we don't know what frame this
     frame calls.  */

  /* Link it in.  */
  this_frame->prev = prev_frame;
  prev_frame->next = this_frame.get ();

  frame_debug_printf ("  -> %s", prev_frame->to_string ().c_str ());

  return frame_info_ptr (prev_frame);
}

/* Debug routine to print a NULL frame being returned.  */

static void
frame_debug_got_null_frame (const frame_info_ptr &this_frame,
			    const char *reason)
{
  if (frame_debug)
    {
      if (this_frame != NULL)
	frame_debug_printf ("this_frame=%d -> %s", this_frame->level, reason);
      else
	frame_debug_printf ("this_frame=nullptr -> %s", reason);
    }
}

/* Is this (non-sentinel) frame in the "main"() function?  */

static bool
inside_main_func (const frame_info_ptr &this_frame)
{
  if (current_program_space->symfile_object_file == nullptr)
    return false;

  CORE_ADDR sym_addr = 0;
  const char *name = main_name ();
  bound_minimal_symbol msymbol
    = lookup_minimal_symbol (name, NULL,
			     current_program_space->symfile_object_file);

  if (msymbol.minsym != nullptr)
    sym_addr = msymbol.value_address ();

  /* Favor a full symbol in Fortran, for the case where the Fortran main
     is also called "main".  */
  if (msymbol.minsym == nullptr
      || get_frame_language (this_frame) == language_fortran)
    {
      /* In some language (for example Fortran) there will be no minimal
	 symbol with the name of the main function.  In this case we should
	 search the full symbols to see if we can find a match.  */
      struct block_symbol bs = lookup_symbol (name, nullptr,
					      SEARCH_FUNCTION_DOMAIN, nullptr);

      /* This lookup should always yield a block-valued symbol.  */
      if (bs.symbol != nullptr && bs.symbol->aclass () == LOC_BLOCK)
	{
	  const struct block *block = bs.symbol->value_block ();
	  gdb_assert (block != nullptr);
	  sym_addr = block->start ();
	}
      else if (msymbol.minsym == nullptr)
	return false;
    }

  /* Convert any function descriptor addresses into the actual function
     code address.  */
  sym_addr = (gdbarch_convert_from_func_ptr_addr
	      (get_frame_arch (this_frame), sym_addr,
	       current_inferior ()->top_target ()));

  return sym_addr == get_frame_func (this_frame);
}

/* Test whether THIS_FRAME is inside the process entry point function.  */

static bool
inside_entry_func (const frame_info_ptr &this_frame)
{
  CORE_ADDR entry_point;

  if (!entry_point_address_query (&entry_point))
    return false;

  return get_frame_func (this_frame) == entry_point;
}

/* Return a structure containing various interesting information about
   the frame that called THIS_FRAME.  Returns NULL if there is either
   no such frame or the frame fails any of a set of target-independent
   condition that should terminate the frame chain (e.g., as unwinding
   past main()).

   This function should not contain target-dependent tests, such as
   checking whether the program-counter is zero.  */

frame_info_ptr
get_prev_frame (const frame_info_ptr &this_frame)
{
  FRAME_SCOPED_DEBUG_ENTER_EXIT;

  CORE_ADDR frame_pc;
  int frame_pc_p;

  /* There is always a frame.  If this assertion fails, suspect that
     something should be calling get_selected_frame() or
     get_current_frame().  */
  gdb_assert (this_frame != NULL);

  frame_pc_p = get_frame_pc_if_available (this_frame, &frame_pc);

  /* tausq/2004-12-07: Dummy frames are skipped because it doesn't make much
     sense to stop unwinding at a dummy frame.  One place where a dummy
     frame may have an address "inside_main_func" is on HPUX.  On HPUX, the
     pcsqh register (space register for the instruction at the head of the
     instruction queue) cannot be written directly; the only way to set it
     is to branch to code that is in the target space.  In order to implement
     frame dummies on HPUX, the called function is made to jump back to where
     the inferior was when the user function was called.  If gdb was inside
     the main function when we created the dummy frame, the dummy frame will
     point inside the main function.  */
  if (this_frame->level >= 0
      && get_frame_type (this_frame) == NORMAL_FRAME
      && !user_set_backtrace_options.backtrace_past_main
      && frame_pc_p
      && inside_main_func (this_frame))
    /* Don't unwind past main().  Note, this is done _before_ the
       frame has been marked as previously unwound.  That way if the
       user later decides to enable unwinds past main(), that will
       automatically happen.  */
    {
      frame_debug_got_null_frame (this_frame, "inside main func");
      return NULL;
    }

  /* If the user's backtrace limit has been exceeded, stop.  We must
     add two to the current level; one of those accounts for backtrace_limit
     being 1-based and the level being 0-based, and the other accounts for
     the level of the new frame instead of the level of the current
     frame.  */
  if (this_frame->level + 2 > user_set_backtrace_options.backtrace_limit)
    {
      frame_debug_got_null_frame (this_frame, "backtrace limit exceeded");
      return NULL;
    }

  /* If we're already inside the entry function for the main objfile,
     then it isn't valid.  Don't apply this test to a dummy frame -
     dummy frame PCs typically land in the entry func.  Don't apply
     this test to the sentinel frame.  Sentinel frames should always
     be allowed to unwind.  */
  /* NOTE: cagney/2003-07-07: Fixed a bug in inside_main_func() -
     wasn't checking for "main" in the minimal symbols.  With that
     fixed asm-source tests now stop in "main" instead of halting the
     backtrace in weird and wonderful ways somewhere inside the entry
     file.  Suspect that tests for inside the entry file/func were
     added to work around that (now fixed) case.  */
  /* NOTE: cagney/2003-07-15: danielj (if I'm reading it right)
     suggested having the inside_entry_func test use the
     inside_main_func() msymbol trick (along with entry_point_address()
     I guess) to determine the address range of the start function.
     That should provide a far better stopper than the current
     heuristics.  */
  /* NOTE: tausq/2004-10-09: this is needed if, for example, the compiler
     applied tail-call optimizations to main so that a function called
     from main returns directly to the caller of main.  Since we don't
     stop at main, we should at least stop at the entry point of the
     application.  */
  if (this_frame->level >= 0
      && get_frame_type (this_frame) == NORMAL_FRAME
      && !user_set_backtrace_options.backtrace_past_entry
      && frame_pc_p
      && inside_entry_func (this_frame))
    {
      frame_debug_got_null_frame (this_frame, "inside entry func");
      return NULL;
    }

  /* Assume that the only way to get a zero PC is through something
     like a SIGSEGV or a dummy frame, and hence that NORMAL frames
     will never unwind a zero PC.  */
  if (this_frame->level > 0
      && (get_frame_type (this_frame) == NORMAL_FRAME
	  || get_frame_type (this_frame) == INLINE_FRAME)
      && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME
      && frame_pc_p && frame_pc == 0)
    {
      frame_debug_got_null_frame (this_frame, "zero PC");
      return NULL;
    }

  return get_prev_frame_always (this_frame);
}

CORE_ADDR
get_frame_pc (const frame_info_ptr &frame)
{
  gdb_assert (frame->next != NULL);
  return frame_unwind_pc (frame_info_ptr (frame->next));
}

bool
get_frame_pc_if_available (const frame_info_ptr &frame, CORE_ADDR *pc)
{

  gdb_assert (frame->next != NULL);

  try
    {
      *pc = frame_unwind_pc (frame_info_ptr (frame->next));
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == NOT_AVAILABLE_ERROR)
	return false;
      else
	throw;
    }

  return true;
}

/* Return an address that falls within THIS_FRAME's code block.  */

CORE_ADDR
get_frame_address_in_block (const frame_info_ptr &this_frame)
{
  /* A draft address.  */
  CORE_ADDR pc = get_frame_pc (this_frame);

  frame_info_ptr next_frame (this_frame->next);

  /* Calling get_frame_pc returns the resume address for THIS_FRAME.
     Normally the resume address is inside the body of the function
     associated with THIS_FRAME, but there is a special case: when
     calling a function which the compiler knows will never return
     (for instance abort), the call may be the very last instruction
     in the calling function.  The resume address will point after the
     call and may be at the beginning of a different function
     entirely.

     If THIS_FRAME is a signal frame or dummy frame, then we should
     not adjust the unwound PC.  For a dummy frame, GDB pushed the
     resume address manually onto the stack.  For a signal frame, the
     OS may have pushed the resume address manually and invoked the
     handler (e.g. GNU/Linux), or invoked the trampoline which called
     the signal handler - but in either case the signal handler is
     expected to return to the trampoline.  So in both of these
     cases we know that the resume address is executable and
     related.  So we only need to adjust the PC if THIS_FRAME
     is a normal function.

     If the program has been interrupted while THIS_FRAME is current,
     then clearly the resume address is inside the associated
     function.  There are three kinds of interruption: debugger stop
     (next frame will be SENTINEL_FRAME), operating system
     signal or exception (next frame will be SIGTRAMP_FRAME),
     or debugger-induced function call (next frame will be
     DUMMY_FRAME).  So we only need to adjust the PC if
     NEXT_FRAME is a normal function.

     We check the type of NEXT_FRAME first, since it is already
     known; frame type is determined by the unwinder, and since
     we have THIS_FRAME we've already selected an unwinder for
     NEXT_FRAME.

     If the next frame is inlined, we need to keep going until we find
     the real function - for instance, if a signal handler is invoked
     while in an inlined function, then the code address of the
     "calling" normal function should not be adjusted either.  */

  while (get_frame_type (next_frame) == INLINE_FRAME)
    next_frame = frame_info_ptr (next_frame->next);

  if ((get_frame_type (next_frame) == NORMAL_FRAME
       || get_frame_type (next_frame) == TAILCALL_FRAME)
      && (get_frame_type (this_frame) == NORMAL_FRAME
	  || get_frame_type (this_frame) == TAILCALL_FRAME
	  || get_frame_type (this_frame) == INLINE_FRAME))
    return pc - 1;

  return pc;
}

bool
get_frame_address_in_block_if_available (const frame_info_ptr &this_frame,
					 CORE_ADDR *pc)
{

  try
    {
      *pc = get_frame_address_in_block (this_frame);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error == NOT_AVAILABLE_ERROR)
	return false;
      throw;
    }

  return true;
}

symtab_and_line
find_frame_sal (const frame_info_ptr &frame)
{
  frame_info_ptr next_frame;
  int notcurrent;
  CORE_ADDR pc;

  if (frame_inlined_callees (frame) > 0)
    {
      struct symbol *sym;

      /* If the current frame has some inlined callees, and we have a next
	 frame, then that frame must be an inlined frame.  In this case
	 this frame's sal is the "call site" of the next frame's inlined
	 function, which can not be inferred from get_frame_pc.  */
      next_frame = get_next_frame (frame);
      if (next_frame)
	sym = get_frame_function (next_frame);
      else
	sym = inline_skipped_symbol (inferior_thread ());

      /* If frame is inline, it certainly has symbols.  */
      gdb_assert (sym);

      symtab_and_line sal;
      if (sym->line () != 0)
	{
	  sal.symtab = sym->symtab ();
	  sal.line = sym->line ();
	}
      else
	/* If the symbol does not have a location, we don't know where
	   the call site is.  Do not pretend to.  This is jarring, but
	   we can't do much better.  */
	sal.pc = get_frame_pc (frame);

      sal.pspace = get_frame_program_space (frame);
      return sal;
    }

  /* If FRAME is not the innermost frame, that normally means that
     FRAME->pc points at the return instruction (which is *after* the
     call instruction), and we want to get the line containing the
     call (because the call is where the user thinks the program is).
     However, if the next frame is either a SIGTRAMP_FRAME or a
     DUMMY_FRAME, then the next frame will contain a saved interrupt
     PC and such a PC indicates the current (rather than next)
     instruction/line, consequently, for such cases, want to get the
     line containing fi->pc.  */
  if (!get_frame_pc_if_available (frame, &pc))
    return {};

  notcurrent = (pc != get_frame_address_in_block (frame));
  return find_pc_line (pc, notcurrent);
}

/* Per "frame.h", return the ``address'' of the frame.  Code should
   really be using get_frame_id().  */
CORE_ADDR
get_frame_base (const frame_info_ptr &fi)
{
  return get_frame_id (fi).stack_addr;
}

/* High-level offsets into the frame.  Used by the debug info.  */

CORE_ADDR
get_frame_base_address (const frame_info_ptr &fi)
{
  if (get_frame_type (fi) != NORMAL_FRAME)
    return 0;
  if (fi->base == NULL)
    fi->base = frame_base_find_by_frame (fi);
  /* Sneaky: If the low-level unwind and high-level base code share a
     common unwinder, let them share the prologue cache.  */
  if (fi->base->unwind == fi->unwind)
    return fi->base->this_base (fi, &fi->prologue_cache);
  return fi->base->this_base (fi, &fi->base_cache);
}

CORE_ADDR
get_frame_locals_address (const frame_info_ptr &fi)
{
  if (get_frame_type (fi) != NORMAL_FRAME)
    return 0;
  /* If there isn't a frame address method, find it.  */
  if (fi->base == NULL)
    fi->base = frame_base_find_by_frame (fi);
  /* Sneaky: If the low-level unwind and high-level base code share a
     common unwinder, let them share the prologue cache.  */
  if (fi->base->unwind == fi->unwind)
    return fi->base->this_locals (fi, &fi->prologue_cache);
  return fi->base->this_locals (fi, &fi->base_cache);
}

CORE_ADDR
get_frame_args_address (const frame_info_ptr &fi)
{
  if (get_frame_type (fi) != NORMAL_FRAME)
    return 0;
  /* If there isn't a frame address method, find it.  */
  if (fi->base == NULL)
    fi->base = frame_base_find_by_frame (fi);
  /* Sneaky: If the low-level unwind and high-level base code share a
     common unwinder, let them share the prologue cache.  */
  if (fi->base->unwind == fi->unwind)
    return fi->base->this_args (fi, &fi->prologue_cache);
  return fi->base->this_args (fi, &fi->base_cache);
}

/* Return true if the frame unwinder for frame FI is UNWINDER; false
   otherwise.  */

bool
frame_unwinder_is (const frame_info_ptr &fi, const frame_unwind *unwinder)
{
  if (fi->unwind == nullptr)
    frame_unwind_find_by_frame (fi, &fi->prologue_cache);

  return fi->unwind == unwinder;
}

/* Level of the selected frame: 0 for innermost, 1 for its caller, ...
   or -1 for a NULL frame.  */

int
frame_relative_level (const frame_info_ptr &fi)
{
  if (fi == NULL)
    return -1;
  else
    return fi->level;
}

enum frame_type
get_frame_type (const frame_info_ptr &frame)
{
  if (frame->unwind == NULL)
    /* Initialize the frame's unwinder because that's what
       provides the frame's type.  */
    frame_unwind_find_by_frame (frame, &frame->prologue_cache);
  return frame->unwind->type;
}

struct program_space *
get_frame_program_space (const frame_info_ptr &frame)
{
  return frame->pspace;
}

struct program_space *
frame_unwind_program_space (const frame_info_ptr &this_frame)
{
  gdb_assert (this_frame);

  /* This is really a placeholder to keep the API consistent --- we
     assume for now that we don't have frame chains crossing
     spaces.  */
  return this_frame->pspace;
}

const address_space *
get_frame_address_space (const frame_info_ptr &frame)
{
  return frame->aspace;
}

/* Memory access methods.  */

void
get_frame_memory (const frame_info_ptr &this_frame, CORE_ADDR addr,
		  gdb::array_view<gdb_byte> buffer)
{
  read_memory (addr, buffer.data (), buffer.size ());
}

LONGEST
get_frame_memory_signed (const frame_info_ptr &this_frame, CORE_ADDR addr,
			 int len)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  return read_memory_integer (addr, len, byte_order);
}

ULONGEST
get_frame_memory_unsigned (const frame_info_ptr &this_frame, CORE_ADDR addr,
			   int len)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  return read_memory_unsigned_integer (addr, len, byte_order);
}

bool
safe_frame_unwind_memory (const frame_info_ptr &this_frame,
			  CORE_ADDR addr, gdb::array_view<gdb_byte> buffer)
{
  /* NOTE: target_read_memory returns zero on success!  */
  return target_read_memory (addr, buffer.data (), buffer.size ()) == 0;
}

/* Architecture methods.  */

struct gdbarch *
get_frame_arch (const frame_info_ptr &this_frame)
{
  return frame_unwind_arch (frame_info_ptr (this_frame->next));
}

struct gdbarch *
frame_unwind_arch (const frame_info_ptr &next_frame)
{
  if (!next_frame->prev_arch.p)
    {
      struct gdbarch *arch;

      if (next_frame->unwind == NULL)
	frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache);

      if (next_frame->unwind->prev_arch != NULL)
	arch = next_frame->unwind->prev_arch (next_frame,
					      &next_frame->prologue_cache);
      else
	arch = get_frame_arch (next_frame);

      next_frame->prev_arch.arch = arch;
      next_frame->prev_arch.p = true;
      frame_debug_printf ("next_frame=%d -> %s",
			  next_frame->level,
			  gdbarch_bfd_arch_info (arch)->printable_name);
    }

  return next_frame->prev_arch.arch;
}

struct gdbarch *
frame_unwind_caller_arch (const frame_info_ptr &initial_next_frame)
{
  frame_info_ptr next_frame = skip_artificial_frames (initial_next_frame);

  /* We must have a non-artificial frame.  The caller is supposed to check
     the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID
     in this case.  */
  gdb_assert (next_frame != nullptr);

  return frame_unwind_arch (next_frame);
}

/* Gets the language of FRAME.  */

enum language
get_frame_language (const frame_info_ptr &frame)
{
  CORE_ADDR pc = 0;
  bool pc_p = false;

  gdb_assert (frame!= NULL);

    /* We determine the current frame language by looking up its
       associated symtab.  To retrieve this symtab, we use the frame
       PC.  However we cannot use the frame PC as is, because it
       usually points to the instruction following the "call", which
       is sometimes the first instruction of another function.  So
       we rely on get_frame_address_in_block(), it provides us with
       a PC that is guaranteed to be inside the frame's code
       block.  */

  try
    {
      pc = get_frame_address_in_block (frame);
      pc_p = true;
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error != NOT_AVAILABLE_ERROR)
	throw;
    }

  if (pc_p)
    {
      struct compunit_symtab *cust = find_pc_compunit_symtab (pc);

      if (cust != NULL)
	return cust->language ();
    }

  return language_unknown;
}

/* Stack pointer methods.  */

CORE_ADDR
get_frame_sp (const frame_info_ptr &this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to
     operate on THIS_FRAME now.  */
  return gdbarch_unwind_sp (gdbarch, frame_info_ptr (this_frame->next));
}

/* See frame.h.  */

frame_info_ptr
frame_follow_static_link (const frame_info_ptr &initial_frame)
{
  const block *frame_block = get_frame_block (initial_frame, nullptr);
  if (frame_block == nullptr)
    return {};

  frame_block = frame_block->function_block ();

  const struct dynamic_prop *static_link = frame_block->static_link ();
  if (static_link == nullptr)
    return {};

  CORE_ADDR upper_frame_base;

  if (!dwarf2_evaluate_property (static_link, initial_frame, NULL, &upper_frame_base))
    return {};

  /* Now climb up the stack frame until we reach the frame we are interested
     in.  */
  frame_info_ptr frame = initial_frame;
  for (; frame != nullptr; frame = get_prev_frame (frame))
    {
      struct symbol *framefunc = get_frame_function (frame);

      /* Stacks can be quite deep: give the user a chance to stop this.  */
      QUIT;

      /* If we don't know how to compute FRAME's base address, don't give up:
	 maybe the frame we are looking for is upper in the stack frame.  */
      if (framefunc != nullptr)
	{
	  if (const symbol_block_ops *block_ops = framefunc->block_ops ();
	      (block_ops != nullptr
	       && block_ops->get_frame_base != nullptr
	       && (block_ops->get_frame_base (framefunc, frame)
		   == upper_frame_base)))
	    break;
	}
    }

  return frame;
}

/* Return the reason why we can't unwind past FRAME.  */

enum unwind_stop_reason
get_frame_unwind_stop_reason (const frame_info_ptr &frame)
{
  /* Fill-in STOP_REASON.  */
  get_prev_frame_always (frame);
  gdb_assert (frame->prev_p);

  return frame->stop_reason;
}

/* Return a string explaining REASON.  */

const char *
unwind_stop_reason_to_string (enum unwind_stop_reason reason)
{
  switch (reason)
    {
#define SET(name, description) \
    case name: return _(description);
#include "unwind_stop_reasons.def"
#undef SET

    default:
      internal_error ("Invalid frame stop reason");
    }
}

const char *
frame_stop_reason_string (const frame_info_ptr &fi)
{
  gdb_assert (fi->prev_p);
  gdb_assert (fi->prev == NULL);

  /* Return the specific string if we have one.  */
  if (fi->stop_string != NULL)
    return fi->stop_string;

  /* Return the generic string if we have nothing better.  */
  return unwind_stop_reason_to_string (fi->stop_reason);
}

/* Return the enum symbol name of REASON as a string, to use in debug
   output.  */

static const char *
frame_stop_reason_symbol_string (enum unwind_stop_reason reason)
{
  switch (reason)
    {
#define SET(name, description) \
    case name: return #name;
#include "unwind_stop_reasons.def"
#undef SET

    default:
      internal_error ("Invalid frame stop reason");
    }
}

/* Clean up after a failed (wrong unwinder) attempt to unwind past
   FRAME.  */

void
frame_cleanup_after_sniffer (const frame_info_ptr &frame)
{
  /* The sniffer should not allocate a prologue cache if it did not
     match this frame.  */
  gdb_assert (frame->prologue_cache == NULL);

  /* No sniffer should extend the frame chain; sniff based on what is
     already certain.  */
  gdb_assert (!frame->prev_p);

  /* The sniffer should not check the frame's ID; that's circular.  */
  gdb_assert (frame->this_id.p != frame_id_status::COMPUTED);

  /* Clear cached fields dependent on the unwinder.

     The previous PC is independent of the unwinder, but the previous
     function is not (see get_frame_address_in_block).  */
  frame->prev_func.status = CC_UNKNOWN;
  frame->prev_func.addr = 0;

  /* Discard the unwinder last, so that we can easily find it if an assertion
     in this function triggers.  */
  frame->unwind = NULL;
}

/* Set FRAME's unwinder temporarily, so that we can call a sniffer.
   If sniffing fails, the caller should be sure to call
   frame_cleanup_after_sniffer.  */

void
frame_prepare_for_sniffer (const frame_info_ptr &frame,
			   const struct frame_unwind *unwind)
{
  gdb_assert (frame->unwind == NULL);
  frame->unwind = unwind;
}

static struct cmd_list_element *set_backtrace_cmdlist;
static struct cmd_list_element *show_backtrace_cmdlist;

/* Definition of the "set backtrace" settings that are exposed as
   "backtrace" command options.  */

using boolean_option_def
  = gdb::option::boolean_option_def<set_backtrace_options>;

const gdb::option::option_def set_backtrace_option_defs[] = {

  boolean_option_def {
    "past-main",
    [] (set_backtrace_options *opt) { return &opt->backtrace_past_main; },
    show_backtrace_past_main, /* show_cmd_cb */
    N_("Set whether backtraces should continue past \"main\"."),
    N_("Show whether backtraces should continue past \"main\"."),
    N_("Normally the caller of \"main\" is not of interest, so GDB will terminate\n\
the backtrace at \"main\".  Set this if you need to see the rest\n\
of the stack trace."),
  },

  boolean_option_def {
    "past-entry",
    [] (set_backtrace_options *opt) { return &opt->backtrace_past_entry; },
    show_backtrace_past_entry, /* show_cmd_cb */
    N_("Set whether backtraces should continue past the entry point of a program."),
    N_("Show whether backtraces should continue past the entry point of a program."),
    N_("Normally there are no callers beyond the entry point of a program, so GDB\n\
will terminate the backtrace there.  Set this if you need to see\n\
the rest of the stack trace."),
  },
};

/* Implement the 'maintenance print frame-id' command.  */

static void
maintenance_print_frame_id (const char *args, int from_tty)
{
  frame_info_ptr frame;

  /* Use the currently selected frame, or select a frame based on the level
     number passed by the user.  */
  if (args == nullptr)
    frame = get_selected_frame ("No frame selected");
  else
    {
      int level = value_as_long (parse_and_eval (args));
      frame = find_relative_frame (get_current_frame (), &level);
    }

  /* Print the frame-id.  */
  gdb_assert (frame != nullptr);
  gdb_printf ("frame-id for frame #%d: %s\n",
	      frame_relative_level (frame),
	      get_frame_id (frame).to_string ().c_str ());
}

/* See frame-info-ptr.h.  */

frame_info_ptr::frame_info_ptr (struct frame_info *ptr)
  : m_ptr (ptr)
{
  frame_list.push_back (*this);

  if (m_ptr == nullptr)
    return;

  m_cached_level = ptr->level;

  if (m_cached_level != 0 || m_ptr->this_id.value.user_created_p)
    m_cached_id = m_ptr->this_id.value;
}

/* See frame-info-ptr.h.  */

frame_info *
frame_info_ptr::reinflate () const
{
  /* Ensure we have a valid frame level (sentinel frame or above).  */
  gdb_assert (m_cached_level >= -1);

  if (m_ptr != nullptr)
    {
      /* The frame_info wasn't invalidated, no need to reinflate.  */
      return m_ptr;
    }

  if (m_cached_id.user_created_p)
    m_ptr = create_new_frame (m_cached_id).get ();
  else
    {
      /* Frame #0 needs special handling, see comment in select_frame.  */
      if (m_cached_level == 0)
	m_ptr = get_current_frame ().get ();
      else
	{
	  /* If we reach here without a valid frame id, it means we are trying
	     to reinflate a frame whose id was not know at construction time.
	     We're probably trying to reinflate a frame while computing its id
	     which is not possible, and would indicate a problem with GDB.  */
	  gdb_assert (frame_id_p (m_cached_id));
	  m_ptr = frame_find_by_id (m_cached_id).get ();
	}
    }

  gdb_assert (m_ptr != nullptr);
  return m_ptr;
}

void _initialize_frame ();
void
_initialize_frame ()
{
  obstack_init (&frame_cache_obstack);

  frame_stash_create ();

  gdb::observers::target_changed.attach (frame_observer_target_changed,
					 "frame");

  add_setshow_prefix_cmd ("backtrace", class_maintenance,
			  _("\
Set backtrace specific variables.\n\
Configure backtrace variables such as the backtrace limit"),
			  _("\
Show backtrace specific variables.\n\
Show backtrace variables such as the backtrace limit."),
			  &set_backtrace_cmdlist, &show_backtrace_cmdlist,
			  &setlist, &showlist);

  add_setshow_uinteger_cmd ("limit", class_obscure,
			    &user_set_backtrace_options.backtrace_limit, _("\
Set an upper bound on the number of backtrace levels."), _("\
Show the upper bound on the number of backtrace levels."), _("\
No more than the specified number of frames can be displayed or examined.\n\
Literal \"unlimited\" or zero means no limit."),
			    NULL,
			    show_backtrace_limit,
			    &set_backtrace_cmdlist,
			    &show_backtrace_cmdlist);

  gdb::option::add_setshow_cmds_for_options
    (class_stack, &user_set_backtrace_options,
     set_backtrace_option_defs, &set_backtrace_cmdlist, &show_backtrace_cmdlist);

  /* Debug this files internals.  */
  add_setshow_boolean_cmd ("frame", class_maintenance, &frame_debug,  _("\
Set frame debugging."), _("\
Show frame debugging."), _("\
When non-zero, frame specific internal debugging is enabled."),
			   NULL,
			   show_frame_debug,
			   &setdebuglist, &showdebuglist);

  add_cmd ("frame-id", class_maintenance, maintenance_print_frame_id,
	   _("Print the current frame-id."),
	   &maintenanceprintlist);
}
