//===-- RegisterContextUnwind.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/RegisterContextUnwind.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/CallFrameInfo.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/VASPrintf.h"
#include "lldb/lldb-private.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatAdapters.h"
#include <cassert>
#include <memory>

using namespace lldb;
using namespace lldb_private;

static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) {
  if (sym_ctx.symbol)
    return sym_ctx.symbol->GetName();
  else if (sym_ctx.function)
    return sym_ctx.function->GetName();
  return ConstString();
}

static bool CallFrameAddressIsValid(ABISP abi_sp, lldb::addr_t cfa) {
  if (cfa == LLDB_INVALID_ADDRESS)
    return false;
  if (abi_sp)
    return abi_sp->CallFrameAddressIsValid(cfa);
  return cfa != 0 && cfa != 1;
}

/// Identify a clang outlined function by symbol name.
///
/// The unwind information in outlined functions from clang can be
/// incorrect, and because of when the outlining happens in the compilation,
/// it may not be possible to fix.  We will need to ignore any
/// instruction-emulation or compiler-sourced unwind plans for these
/// functions, and fall back to an ABI default unwindplan.
static bool IsClangOutlinedFunction(const SymbolContext &sym_ctx) {
  llvm::StringRef name = GetSymbolOrFunctionName(sym_ctx).GetStringRef();
  if (name.starts_with("OUTLINED_FUNCTION_"))
    return true;
  return false;
}

#define UNWIND_LOG_IMPL(LOG_FN, log, ...)                                      \
  LOG_FN(log, "{0}th{1}/fr{2} {3}",                                            \
         llvm::indent(std::min(m_frame_number, 100U)), m_thread.GetIndexID(),  \
         m_frame_number, llvm::formatv(__VA_ARGS__))

#define UNWIND_LOG(log, ...) UNWIND_LOG_IMPL(LLDB_LOG, log, __VA_ARGS__)

#define UNWIND_LOG_VERBOSE(log, ...)                                           \
  UNWIND_LOG_IMPL(LLDB_LOG_VERBOSE, log, __VA_ARGS__)

RegisterContextUnwind::RegisterContextUnwind(Thread &thread,
                                             const SharedPtr &next_frame,
                                             SymbolContext &sym_ctx,
                                             uint32_t frame_number,
                                             UnwindLLDB &unwind_lldb)
    : RegisterContext(thread, frame_number), m_thread(thread),
      m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(),
      m_fallback_unwind_plan_sp(), m_all_registers_available(false),
      m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS),
      m_afa(LLDB_INVALID_ADDRESS), m_start_pc(), m_current_pc(),
      m_current_offset(), m_current_offset_backed_up_one(),
      m_behaves_like_zeroth_frame(false), m_sym_ctx(sym_ctx),
      m_sym_ctx_valid(false), m_frame_number(frame_number), m_registers(),
      m_parent_unwind(unwind_lldb) {
  m_sym_ctx.Clear(false);
  m_sym_ctx_valid = false;

  if (IsFrameZero()) {
    InitializeZerothFrame();
  } else {
    InitializeNonZerothFrame();
  }

  // This same code exists over in the GetFullUnwindPlanForFrame() but it may
  // not have been executed yet
  if (IsFrameZero() || next_frame->m_frame_type == eTrapHandlerFrame ||
      next_frame->m_frame_type == eDebuggerFrame) {
    m_all_registers_available = true;
  }
}

bool RegisterContextUnwind::IsUnwindPlanValidForCurrentPC(
    std::shared_ptr<const UnwindPlan> unwind_plan_sp) {
  if (!unwind_plan_sp)
    return false;

  // check if m_current_pc is valid
  if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
    // yes - current offset can be used as is
    return true;
  }

  // If don't have an offset or we're at the start of the function, we've got
  // nothing else to try.
  if (!m_current_offset || m_current_offset == 0)
    return false;

  // check pc - 1 to see if it's valid
  Address pc_minus_one(m_current_pc);
  pc_minus_one.Slide(-1);
  if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one)) {
    return true;
  }

  return false;
}

// Initialize a RegisterContextUnwind which is the first frame of a stack -- the
// zeroth frame or currently executing frame.

void RegisterContextUnwind::InitializeZerothFrame() {
  Log *log = GetLog(LLDBLog::Unwind);
  ExecutionContext exe_ctx(m_thread.shared_from_this());
  RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();

  if (reg_ctx_sp.get() == nullptr) {
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "frame does not have a register context");
    return;
  }

  addr_t current_pc = reg_ctx_sp->GetPC();

  if (current_pc == LLDB_INVALID_ADDRESS) {
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "frame does not have a pc");
    return;
  }

  Process *process = exe_ctx.GetProcessPtr();

  // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
  // this will strip bit zero in case we read a PC from memory or from the LR.
  // (which would be a no-op in frame 0 where we get it from the register set,
  // but still a good idea to make the call here for other ABIs that may
  // exist.)
  if (ABISP abi_sp = process->GetABI())
    current_pc = abi_sp->FixCodeAddress(current_pc);

  std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
      LanguageRuntime::GetRuntimeUnwindPlan(m_thread, this,
                                            m_behaves_like_zeroth_frame);
  if (lang_runtime_plan_sp.get()) {
    UNWIND_LOG(log, "This is an async frame");
  }

  // Initialize m_current_pc, an Address object, based on current_pc, an
  // addr_t.
  m_current_pc.SetLoadAddress(current_pc, &process->GetTarget());

  // If we don't have a Module for some reason, we're not going to find
  // symbol/function information - just stick in some reasonable defaults and
  // hope we can unwind past this frame.
  ModuleSP pc_module_sp(m_current_pc.GetModule());
  if (!m_current_pc.IsValid() || !pc_module_sp) {
    UNWIND_LOG(log, "using architectural default unwind method");
  }

  m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx);

  if (m_sym_ctx.symbol) {
    UNWIND_LOG(log, "with pc value of {0:x}, symbol name is '{1}'", current_pc,
               GetSymbolOrFunctionName(m_sym_ctx));
  } else if (m_sym_ctx.function) {
    UNWIND_LOG(log, "with pc value of {0:x}, function name is '{1}'",
               current_pc, GetSymbolOrFunctionName(m_sym_ctx));
  } else {
    UNWIND_LOG(log, "with pc value of {0:x}, no symbol/function name is known.",
               current_pc);
  }

  if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
    m_frame_type = eTrapHandlerFrame;
  } else {
    // FIXME:  Detect eDebuggerFrame here.
    m_frame_type = eNormalFrame;
  }

  // If we were able to find a symbol/function, set addr_range to the bounds of
  // that symbol/function. else treat the current pc value as the start_pc and
  // record no offset.
  if (m_sym_ctx_valid) {
    m_start_pc = m_sym_ctx.GetFunctionOrSymbolAddress();
    if (m_current_pc.GetModule() == m_start_pc.GetModule()) {
      m_current_offset =
          m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
    }
    m_current_offset_backed_up_one = m_current_offset;
  } else {
    m_start_pc = m_current_pc;
    m_current_offset = std::nullopt;
    m_current_offset_backed_up_one = std::nullopt;
  }

  // We've set m_frame_type and m_sym_ctx before these calls.

  m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();
  m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();

  const UnwindPlan::Row *active_row = nullptr;
  lldb::RegisterKind row_register_kind = eRegisterKindGeneric;

  // If we have LanguageRuntime UnwindPlan for this unwind, use those
  // rules to find the caller frame instead of the function's normal
  // UnwindPlans.  The full unwind plan for this frame will be
  // the LanguageRuntime-provided unwind plan, and there will not be a
  // fast unwind plan.
  if (lang_runtime_plan_sp.get()) {
    active_row =
        lang_runtime_plan_sp->GetRowForFunctionOffset(m_current_offset);
    row_register_kind = lang_runtime_plan_sp->GetRegisterKind();
    if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(),
                          m_cfa)) {
      UNWIND_LOG(log, "Cannot set cfa");
    } else {
      m_full_unwind_plan_sp = lang_runtime_plan_sp;
      if (log) {
        StreamString active_row_strm;
        active_row->Dump(active_row_strm, lang_runtime_plan_sp.get(), &m_thread,
                         m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
        UNWIND_LOG(log, "async active row: {0}", active_row_strm.GetString());
      }
      UNWIND_LOG(log, "m_cfa = {0:x} m_afa = {1:x}", m_cfa, m_afa);
      UNWIND_LOG(log,
                 "initialized async frame current pc is {0:x} cfa is {1:x} afa "
                 "is {2:x}",
                 m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), m_cfa,
                 m_afa);

      return;
    }
  }

  if (m_full_unwind_plan_sp &&
      m_full_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
    active_row =
        m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
    row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
    PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
    if (active_row && log) {
      StreamString active_row_strm;
      active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
                       m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
      UNWIND_LOG(log, "{0}", active_row_strm.GetString());
    }
  }

  if (!active_row) {
    UNWIND_LOG(log, "could not find an unwindplan row for this frame's pc");
    m_frame_type = eNotAValidFrame;
    return;
  }

  if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
    // Try the fall back unwind plan since the
    // full unwind plan failed.
    FuncUnwindersSP func_unwinders_sp;
    std::shared_ptr<const UnwindPlan> call_site_unwind_plan;
    bool cfa_status = false;

    if (m_sym_ctx_valid) {
      func_unwinders_sp =
          pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
              m_current_pc, m_sym_ctx);
    }

    if (func_unwinders_sp.get() != nullptr)
      call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
          process->GetTarget(), m_thread);

    if (call_site_unwind_plan != nullptr) {
      m_fallback_unwind_plan_sp = call_site_unwind_plan;
      if (TryFallbackUnwindPlan())
        cfa_status = true;
    }
    if (!cfa_status) {
      UNWIND_LOG(log, "could not read CFA value for first frame.");
      m_frame_type = eNotAValidFrame;
      return;
    }
  } else
    ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);

  if (m_cfa == LLDB_INVALID_ADDRESS && m_afa == LLDB_INVALID_ADDRESS) {
    UNWIND_LOG(log,
               "could not read CFA or AFA values for first frame, not valid.");
    m_frame_type = eNotAValidFrame;
    return;
  }

  // Give the Architecture a chance to replace the UnwindPlan.
  TryAdoptArchitectureUnwindPlan();

  UNWIND_LOG(log,
             "initialized frame current pc is {0:x} cfa is {1:x} afa is {2:x} "
             "using {3} UnwindPlan",
             m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), m_cfa, m_afa,
             m_full_unwind_plan_sp->GetSourceName());
}

// Initialize a RegisterContextUnwind for the non-zeroth frame -- rely on the
// RegisterContextUnwind "below" it to provide things like its current pc value.

void RegisterContextUnwind::InitializeNonZerothFrame() {
  Log *log = GetLog(LLDBLog::Unwind);
  if (IsFrameZero()) {
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "non-zeroth frame tests positive for IsFrameZero -- that "
                    "shouldn't happen.");
    return;
  }

  if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) {
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "Could not get next frame, marking this frame as invalid.");
    return;
  }
  if (!m_thread.GetRegisterContext()) {
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "Could not get register context for this thread, marking "
                    "this frame as invalid.");
    return;
  }

  ExecutionContext exe_ctx(m_thread.shared_from_this());
  Process *process = exe_ctx.GetProcessPtr();

  // Some languages may have a logical parent stack frame which is
  // not a real stack frame, but the programmer would consider it to
  // be the caller of the frame, e.g. Swift asynchronous frames.
  //
  // A LanguageRuntime may provide an UnwindPlan that is used in this
  // stack trace base on the RegisterContext contents, intsead
  // of the normal UnwindPlans we would use for the return-pc.
  std::shared_ptr<const UnwindPlan> lang_runtime_plan_sp =
      LanguageRuntime::GetRuntimeUnwindPlan(m_thread, this,
                                            m_behaves_like_zeroth_frame);
  if (lang_runtime_plan_sp.get()) {
    UNWIND_LOG(log, "This is an async frame");
  }

  addr_t pc;
  if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
    UNWIND_LOG(log, "could not get pc value");
    m_frame_type = eNotAValidFrame;
    return;
  }

  // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs
  // this will strip bit zero in case we read a PC from memory or from the LR.
  ABISP abi_sp = process->GetABI();
  if (abi_sp)
    pc = abi_sp->FixCodeAddress(pc);

  if (log) {
    UNWIND_LOG(log, "pc = {0:x}", pc);
    addr_t reg_val;
    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
      UNWIND_LOG(log, "fp = {0:x}", reg_val);
    if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
      UNWIND_LOG(log, "sp = {0:x}", reg_val);
  }

  // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap
  // handler function
  bool above_trap_handler = false;
  if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
      GetNextFrame()->IsTrapHandlerFrame())
    above_trap_handler = true;

  if (pc == 0 || pc == 0x1) {
    if (!above_trap_handler) {
      m_frame_type = eNotAValidFrame;
      UNWIND_LOG(log, "this frame has a pc of 0x0");
      return;
    }
  }

  const bool allow_section_end = true;
  m_current_pc.SetLoadAddress(pc, &process->GetTarget(), allow_section_end);

  // If we don't have a Module for some reason, we're not going to find
  // symbol/function information - just stick in some reasonable defaults and
  // hope we can unwind past this frame.  If we're above a trap handler,
  // we may be at a bogus address because we jumped through a bogus function
  // pointer and trapped, so don't force the arch default unwind plan in that
  // case.
  ModuleSP pc_module_sp(m_current_pc.GetModule());
  if ((!m_current_pc.IsValid() || !pc_module_sp) &&
      above_trap_handler == false) {
    UNWIND_LOG(log, "using architectural default unwind method");

    // Test the pc value to see if we know it's in an unmapped/non-executable
    // region of memory.
    uint32_t permissions;
    if (process->GetLoadAddressPermissions(pc, permissions) &&
        (permissions & ePermissionsExecutable) == 0) {
      // If this is the second frame off the stack, we may have unwound the
      // first frame incorrectly.  But using the architecture default unwind
      // plan may get us back on track -- albeit possibly skipping a real
      // frame.  Give this frame a clearly-invalid pc and see if we can get any
      // further.
      if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
          GetNextFrame()->IsFrameZero()) {
        UNWIND_LOG(log,
                   "had a pc of {0:x} which is not in executable memory but on "
                   "frame 1 -- allowing it once.",
                   pc);
        m_frame_type = eSkipFrame;
      } else {
        // anywhere other than the second frame, a non-executable pc means
        // we're off in the weeds -- stop now.
        m_frame_type = eNotAValidFrame;
        UNWIND_LOG(log, "pc is in a non-executable section of memory and this "
                        "isn't the 2nd frame in the stack walk.");
        return;
      }
    }

    if (abi_sp) {
      m_fast_unwind_plan_sp.reset();
      m_full_unwind_plan_sp = abi_sp->CreateDefaultUnwindPlan();
      assert(((!m_full_unwind_plan_sp ||
               m_full_unwind_plan_sp->GetRowCount() == 0 ||
               m_full_unwind_plan_sp->GetRowAtIndex(0)
                   ->GetUnspecifiedRegistersAreUndefined())) &&
             "Default UnwindPlan must set "
             "UnspecifiedRegistersAreUndefined to true");
      if (m_frame_type != eSkipFrame) // don't override eSkipFrame
      {
        m_frame_type = eNormalFrame;
      }
      m_all_registers_available = false;
      m_current_offset = std::nullopt;
      m_current_offset_backed_up_one = std::nullopt;
      RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
      if (const UnwindPlan::Row *row =
              m_full_unwind_plan_sp->GetRowForFunctionOffset(0)) {
        if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) {
          UNWIND_LOG(log, "failed to get cfa value");
          if (m_frame_type != eSkipFrame) // don't override eSkipFrame
          {
            m_frame_type = eNotAValidFrame;
          }
          return;
        }

        ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa);

        // A couple of sanity checks..
        if (!CallFrameAddressIsValid(abi_sp, m_cfa)) {
          UNWIND_LOG(log, "could not find a valid cfa address");
          m_frame_type = eNotAValidFrame;
          return;
        }

        // m_cfa should point into the stack memory; if we can query memory
        // region permissions, see if the memory is allocated & readable.
        if (process->GetLoadAddressPermissions(m_cfa, permissions) &&
            (permissions & ePermissionsReadable) == 0) {
          m_frame_type = eNotAValidFrame;
          UNWIND_LOG(
              log, "the CFA points to a region of memory that is not readable");
          return;
        }
      } else {
        UNWIND_LOG(log, "could not find a row for function offset zero");
        m_frame_type = eNotAValidFrame;
        return;
      }

      if (CheckIfLoopingStack()) {
        TryFallbackUnwindPlan();
        if (CheckIfLoopingStack()) {
          UNWIND_LOG(log, "same CFA address as next frame, assuming the unwind "
                          "is looping - stopping");
          m_frame_type = eNotAValidFrame;
          return;
        }
      }

      // Give the Architecture a chance to replace the UnwindPlan.
      TryAdoptArchitectureUnwindPlan();

      UNWIND_LOG(log, "initialized frame cfa is {0:x} afa is {1:x}", m_cfa,
                 m_afa);
      return;
    }
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "could not find any symbol for this pc, or a default "
                    "unwind plan, to continue unwind.");
    return;
  }

  m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx);

  if (m_sym_ctx.symbol) {
    UNWIND_LOG(log, "with pc value of {0:x}, symbol name is '{1}'", pc,
               GetSymbolOrFunctionName(m_sym_ctx));
  } else if (m_sym_ctx.function) {
    UNWIND_LOG(log, "with pc value of {0:x}, function name is '{1}'", pc,
               GetSymbolOrFunctionName(m_sym_ctx));
  } else {
    UNWIND_LOG(log, "with pc value of {0:x}, no symbol/function name is known.",
               pc);
  }

  bool decr_pc_and_recompute_addr_range;

  if (!m_sym_ctx_valid) {
    // Always decrement and recompute if the symbol lookup failed
    decr_pc_and_recompute_addr_range = true;
  } else if (GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
             GetNextFrame()->m_frame_type == eDebuggerFrame) {
    // Don't decrement if we're "above" an asynchronous event like
    // sigtramp.
    decr_pc_and_recompute_addr_range = false;
  } else if (Address addr = m_sym_ctx.GetFunctionOrSymbolAddress();
             addr != m_current_pc) {
    // If our "current" pc isn't the start of a function, decrement the pc
    // if we're up the stack.
    if (m_behaves_like_zeroth_frame)
      decr_pc_and_recompute_addr_range = false;
    else
      decr_pc_and_recompute_addr_range = true;
  } else if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
    // Signal dispatch may set the return address of the handler it calls to
    // point to the first byte of a return trampoline (like __kernel_rt_sigreturn),
    // so do not decrement and recompute if the symbol we already found is a trap
    // handler.
    decr_pc_and_recompute_addr_range = false;
  } else if (m_behaves_like_zeroth_frame) {
    decr_pc_and_recompute_addr_range = false;
  } else {
    // Decrement to find the function containing the call.
    decr_pc_and_recompute_addr_range = true;
  }

  // We need to back up the pc by 1 byte and re-search for the Symbol to handle
  // the case where the "saved pc" value is pointing to the next function, e.g.
  // if a function ends with a CALL instruction.
  // FIXME this may need to be an architectural-dependent behavior; if so we'll
  // need to add a member function
  // to the ABI plugin and consult that.
  if (decr_pc_and_recompute_addr_range) {
    UNWIND_LOG(log,
               "Backing up the pc value of {0:x} by 1 and re-doing symbol "
               "lookup; old symbol was {1}",
               pc, GetSymbolOrFunctionName(m_sym_ctx));
    Address temporary_pc;
    temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget());
    m_sym_ctx.Clear(false);
    m_sym_ctx_valid = temporary_pc.ResolveFunctionScope(m_sym_ctx);

    UNWIND_LOG(log, "Symbol is now {0}", GetSymbolOrFunctionName(m_sym_ctx));
  }

  // If we were able to find a symbol/function, set addr_range_ptr to the
  // bounds of that symbol/function. else treat the current pc value as the
  // start_pc and record no offset.
  if (m_sym_ctx_valid) {
    m_start_pc = m_sym_ctx.GetFunctionOrSymbolAddress();
    m_current_offset = pc - m_start_pc.GetLoadAddress(&process->GetTarget());
    m_current_offset_backed_up_one = m_current_offset;
    if (decr_pc_and_recompute_addr_range &&
        m_current_offset_backed_up_one != 0) {
      --*m_current_offset_backed_up_one;
      if (m_sym_ctx_valid) {
        m_current_pc.SetLoadAddress(pc - 1, &process->GetTarget());
      }
    }
  } else {
    m_start_pc = m_current_pc;
    m_current_offset = std::nullopt;
    m_current_offset_backed_up_one = std::nullopt;
  }

  if (IsTrapHandlerSymbol(process, m_sym_ctx)) {
    m_frame_type = eTrapHandlerFrame;
  } else {
    // FIXME:  Detect eDebuggerFrame here.
    if (m_frame_type != eSkipFrame) // don't override eSkipFrame
    {
      m_frame_type = eNormalFrame;
    }
  }

  const UnwindPlan::Row *active_row;
  RegisterKind row_register_kind = eRegisterKindGeneric;

  // If we have LanguageRuntime UnwindPlan for this unwind, use those
  // rules to find the caller frame instead of the function's normal
  // UnwindPlans.  The full unwind plan for this frame will be
  // the LanguageRuntime-provided unwind plan, and there will not be a
  // fast unwind plan.
  if (lang_runtime_plan_sp.get()) {
    active_row =
        lang_runtime_plan_sp->GetRowForFunctionOffset(m_current_offset);
    row_register_kind = lang_runtime_plan_sp->GetRegisterKind();
    if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(),
                          m_cfa)) {
      UNWIND_LOG(log, "Cannot set cfa");
    } else {
      m_full_unwind_plan_sp = lang_runtime_plan_sp;
      if (log) {
        StreamString active_row_strm;
        active_row->Dump(active_row_strm, lang_runtime_plan_sp.get(), &m_thread,
                         m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
        UNWIND_LOG(log, "async active row: {0}", active_row_strm.GetString());
      }
      UNWIND_LOG(log, "m_cfa = {0:x} m_afa = {1:x}", m_cfa, m_afa);
      UNWIND_LOG(log,
                 "initialized async frame current pc is {0:x} cfa is {1:x} afa "
                 "is {2:x}",
                 m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), m_cfa,
                 m_afa);

      return;
    }
  }

  // We've set m_frame_type and m_sym_ctx before this call.
  m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame();

  // Try to get by with just the fast UnwindPlan if possible - the full
  // UnwindPlan may be expensive to get (e.g. if we have to parse the entire
  // eh_frame section of an ObjectFile for the first time.)

  if (m_fast_unwind_plan_sp &&
      m_fast_unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
    active_row =
        m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
    row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind();
    PropagateTrapHandlerFlagFromUnwindPlan(m_fast_unwind_plan_sp);
    if (active_row && log) {
      StreamString active_row_strm;
      active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread,
                       m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
      UNWIND_LOG(log, "Using fast unwind plan '{0}'",
                 m_fast_unwind_plan_sp->GetSourceName());
      UNWIND_LOG(log, "active row: {0}", active_row_strm.GetString());
    }
  } else {
    m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
    if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp)) {
      active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset(
          m_current_offset_backed_up_one);
      row_register_kind = m_full_unwind_plan_sp->GetRegisterKind();
      PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
      if (active_row && log) {
        StreamString active_row_strm;
        active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
                         &m_thread,
                         m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
        UNWIND_LOG(log, "Using full unwind plan '{0}'",
                   m_full_unwind_plan_sp->GetSourceName());
        UNWIND_LOG(log, "active row: {0}", active_row_strm.GetString());
      }
    }
  }

  if (!active_row) {
    m_frame_type = eNotAValidFrame;
    UNWIND_LOG(log, "could not find unwind row for this pc");
    return;
  }

  if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) {
    UNWIND_LOG(log, "failed to get cfa");
    m_frame_type = eNotAValidFrame;
    return;
  }

  ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa);

  UNWIND_LOG(log, "m_cfa = {0:x} m_afa = {1:x}", m_cfa, m_afa);

  if (CheckIfLoopingStack()) {
    TryFallbackUnwindPlan();
    if (CheckIfLoopingStack()) {
      UNWIND_LOG(log, "same CFA address as next frame, assuming the unwind is "
                      "looping - stopping");
      m_frame_type = eNotAValidFrame;
      return;
    }
  }

  // Give the Architecture a chance to replace the UnwindPlan.
  TryAdoptArchitectureUnwindPlan();

  UNWIND_LOG(log,
             "initialized frame current pc is {0:x} cfa is {1:x} afa is {2:x}",
             m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), m_cfa, m_afa);
}

bool RegisterContextUnwind::CheckIfLoopingStack() {
  // If we have a bad stack setup, we can get the same CFA value multiple times
  // -- or even more devious, we can actually oscillate between two CFA values.
  // Detect that here and break out to avoid a possible infinite loop in lldb
  // trying to unwind the stack. To detect when we have the same CFA value
  // multiple times, we compare the
  // CFA of the current
  // frame with the 2nd next frame because in some specail case (e.g. signal
  // hanlders, hand written assembly without ABI compliance) we can have 2
  // frames with the same
  // CFA (in theory we
  // can have arbitrary number of frames with the same CFA, but more then 2 is
  // very unlikely)

  RegisterContextUnwind::SharedPtr next_frame = GetNextFrame();
  if (next_frame) {
    RegisterContextUnwind::SharedPtr next_next_frame =
        next_frame->GetNextFrame();
    addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
    if (next_next_frame && next_next_frame->GetCFA(next_next_frame_cfa)) {
      if (next_next_frame_cfa == m_cfa) {
        // We have a loop in the stack unwind
        return true;
      }
    }
  }
  return false;
}

bool RegisterContextUnwind::IsFrameZero() const { return m_frame_number == 0; }

bool RegisterContextUnwind::BehavesLikeZerothFrame() const {
  if (m_frame_number == 0)
    return true;
  if (m_behaves_like_zeroth_frame)
    return true;
  return false;
}

// Find a fast unwind plan for this frame, if possible.
//
// On entry to this method,
//
//   1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
//   if either of those are correct,
//   2. m_sym_ctx should already be filled in, and
//   3. m_current_pc should have the current pc value for this frame
//   4. m_current_offset_backed_up_one should have the current byte offset into
//   the function, maybe backed up by 1, std::nullopt if unknown

std::shared_ptr<const UnwindPlan>
RegisterContextUnwind::GetFastUnwindPlanForFrame() {
  ModuleSP pc_module_sp(m_current_pc.GetModule());

  if (!m_current_pc.IsValid() || !pc_module_sp ||
      pc_module_sp->GetObjectFile() == nullptr)
    return nullptr;

  if (IsFrameZero())
    return nullptr;

  FuncUnwindersSP func_unwinders_sp(
      pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
          m_current_pc, m_sym_ctx));
  if (!func_unwinders_sp)
    return nullptr;

  // If we're in _sigtramp(), unwinding past this frame requires special
  // knowledge.
  if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
    return nullptr;

  if (std::shared_ptr<const UnwindPlan> unwind_plan_sp =
          func_unwinders_sp->GetUnwindPlanFastUnwind(
              *m_thread.CalculateTarget(), m_thread)) {
    if (unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
      m_frame_type = eNormalFrame;
      return unwind_plan_sp;
    }
  }
  return nullptr;
}

// On entry to this method,
//
//   1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame
//   if either of those are correct,
//   2. m_sym_ctx should already be filled in, and
//   3. m_current_pc should have the current pc value for this frame
//   4. m_current_offset_backed_up_one should have the current byte offset into
//   the function, maybe backed up by 1, std::nullopt if unknown

std::shared_ptr<const UnwindPlan>
RegisterContextUnwind::GetFullUnwindPlanForFrame() {
  Log *log = GetLog(LLDBLog::Unwind);
  std::shared_ptr<const UnwindPlan> arch_default_unwind_plan_sp;
  ExecutionContext exe_ctx(m_thread.shared_from_this());
  Process *process = exe_ctx.GetProcessPtr();
  ABI *abi = process ? process->GetABI().get() : nullptr;
  if (abi) {
    arch_default_unwind_plan_sp = abi->CreateDefaultUnwindPlan();
    assert(((!arch_default_unwind_plan_sp ||
             arch_default_unwind_plan_sp->GetRowCount() == 0 ||
             arch_default_unwind_plan_sp->GetRowAtIndex(0)
                 ->GetUnspecifiedRegistersAreUndefined())) &&
           "Default UnwindPlan must set "
           "UnspecifiedRegistersAreUndefined to true");
  } else {
    UNWIND_LOG(
        log, "unable to get architectural default UnwindPlan from ABI plugin");
  }

  if (IsFrameZero() || GetNextFrame()->m_frame_type == eTrapHandlerFrame ||
      GetNextFrame()->m_frame_type == eDebuggerFrame) {
    m_behaves_like_zeroth_frame = true;
    // If this frame behaves like a 0th frame (currently executing or
    // interrupted asynchronously), all registers can be retrieved.
    m_all_registers_available = true;
  }

  // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer)
  // so the pc is 0x0 in the zeroth frame, we need to use the "unwind at first
  // instruction" arch default UnwindPlan Also, if this Process can report on
  // memory region attributes, any non-executable region means we jumped
  // through a bad function pointer - handle the same way as 0x0. Note, if we
  // have a symbol context & a symbol, we don't want to follow this code path.
  // This is for jumping to memory regions without any information available.

  if ((!m_sym_ctx_valid ||
       (m_sym_ctx.function == nullptr && m_sym_ctx.symbol == nullptr)) &&
      m_behaves_like_zeroth_frame && m_current_pc.IsValid()) {
    uint32_t permissions;
    addr_t current_pc_addr =
        m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr());
    if (current_pc_addr == 0 ||
        (process &&
         process->GetLoadAddressPermissions(current_pc_addr, permissions) &&
         (permissions & ePermissionsExecutable) == 0)) {
      if (abi) {
        m_frame_type = eNormalFrame;
        return abi->CreateFunctionEntryUnwindPlan();
      }
    }
  }

  // No Module for the current pc, try using the architecture default unwind.
  ModuleSP pc_module_sp(m_current_pc.GetModule());
  if (!m_current_pc.IsValid() || !pc_module_sp ||
      pc_module_sp->GetObjectFile() == nullptr) {
    m_frame_type = eNormalFrame;
    return arch_default_unwind_plan_sp;
  }

  // Function outlining is a clang feature where common blocks of instructions
  // from separate functions can be put in a separate utility function, and
  // the original functions call into the utility function to execute them,
  // resulting in fewer bytes used for the code section overall.
  //
  // The call to the OUTLINED_FUNCTION may not be a normal ABI call (e.g.
  // on RISCV it might be called `jal t0, OUTLINED_FUNCTION_<nn>` putting the
  // return address in a temporary register instead of $ra).  The unwind
  // instructions in eh_frame/debug_frame are not correct today for an
  // OUTLINED_FUNCTION, even when a normal ABI call is made.
  // CFI may be absent or incorrect; instruction emulation may be incorrect
  // because it assumes a normal ABI call was made.
  if (m_sym_ctx_valid && arch_default_unwind_plan_sp) {
    if (IsClangOutlinedFunction(m_sym_ctx)) {
      UNWIND_LOG(log,
                 "Overriding full unwind plan, using architectural default for "
                 "function {0}",
                 GetSymbolOrFunctionName(m_sym_ctx));
      return arch_default_unwind_plan_sp;
    }
  }

  FuncUnwindersSP func_unwinders_sp;
  if (m_sym_ctx_valid) {
    func_unwinders_sp =
        pc_module_sp->GetUnwindTable().GetFuncUnwindersContainingAddress(
            m_current_pc, m_sym_ctx);
  }

  // No FuncUnwinders available for this pc (stripped function symbols, lldb
  // could not augment its function table with another source, like
  // LC_FUNCTION_STARTS or eh_frame in ObjectFileMachO). See if eh_frame or the
  // .ARM.exidx tables have unwind information for this address, else fall back
  // to the architectural default unwind.
  if (!func_unwinders_sp) {
    m_frame_type = eNormalFrame;

    if (!pc_module_sp || !pc_module_sp->GetObjectFile() ||
        !m_current_pc.IsValid())
      return arch_default_unwind_plan_sp;

    // Even with -fomit-frame-pointer, we can try eh_frame to get back on
    // track.
    if (DWARFCallFrameInfo *eh_frame =
            pc_module_sp->GetUnwindTable().GetEHFrameInfo()) {
      if (std::unique_ptr<UnwindPlan> plan_up =
              eh_frame->GetUnwindPlan(m_current_pc))
        return plan_up;
    }

    ArmUnwindInfo *arm_exidx =
        pc_module_sp->GetUnwindTable().GetArmUnwindInfo();
    if (arm_exidx) {
      auto unwind_plan_sp =
          std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
      if (arm_exidx->GetUnwindPlan(exe_ctx.GetTargetRef(), m_current_pc,
                                   *unwind_plan_sp))
        return unwind_plan_sp;
    }

    CallFrameInfo *object_file_unwind =
        pc_module_sp->GetUnwindTable().GetObjectFileUnwindInfo();
    if (object_file_unwind) {
      if (std::unique_ptr<UnwindPlan> plan_up =
              object_file_unwind->GetUnwindPlan(m_current_pc))
        return plan_up;
    }

    return arch_default_unwind_plan_sp;
  }

  if (m_frame_type == eTrapHandlerFrame && process) {
    m_fast_unwind_plan_sp.reset();

    // On some platforms the unwind information for signal handlers is not
    // present or correct. Give the platform plugins a chance to provide
    // substitute plan. Otherwise, use eh_frame.
    if (m_sym_ctx_valid) {
      lldb::PlatformSP platform = process->GetTarget().GetPlatform();
      const ArchSpec arch = process->GetTarget().GetArchitecture();
      if (auto unwind_plan_sp = platform->GetTrapHandlerUnwindPlan(
              arch, GetSymbolOrFunctionName(m_sym_ctx)))
        return unwind_plan_sp;
    }

    auto unwind_plan_sp =
        func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
    if (!unwind_plan_sp)
      unwind_plan_sp =
          func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
        unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
      return unwind_plan_sp;
    }
  }

  // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame
  // even when it's frame zero This comes up if we have hand-written functions
  // in a Module and hand-written eh_frame.  The assembly instruction
  // inspection may fail and the eh_frame CFI were probably written with some
  // care to do the right thing.  It'd be nice if there was a way to ask the
  // eh_frame directly if it is asynchronous (can be trusted at every
  // instruction point) or synchronous (the normal case - only at call sites).
  // But there is not.
  if (process && process->GetDynamicLoader() &&
      process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo(m_sym_ctx)) {
    // We must specifically call the GetEHFrameUnwindPlan() method here --
    // normally we would call GetUnwindPlanAtCallSite() -- because CallSite may
    // return an unwind plan sourced from either eh_frame (that's what we
    // intend) or compact unwind (this won't work)
    auto unwind_plan_sp =
        func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
    if (!unwind_plan_sp)
      unwind_plan_sp =
          func_unwinders_sp->GetObjectFileUnwindPlan(process->GetTarget());
    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
      UNWIND_LOG_VERBOSE(log,
                         "frame uses {0} for full UnwindPlan because the "
                         "DynamicLoader suggested we prefer it",
                         unwind_plan_sp->GetSourceName());
      return unwind_plan_sp;
    }
  }

  // Typically the NonCallSite UnwindPlan is the unwind created by inspecting
  // the assembly language instructions
  if (m_behaves_like_zeroth_frame && process) {
    auto unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
        process->GetTarget(), m_thread);
    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
      if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
        // We probably have an UnwindPlan created by inspecting assembly
        // instructions. The assembly profilers work really well with compiler-
        // generated functions but hand- written assembly can be problematic.
        // We set the eh_frame based unwind plan as our fallback unwind plan if
        // instruction emulation doesn't work out even for non call sites if it
        // is available and use the architecture default unwind plan if it is
        // not available. The eh_frame unwind plan is more reliable even on non
        // call sites then the architecture default plan and for hand written
        // assembly code it is often written in a way that it valid at all
        // location what helps in the most common cases when the instruction
        // emulation fails.
        std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
            func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
                                                       m_thread);
        if (call_site_unwind_plan &&
            call_site_unwind_plan.get() != unwind_plan_sp.get() &&
            call_site_unwind_plan->GetSourceName() !=
                unwind_plan_sp->GetSourceName()) {
          m_fallback_unwind_plan_sp = call_site_unwind_plan;
        } else {
          m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
        }
      }
      UNWIND_LOG_VERBOSE(
          log,
          "frame uses {0} for full UnwindPlan because this is the non-call "
          "site unwind plan and this is a zeroth frame",
          unwind_plan_sp->GetSourceName());
      return unwind_plan_sp;
    }

    // If we're on the first instruction of a function, and we have an
    // architectural default UnwindPlan for the initial instruction of a
    // function, use that.
    if (m_current_offset == 0) {
      unwind_plan_sp =
          func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry(
              m_thread);
      if (unwind_plan_sp) {
        UNWIND_LOG_VERBOSE(log,
                           "frame uses {0} for full UnwindPlan because we are "
                           "at the first instruction of a function",
                           unwind_plan_sp->GetSourceName());
        return unwind_plan_sp;
      }
    }
  }

  std::shared_ptr<const UnwindPlan> unwind_plan_sp;
  // Typically this is unwind info from an eh_frame section intended for
  // exception handling; only valid at call sites
  if (process) {
    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
        process->GetTarget(), m_thread);
  }
  if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) {
    UNWIND_LOG_VERBOSE(log,
                       "frame uses {0} for full UnwindPlan because this is the "
                       "call-site unwind plan",
                       unwind_plan_sp->GetSourceName());
    return unwind_plan_sp;
  }

  // We'd prefer to use an UnwindPlan intended for call sites when we're at a
  // call site but if we've struck out on that, fall back to using the non-
  // call-site assembly inspection UnwindPlan if possible.
  if (process) {
    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
        process->GetTarget(), m_thread);
  }
  if (unwind_plan_sp &&
      unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
    // We probably have an UnwindPlan created by inspecting assembly
    // instructions. The assembly profilers work really well with compiler-
    // generated functions but hand- written assembly can be problematic. We
    // set the eh_frame based unwind plan as our fallback unwind plan if
    // instruction emulation doesn't work out even for non call sites if it is
    // available and use the architecture default unwind plan if it is not
    // available. The eh_frame unwind plan is more reliable even on non call
    // sites then the architecture default plan and for hand written assembly
    // code it is often written in a way that it valid at all location what
    // helps in the most common cases when the instruction emulation fails.
    std::shared_ptr<const UnwindPlan> call_site_unwind_plan =
        func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(),
                                                   m_thread);
    if (call_site_unwind_plan &&
        call_site_unwind_plan.get() != unwind_plan_sp.get() &&
        call_site_unwind_plan->GetSourceName() !=
            unwind_plan_sp->GetSourceName()) {
      m_fallback_unwind_plan_sp = call_site_unwind_plan;
    } else {
      m_fallback_unwind_plan_sp = arch_default_unwind_plan_sp;
    }
  }

  if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp)) {
    UNWIND_LOG_VERBOSE(log,
                       "frame uses {0} for full UnwindPlan because we failed "
                       "to find a call-site unwind plan that would work",
                       unwind_plan_sp->GetSourceName());
    return unwind_plan_sp;
  }

  // If nothing else, use the architectural default UnwindPlan and hope that
  // does the job.
  if (arch_default_unwind_plan_sp)
    UNWIND_LOG_VERBOSE(log,
                       "frame uses {0} for full UnwindPlan because we are "
                       "falling back to the arch default plan",
                       arch_default_unwind_plan_sp->GetSourceName());
  else
    UNWIND_LOG(log,
               "Unable to find any UnwindPlan for full unwind of this frame.");

  return arch_default_unwind_plan_sp;
}

void RegisterContextUnwind::InvalidateAllRegisters() {
  m_frame_type = eNotAValidFrame;
}

size_t RegisterContextUnwind::GetRegisterCount() {
  return m_thread.GetRegisterContext()->GetRegisterCount();
}

const RegisterInfo *RegisterContextUnwind::GetRegisterInfoAtIndex(size_t reg) {
  return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}

size_t RegisterContextUnwind::GetRegisterSetCount() {
  return m_thread.GetRegisterContext()->GetRegisterSetCount();
}

const RegisterSet *RegisterContextUnwind::GetRegisterSet(size_t reg_set) {
  return m_thread.GetRegisterContext()->GetRegisterSet(reg_set);
}

uint32_t RegisterContextUnwind::ConvertRegisterKindToRegisterNumber(
    lldb::RegisterKind kind, uint32_t num) {
  return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
      kind, num);
}

bool RegisterContextUnwind::ReadRegisterValueFromRegisterLocation(
    lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc,
    const RegisterInfo *reg_info, RegisterValue &value) {
  if (!IsValid())
    return false;
  bool success = false;

  switch (regloc.type) {
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterInLiveRegisterContext: {
    const RegisterInfo *other_reg_info =
        GetRegisterInfoAtIndex(regloc.location.register_number);

    if (!other_reg_info)
      return false;

    success =
        m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
  } break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister: {
    const RegisterInfo *other_reg_info =
        GetRegisterInfoAtIndex(regloc.location.register_number);

    if (!other_reg_info)
      return false;

    if (IsFrameZero()) {
      success =
          m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
    } else {
      success = GetNextFrame()->ReadRegister(other_reg_info, value);
    }
  } break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterIsRegisterPlusOffset: {
    auto regnum = regloc.location.reg_plus_offset.register_number;
    const RegisterInfo *other_reg_info =
        GetRegisterInfoAtIndex(regloc.location.reg_plus_offset.register_number);

    if (!other_reg_info)
      return false;

    if (IsFrameZero()) {
      success =
          m_thread.GetRegisterContext()->ReadRegister(other_reg_info, value);
    } else {
      success = GetNextFrame()->ReadRegister(other_reg_info, value);
    }
    if (success) {
      Log *log = GetLog(LLDBLog::Unwind);
      UNWIND_LOG(log, "read ({0})'s location", regnum);
      value = value.GetAsUInt64(~0ull, &success) +
              regloc.location.reg_plus_offset.offset;
      UNWIND_LOG(log, "success {0}", success ? "yes" : "no");
    }
  } break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred:
    success =
        value.SetUInt(regloc.location.inferred_value, reg_info->byte_size);
    break;

  case UnwindLLDB::ConcreteRegisterLocation::eRegisterNotSaved:
    break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtHostMemoryLocation:
    llvm_unreachable("FIXME debugger inferior function call unwind");
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation: {
    Status error(ReadRegisterValueFromMemory(
        reg_info, regloc.location.target_memory_location, reg_info->byte_size,
        value));
    success = error.Success();
  } break;
  default:
    llvm_unreachable("Unknown ConcreteRegisterLocation type.");
  }
  return success;
}

bool RegisterContextUnwind::WriteRegisterValueToRegisterLocation(
    lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc,
    const RegisterInfo *reg_info, const RegisterValue &value) {
  if (!IsValid())
    return false;

  bool success = false;

  switch (regloc.type) {
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterInLiveRegisterContext: {
    const RegisterInfo *other_reg_info =
        GetRegisterInfoAtIndex(regloc.location.register_number);
    success =
        m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
  } break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister: {
    const RegisterInfo *other_reg_info =
        GetRegisterInfoAtIndex(regloc.location.register_number);
    if (IsFrameZero()) {
      success =
          m_thread.GetRegisterContext()->WriteRegister(other_reg_info, value);
    } else {
      success = GetNextFrame()->WriteRegister(other_reg_info, value);
    }
  } break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterIsRegisterPlusOffset:
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred:
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterNotSaved:
    break;
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtHostMemoryLocation:
    llvm_unreachable("FIXME debugger inferior function call unwind");
  case UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation: {
    Status error(WriteRegisterValueToMemory(
        reg_info, regloc.location.target_memory_location, reg_info->byte_size,
        value));
    success = error.Success();
  } break;
  default:
    llvm_unreachable("Unknown ConcreteRegisterLocation type.");
  }
  return success;
}

bool RegisterContextUnwind::IsValid() const {
  return m_frame_type != eNotAValidFrame;
}

// After the final stack frame in a stack walk we'll get one invalid
// (eNotAValidFrame) stack frame -- one past the end of the stack walk.  But
// higher-level code will need to tell the difference between "the unwind plan
// below this frame failed" versus "we successfully completed the stack walk"
// so this method helps to disambiguate that.

bool RegisterContextUnwind::IsTrapHandlerFrame() const {
  return m_frame_type == eTrapHandlerFrame;
}

// A skip frame is a bogus frame on the stack -- but one where we're likely to
// find a real frame farther
// up the stack if we keep looking.  It's always the second frame in an unwind
// (i.e. the first frame after frame zero) where unwinding can be the
// trickiest.  Ideally we'll mark up this frame in some way so the user knows
// we're displaying bad data and we may have skipped one frame of their real
// program in the process of getting back on track.

bool RegisterContextUnwind::IsSkipFrame() const {
  return m_frame_type == eSkipFrame;
}

bool RegisterContextUnwind::IsTrapHandlerSymbol(
    lldb_private::Process *process,
    const lldb_private::SymbolContext &m_sym_ctx) const {
  PlatformSP platform_sp(process->GetTarget().GetPlatform());
  if (platform_sp) {
    const std::vector<ConstString> trap_handler_names(
        platform_sp->GetTrapHandlerSymbolNames());
    for (ConstString name : trap_handler_names) {
      if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
          (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
        return true;
      }
    }
  }
  const std::vector<ConstString> user_specified_trap_handler_names(
      m_parent_unwind.GetUserSpecifiedTrapHandlerFunctionNames());
  for (ConstString name : user_specified_trap_handler_names) {
    if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
        (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == name)) {
      return true;
    }
  }

  return false;
}

// Search this stack frame's UnwindPlans for the AbstractRegisterLocation
// for this register.
//
// \param[in] lldb_regnum
//     The register number (in the eRegisterKindLLDB register numbering)
//     we are searching for.
//
// \param[out] kind
//     Set to the RegisterKind of the UnwindPlan which is the basis for
//     the returned AbstractRegisterLocation; if the location is in terms
//     of another register number, this Kind is needed to interpret it
//     correctly.
//
// \return
//     An empty optional indicaTes that there was an error in processing
//     the request.
//
//     If there is no unwind rule for a volatile (caller-preserved) register,
//     the returned AbstractRegisterLocation will be IsUndefined,
//     indicating that we should stop searching.
//
//     If there is no unwind rule for a non-volatile (callee-preserved)
//     register, the returned AbstractRegisterLocation will be IsSame.
//     In frame 0, IsSame means get the value from the live register context.
//     Else it means to continue descending down the stack to more-live frames
//     looking for a location/value.
//
//     If an AbstractRegisterLocation is found in an UnwindPlan, that will
//     be returned, with no consideration of the current ABI rules for
//     registers.  Functions using an alternate ABI calling convention
//     will work as long as the UnwindPlans are exhaustive about what
//     registers are volatile/non-volatile.
std::optional<UnwindPlan::Row::AbstractRegisterLocation>
RegisterContextUnwind::GetAbstractRegisterLocation(uint32_t lldb_regnum,
                                                   lldb::RegisterKind &kind) {
  RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum);
  Log *log = GetLog(LLDBLog::Unwind);

  kind = eRegisterKindLLDB;
  UnwindPlan::Row::AbstractRegisterLocation unwindplan_regloc;

  // First, try to find a register location via the FastUnwindPlan
  if (m_fast_unwind_plan_sp) {
    const UnwindPlan::Row *active_row =
        m_fast_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
    if (regnum.GetAsKind(kind) == LLDB_INVALID_REGNUM) {
      UNWIND_LOG(log,
                 "could not convert lldb regnum {0} ({1}) into {2} "
                 "RegisterKind reg numbering scheme",
                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), kind);
      return {};
    }
    kind = m_fast_unwind_plan_sp->GetRegisterKind();
    // The Fast UnwindPlan typically only provides fp & pc as we move up
    // the stack, without requiring additional parsing or memory reads.
    // It may mark all other registers as IsUndefined() because, indicating
    // that it doesn't know if they were spilled to stack or not.
    // If this case, for an IsUndefined register, we should continue on
    // to the Full UnwindPlan which may have more accurate information
    // about register locations of all registers.
    if (active_row &&
        active_row->GetRegisterInfo(regnum.GetAsKind(kind),
                                    unwindplan_regloc) &&
        !unwindplan_regloc.IsUndefined()) {
      UNWIND_LOG(
          log,
          "supplying caller's saved {0} ({1})'s location using FastUnwindPlan",
          regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      return unwindplan_regloc;
    }
  }

  // Second, try to find a register location via the FullUnwindPlan.
  bool got_new_full_unwindplan = false;
  if (!m_full_unwind_plan_sp) {
    m_full_unwind_plan_sp = GetFullUnwindPlanForFrame();
    got_new_full_unwindplan = true;
  }
  if (m_full_unwind_plan_sp) {
    RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
                             LLDB_REGNUM_GENERIC_PC);

    const UnwindPlan::Row *active_row =
        m_full_unwind_plan_sp->GetRowForFunctionOffset(
            m_current_offset_backed_up_one);
    kind = m_full_unwind_plan_sp->GetRegisterKind();

    if (got_new_full_unwindplan && active_row && log) {
      StreamString active_row_strm;
      ExecutionContext exe_ctx(m_thread.shared_from_this());
      active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread,
                       m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr()));
      UNWIND_LOG(log, "Using full unwind plan '{0}'",
                 m_full_unwind_plan_sp->GetSourceName());
      UNWIND_LOG(log, "active row: {0}", active_row_strm.GetString());
    }

    if (regnum.GetAsKind(kind) == LLDB_INVALID_REGNUM) {
      if (kind == eRegisterKindGeneric)
        UNWIND_LOG(log,
                   "could not convert lldb regnum {0} ({1}) into "
                   "eRegisterKindGeneric reg numbering scheme",
                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      else
        UNWIND_LOG(log,
                   "could not convert lldb regnum {0} ({1}) into {2} "
                   "RegisterKind reg numbering scheme",
                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), kind);
      if (active_row && active_row->GetUnspecifiedRegistersAreUndefined()) {
        UNWIND_LOG(
            log,
            "marking register {0} ({1}) as Undefined (volatile) in this "
            "stack frame because this row is UnspecifiedRegistersAreUndefined.",
            regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
        unwindplan_regloc.SetUndefined();
        return unwindplan_regloc;
      }
      return {};
    }

    if (regnum.IsValid() && active_row &&
        active_row->GetRegisterInfo(regnum.GetAsKind(kind),
                                    unwindplan_regloc)) {
      UNWIND_LOG(
          log,
          "supplying caller's saved {0} ({1})'s location using {2} UnwindPlan",
          regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
          m_full_unwind_plan_sp->GetSourceName());
      return unwindplan_regloc;
    }

    // When asking for the caller's pc, and did not find a register
    // location for PC above in the UnwindPlan.  Check if we have a
    // Return Address register on this target.
    //
    // On a Return Address Register architecture like arm/mips/riscv,
    // the caller's pc is in the RA register, and will be spilled to
    // stack before any other function is called.  If no function
    // has been called yet, the return address may still be in the
    // live RA reg.
    //
    // There's a lot of variety of what we might see in an UnwindPlan.
    // We may have
    //   ra=IsSame {unncessary}
    //   ra=StackAddr {caller's return addr spilled to stack}
    // or no reg location for pc or ra at all, in a frameless function -
    // the caller's return address is in live ra reg.
    //
    // If a function has been interrupted in a non-call way --
    // async signal/sigtramp, or a hardware exception / interrupt / fault --
    // then the "pc" and "ra" are two distinct values, and must be
    // handled separately.  The "pc" is the pc value at the point
    // the function was interrupted.  The "ra" is the return address
    // register value at that point.
    // The UnwindPlan for the sigtramp/trap handler will normally have
    // register loations for both pc and lr, and so we'll have already
    // fetched them above.
    if (pc_regnum.IsValid() && pc_regnum == regnum) {
      uint32_t return_address_regnum = LLDB_INVALID_REGNUM;

      // Get the return address register number from the UnwindPlan
      // or the register set definition.
      if (m_full_unwind_plan_sp->GetReturnAddressRegister() !=
          LLDB_INVALID_REGNUM) {
        return_address_regnum =
            m_full_unwind_plan_sp->GetReturnAddressRegister();
      } else {
        RegisterNumber arch_default_ra_regnum(m_thread, eRegisterKindGeneric,
                                              LLDB_REGNUM_GENERIC_RA);
        return_address_regnum = arch_default_ra_regnum.GetAsKind(kind);
      }

      // This system is using a return address register.
      if (return_address_regnum != LLDB_INVALID_REGNUM) {
        RegisterNumber return_address_reg;
        return_address_reg.init(m_thread,
                                m_full_unwind_plan_sp->GetRegisterKind(),
                                return_address_regnum);
        UNWIND_LOG(log,
                   "requested caller's saved PC but this UnwindPlan uses a RA "
                   "reg; getting {0} ({1}) instead",
                   return_address_reg.GetName(),
                   return_address_reg.GetAsKind(eRegisterKindLLDB));

        // Do we have a location for the ra register?
        if (active_row &&
            active_row->GetRegisterInfo(return_address_reg.GetAsKind(kind),
                                        unwindplan_regloc)) {
          UNWIND_LOG(log,
                     "supplying caller's saved {0} ({1})'s location using {2} "
                     "UnwindPlan",
                     return_address_reg.GetName(),
                     return_address_reg.GetAsKind(eRegisterKindLLDB),
                     m_full_unwind_plan_sp->GetSourceName());
          // If we have "ra=IsSame", rewrite to "ra=InRegister(ra)" because the
          // calling function thinks it is fetching "pc" and if we return an
          // IsSame register location, it will try to read pc.
          if (unwindplan_regloc.IsSame())
            unwindplan_regloc.SetInRegister(return_address_reg.GetAsKind(kind));
          return unwindplan_regloc;
        } else {
          // No unwind rule for the return address reg on frame 0, or an
          // interrupted function, means that the caller's address is still in
          // RA reg (0th frame) or the trap handler below this one (sigtramp
          // etc) has a save location for the RA reg.
          if (BehavesLikeZerothFrame()) {
            unwindplan_regloc.SetInRegister(return_address_reg.GetAsKind(kind));
            return unwindplan_regloc;
          }
        }
      }
    }
    if (active_row && active_row->GetUnspecifiedRegistersAreUndefined()) {
      UNWIND_LOG(
          log,
          "marking register {0} ({1}) as Undefined (volatile) in this "
          "stack frame because this row is UnspecifiedRegistersAreUndefined.",
          regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      unwindplan_regloc.SetUndefined();
      return unwindplan_regloc;
    }
  }

  ExecutionContext exe_ctx(m_thread.shared_from_this());
  Process *process = exe_ctx.GetProcessPtr();

  // Third, try finding a register location via the ABI
  // FallbackRegisterLocation.
  //
  // If the UnwindPlan failed to give us an unwind location for this
  // register, we may be able to fall back to some ABI-defined default.  For
  // example, some ABIs allow to determine the caller's SP via the CFA. Also,
  // the ABI willset volatile registers to the undefined state.
  ABI *abi = process ? process->GetABI().get() : nullptr;
  if (abi) {
    const RegisterInfo *reg_info =
        GetRegisterInfoAtIndex(regnum.GetAsKind(eRegisterKindLLDB));
    if (reg_info &&
        abi->GetFallbackRegisterLocation(reg_info, unwindplan_regloc)) {
      if (!unwindplan_regloc.IsUndefined())
        UNWIND_LOG(
            log,
            "supplying caller's saved {0} ({1})'s location using ABI default",
            regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      // ABI defined volatile registers with no register location
      // will be returned as IsUndefined, stopping the search down
      // the stack.
      return unwindplan_regloc;
    }
  }

  // We have no AbstractRegisterLocation, and the ABI says this is a
  // non-volatile / callee-preserved register.  Continue down the stack
  // or to frame 0 & the live RegisterContext.
  std::string unwindplan_name;
  if (m_full_unwind_plan_sp) {
    unwindplan_name += "via '";
    unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString("");
    unwindplan_name += "'";
  }
  UNWIND_LOG(log, "no save location for {0} ({1}) {2}", regnum.GetName(),
             regnum.GetAsKind(eRegisterKindLLDB), unwindplan_name);

  unwindplan_regloc.SetSame();
  return unwindplan_regloc;
}

// Answer the question: Where did THIS frame save the CALLER frame ("previous"
// frame)'s register value?

enum UnwindLLDB::RegisterSearchResult
RegisterContextUnwind::SavedLocationForRegister(
    uint32_t lldb_regnum,
    lldb_private::UnwindLLDB::ConcreteRegisterLocation &regloc) {
  RegisterNumber regnum(m_thread, eRegisterKindLLDB, lldb_regnum);
  Log *log = GetLog(LLDBLog::Unwind);

  // Have we already found this register location?
  if (!m_registers.empty()) {
    auto iterator = m_registers.find(regnum.GetAsKind(eRegisterKindLLDB));
    if (iterator != m_registers.end()) {
      regloc = iterator->second;
      UNWIND_LOG(log, "supplying caller's saved {0} ({1})'s location, cached",
                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }
  }

  RegisterKind abs_regkind;
  std::optional<UnwindPlan::Row::AbstractRegisterLocation> abs_regloc =
      GetAbstractRegisterLocation(lldb_regnum, abs_regkind);

  if (!abs_regloc)
    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;

  if (abs_regloc->IsUndefined()) {
    UNWIND_LOG(
        log, "did not supply reg location for {0} ({1}) because it is volatile",
        regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
    return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
  }

  ExecutionContext exe_ctx(m_thread.shared_from_this());
  Process *process = exe_ctx.GetProcessPtr();
  // abs_regloc has valid contents about where to retrieve the register
  if (abs_regloc->IsUnspecified()) {
    lldb_private::UnwindLLDB::ConcreteRegisterLocation new_regloc = {};
    new_regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterNotSaved;
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = new_regloc;
    UNWIND_LOG(log,
               "save location for {0} ({1}) is unspecified, continue searching",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
  }

  if (abs_regloc->IsSame()) {
    if (IsFrameZero()) {
      regloc.type =
          UnwindLLDB::ConcreteRegisterLocation::eRegisterInLiveRegisterContext;
      regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
      m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
      UNWIND_LOG(log,
                 "supplying caller's register {0} ({1}) from the live "
                 "RegisterContext at frame 0",
                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }
    // PC/RA reg don't follow the usual "callee-saved aka non-volatile" versus
    // "caller saved aka volatile" system.  A stack frame can provide its caller
    // return address, but if we don't find a rule for pc/RA mid-stack, we
    // never want to iterate further down the stack looking for it.
    // Defensively prevent iterating down the stack for these two.
    if (!BehavesLikeZerothFrame() &&
        (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC ||
         regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) {
      UNWIND_LOG(log,
                 "register {0} ({1}) is marked as 'IsSame' - it is a pc or "
                 "return address reg on a frame which does not have all "
                 "registers available -- treat as if we have no information",
                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }

    regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister;
    regloc.location.register_number = regnum.GetAsKind(eRegisterKindLLDB);
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(log,
               "supplying caller's register {0} ({1}) value is unmodified in "
               "this frame",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  if (abs_regloc->IsCFAPlusOffset()) {
    int offset = abs_regloc->GetOffset();
    regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred;
    regloc.location.inferred_value = m_cfa + offset;
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(log,
               "supplying caller's register {0} ({1}), value is CFA plus "
               "offset {2} [value is {3:x}]",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
               regloc.location.inferred_value);
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  if (abs_regloc->IsAtCFAPlusOffset()) {
    int offset = abs_regloc->GetOffset();
    regloc.type =
        UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation;
    regloc.location.target_memory_location = m_cfa + offset;
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(log,
               "supplying caller's register {0} ({1}) from the stack, saved at "
               "CFA plus offset {2} [saved at {3:x}]",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
               regloc.location.target_memory_location);
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  if (abs_regloc->IsAFAPlusOffset()) {
    if (m_afa == LLDB_INVALID_ADDRESS)
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;

    int offset = abs_regloc->GetOffset();
    regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred;
    regloc.location.inferred_value = m_afa + offset;
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(log,
               "supplying caller's register {0} ({1}), value is AFA plus "
               "offset {2} [value is {3:x}]",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
               regloc.location.inferred_value);
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  if (abs_regloc->IsAtAFAPlusOffset()) {
    if (m_afa == LLDB_INVALID_ADDRESS)
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;

    int offset = abs_regloc->GetOffset();
    regloc.type =
        UnwindLLDB::ConcreteRegisterLocation::eRegisterSavedAtMemoryLocation;
    regloc.location.target_memory_location = m_afa + offset;
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(log,
               "supplying caller's register {0} ({1}) from the stack, saved at "
               "AFA plus offset {2} [saved at {3:x}]",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset,
               regloc.location.target_memory_location);
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  if (abs_regloc->IsInOtherRegister()) {
    RegisterNumber row_regnum(m_thread, abs_regkind,
                              abs_regloc->GetRegisterNumber());
    if (row_regnum.GetAsKind(eRegisterKindLLDB) == LLDB_INVALID_REGNUM) {
      UNWIND_LOG(log,
                 "could not supply caller's {0} ({1}) location - was saved in "
                 "another reg but couldn't convert that regnum",
                 regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
      return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }
    regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister;
    regloc.location.register_number = row_regnum.GetAsKind(eRegisterKindLLDB);
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(
        log,
        "supplying caller's register {0} ({1}), saved in register {2} ({3})",
        regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB),
        row_regnum.GetName(), row_regnum.GetAsKind(eRegisterKindLLDB));
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  if (abs_regloc->IsDWARFExpression() || abs_regloc->IsAtDWARFExpression()) {
    DataExtractor dwarfdata(abs_regloc->GetDWARFExpressionBytes(),
                            abs_regloc->GetDWARFExpressionLength(),
                            process->GetByteOrder(),
                            process->GetAddressByteSize());
    ModuleSP opcode_ctx;
    DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
    dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(abs_regkind);
    Value cfa_val = Scalar(m_cfa);
    cfa_val.SetValueType(Value::ValueType::LoadAddress);
    llvm::Expected<Value> result =
        dwarfexpr.Evaluate(&exe_ctx, this, 0, &cfa_val, nullptr);
    if (!result) {
      LLDB_LOG_ERROR(log, result.takeError(),
                     "DWARF expression failed to evaluate: {0}");
    } else {
      addr_t val;
      val = result->GetScalar().ULongLong();
      if (abs_regloc->IsDWARFExpression()) {
        regloc.type =
            UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred;
        regloc.location.inferred_value = val;
        m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
        UNWIND_LOG(log,
                   "supplying caller's register {0} ({1}) via DWARF expression "
                   "(IsDWARFExpression)",
                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
      } else {
        regloc.type = UnwindLLDB::ConcreteRegisterLocation::
            eRegisterSavedAtMemoryLocation;
        regloc.location.target_memory_location = val;
        m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
        UNWIND_LOG(log,
                   "supplying caller's register {0} ({1}) via DWARF expression "
                   "(IsAtDWARFExpression)",
                   regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
      }
    }
    UNWIND_LOG(log,
               "tried to use IsDWARFExpression or IsAtDWARFExpression for {0} "
               "({1}) but failed",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
  }

  if (abs_regloc->IsConstant()) {
    regloc.type = UnwindLLDB::ConcreteRegisterLocation::eRegisterValueInferred;
    regloc.location.inferred_value = abs_regloc->GetConstant();
    m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc;
    UNWIND_LOG(log, "supplying caller's register {0} ({1}) via constant value",
               regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));
    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
  }

  UNWIND_LOG(log, "no save location for {0} ({1}) in this stack frame",
             regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB));

  // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are
  // unsupported.

  return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}

UnwindPlanSP RegisterContextUnwind::TryAdoptArchitectureUnwindPlan() {
  if (!m_full_unwind_plan_sp)
    return {};
  ProcessSP process_sp = m_thread.GetProcess();
  if (!process_sp)
    return {};

  UnwindPlanSP arch_override_plan_sp;
  if (Architecture *arch = process_sp->GetTarget().GetArchitecturePlugin())
    arch_override_plan_sp =
        arch->GetArchitectureUnwindPlan(m_thread, this, m_full_unwind_plan_sp);

  if (arch_override_plan_sp) {
    m_full_unwind_plan_sp = arch_override_plan_sp;
    PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
    m_registers.clear();
    if (Log *log = GetLog(LLDBLog::Unwind)) {
      UNWIND_LOG(
          log, "Replacing Full Unwindplan with Architecture UnwindPlan, '{0}'",
          m_full_unwind_plan_sp->GetSourceName());
      const UnwindPlan::Row *active_row =
          m_full_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);
      if (active_row) {
        StreamString active_row_strm;
        active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(),
                         &m_thread,
                         m_start_pc.GetLoadAddress(&process_sp->GetTarget()));
        UNWIND_LOG(log, "{0}", active_row_strm.GetString());
      }
    }
  }

  return {};
}

// TryFallbackUnwindPlan() -- this method is a little tricky.
//
// When this is called, the frame above -- the caller frame, the "previous"
// frame -- is invalid or bad.
//
// Instead of stopping the stack walk here, we'll try a different UnwindPlan
// and see if we can get a valid frame above us.
//
// This most often happens when an unwind plan based on assembly instruction
// inspection is not correct -- mostly with hand-written assembly functions or
// functions where the stack frame is set up "out of band", e.g. the kernel
// saved the register context and then called an asynchronous trap handler like
// _sigtramp.
//
// Often in these cases, if we just do a dumb stack walk we'll get past this
// tricky frame and our usual techniques can continue to be used.

bool RegisterContextUnwind::TryFallbackUnwindPlan() {
  if (m_fallback_unwind_plan_sp == nullptr)
    return false;

  if (m_full_unwind_plan_sp == nullptr)
    return false;

  if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
      m_full_unwind_plan_sp->GetSourceName() ==
          m_fallback_unwind_plan_sp->GetSourceName()) {
    return false;
  }

  // If a compiler generated unwind plan failed, trying the arch default
  // unwindplan isn't going to do any better.
  if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
    return false;

  // Get the caller's pc value and our own CFA value. Swap in the fallback
  // unwind plan, re-fetch the caller's pc value and CFA value. If they're the
  // same, then the fallback unwind plan provides no benefit.

  RegisterNumber pc_regnum(m_thread, eRegisterKindGeneric,
                           LLDB_REGNUM_GENERIC_PC);

  addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS;
  addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS;
  UnwindLLDB::ConcreteRegisterLocation regloc = {};
  if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
                               regloc) ==
      UnwindLLDB::RegisterSearchResult::eRegisterFound) {
    const RegisterInfo *reg_info =
        GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
    if (reg_info) {
      RegisterValue reg_value;
      if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
        old_caller_pc_value = reg_value.GetAsUInt64();
        if (ProcessSP process_sp = m_thread.GetProcess()) {
          if (ABISP abi_sp = process_sp->GetABI())
            old_caller_pc_value = abi_sp->FixCodeAddress(old_caller_pc_value);
        }
      }
    }
  }

  // This is a tricky wrinkle!  If SavedLocationForRegister() detects a really
  // impossible register location for the full unwind plan, it may call
  // ForceSwitchToFallbackUnwindPlan() which in turn replaces the full
  // unwindplan with the fallback... in short, we're done, we're using the
  // fallback UnwindPlan. We checked if m_fallback_unwind_plan_sp was nullptr
  // at the top -- the only way it became nullptr since then is via
  // SavedLocationForRegister().
  if (m_fallback_unwind_plan_sp == nullptr)
    return true;

  // Switch the full UnwindPlan to be the fallback UnwindPlan.  If we decide
  // this isn't working, we need to restore. We'll also need to save & restore
  // the value of the m_cfa ivar.  Save is down below a bit in 'old_cfa'.
  std::shared_ptr<const UnwindPlan> original_full_unwind_plan_sp =
      m_full_unwind_plan_sp;
  addr_t old_cfa = m_cfa;
  addr_t old_afa = m_afa;

  m_registers.clear();

  m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;

  const UnwindPlan::Row *active_row =
      m_fallback_unwind_plan_sp->GetRowForFunctionOffset(
          m_current_offset_backed_up_one);

  Log *log = GetLog(LLDBLog::Unwind);
  if (active_row &&
      active_row->GetCFAValue().GetValueType() !=
          UnwindPlan::Row::FAValue::unspecified) {
    addr_t new_cfa;
    ProcessSP process_sp = m_thread.GetProcess();
    ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr;
    if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
                          active_row->GetCFAValue(), new_cfa) ||
        !CallFrameAddressIsValid(abi_sp, new_cfa)) {
      UNWIND_LOG(log, "failed to get cfa with fallback unwindplan");
      m_fallback_unwind_plan_sp.reset();
      m_full_unwind_plan_sp = original_full_unwind_plan_sp;
      return false;
    }
    m_cfa = new_cfa;

    ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
                     active_row->GetAFAValue(), m_afa);

    if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB),
                                 regloc) ==
        UnwindLLDB::RegisterSearchResult::eRegisterFound) {
      const RegisterInfo *reg_info =
          GetRegisterInfoAtIndex(pc_regnum.GetAsKind(eRegisterKindLLDB));
      if (reg_info) {
        RegisterValue reg_value;
        if (ReadRegisterValueFromRegisterLocation(regloc, reg_info,
                                                  reg_value)) {
          new_caller_pc_value = reg_value.GetAsUInt64();
          if (process_sp)
            new_caller_pc_value =
                process_sp->FixCodeAddress(new_caller_pc_value);
        }
      }
    }

    if (new_caller_pc_value == LLDB_INVALID_ADDRESS) {
      UNWIND_LOG(log, "failed to get a pc value for the caller frame with the "
                      "fallback unwind plan");
      m_fallback_unwind_plan_sp.reset();
      m_full_unwind_plan_sp = original_full_unwind_plan_sp;
      m_cfa = old_cfa;
      m_afa = old_afa;
      return false;
    }

    if (old_caller_pc_value == new_caller_pc_value &&
        m_cfa == old_cfa &&
        m_afa == old_afa) {
      UNWIND_LOG(log, "fallback unwind plan got the same values for this frame "
                      "CFA and caller frame pc, not using");
      m_fallback_unwind_plan_sp.reset();
      m_full_unwind_plan_sp = original_full_unwind_plan_sp;
      return false;
    }

    UNWIND_LOG(log,
               "trying to unwind from this function with the UnwindPlan '{0}' "
               "because UnwindPlan '{1}' failed.",
               m_fallback_unwind_plan_sp->GetSourceName(),
               original_full_unwind_plan_sp->GetSourceName());

    // We've copied the fallback unwind plan into the full - now clear the
    // fallback.
    m_fallback_unwind_plan_sp.reset();
    PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);
  }

  return true;
}

bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() {
  if (m_fallback_unwind_plan_sp == nullptr)
    return false;

  if (m_full_unwind_plan_sp == nullptr)
    return false;

  if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() ||
      m_full_unwind_plan_sp->GetSourceName() ==
          m_fallback_unwind_plan_sp->GetSourceName()) {
    return false;
  }

  const UnwindPlan::Row *active_row =
      m_fallback_unwind_plan_sp->GetRowForFunctionOffset(m_current_offset);

  if (active_row &&
      active_row->GetCFAValue().GetValueType() !=
          UnwindPlan::Row::FAValue::unspecified) {
    addr_t new_cfa;
    ProcessSP process_sp = m_thread.GetProcess();
    ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr;
    if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
                          active_row->GetCFAValue(), new_cfa) ||
        !CallFrameAddressIsValid(abi_sp, new_cfa)) {
      UNWIND_LOG(GetLog(LLDBLog::Unwind),
                 "failed to get cfa with fallback unwindplan");
      m_fallback_unwind_plan_sp.reset();
      return false;
    }

    ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(),
                     active_row->GetAFAValue(), m_afa);

    m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
    m_fallback_unwind_plan_sp.reset();

    m_registers.clear();

    m_cfa = new_cfa;

    PropagateTrapHandlerFlagFromUnwindPlan(m_full_unwind_plan_sp);

    UNWIND_LOG(GetLog(LLDBLog::Unwind),
               "switched unconditionally to the fallback unwindplan {0}",
               m_full_unwind_plan_sp->GetSourceName());
    return true;
  }
  return false;
}

void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(
    std::shared_ptr<const UnwindPlan> unwind_plan) {
  if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
    // Unwind plan does not indicate trap handler.  Do nothing.  We may
    // already be flagged as trap handler flag due to the symbol being
    // in the trap handler symbol list, and that should take precedence.
    return;
  } else if (m_frame_type != eNormalFrame) {
    // If this is already a trap handler frame, nothing to do.
    // If this is a skip or debug or invalid frame, don't override that.
    return;
  }

  m_frame_type = eTrapHandlerFrame;

  Log *log = GetLog(LLDBLog::Unwind);
  UNWIND_LOG(log, "This frame is marked as a trap handler via its UnwindPlan");

  if (m_current_offset_backed_up_one != m_current_offset) {
    // We backed up the pc by 1 to compute the symbol context, but
    // now need to undo that because the pc of the trap handler
    // frame may in fact be the first instruction of a signal return
    // trampoline, rather than the instruction after a call.  This
    // happens on systems where the signal handler dispatch code, rather
    // than calling the handler and being returned to, jumps to the
    // handler after pushing the address of a return trampoline on the
    // stack -- on these systems, when the handler returns, control will
    // be transferred to the return trampoline, so that's the best
    // symbol we can present in the callstack.
    UNWIND_LOG(log,
               "Resetting current offset and re-doing symbol lookup; old "
               "symbol was {0}",
               GetSymbolOrFunctionName(m_sym_ctx));
    m_current_offset_backed_up_one = m_current_offset;

    m_sym_ctx_valid = m_current_pc.ResolveFunctionScope(m_sym_ctx);

    UNWIND_LOG(log, "Symbol is now {0}", GetSymbolOrFunctionName(m_sym_ctx));

    ExecutionContext exe_ctx(m_thread.shared_from_this());
    Process *process = exe_ctx.GetProcessPtr();
    Target *target = &process->GetTarget();

    if (m_sym_ctx_valid) {
      m_start_pc = m_sym_ctx.GetFunctionOrSymbolAddress();
      m_current_offset = m_current_pc.GetLoadAddress(target) -
                         m_start_pc.GetLoadAddress(target);
    }
  }
}

bool RegisterContextUnwind::ReadFrameAddress(
    lldb::RegisterKind row_register_kind, const UnwindPlan::Row::FAValue &fa,
    addr_t &address) {
  RegisterValue reg_value;

  address = LLDB_INVALID_ADDRESS;
  addr_t cfa_reg_contents;
  ABISP abi_sp = m_thread.GetProcess()->GetABI();

  Log *log = GetLog(LLDBLog::Unwind);
  switch (fa.GetValueType()) {
  case UnwindPlan::Row::FAValue::isRegisterDereferenced: {
    UNWIND_LOG(log, "CFA value via dereferencing reg");
    RegisterNumber regnum_to_deref(m_thread, row_register_kind,
                                   fa.GetRegisterNumber());
    addr_t reg_to_deref_contents;
    if (ReadGPRValue(regnum_to_deref, reg_to_deref_contents)) {
      const RegisterInfo *reg_info =
          GetRegisterInfoAtIndex(regnum_to_deref.GetAsKind(eRegisterKindLLDB));
      RegisterValue reg_value;
      if (reg_info) {
        Status error = ReadRegisterValueFromMemory(
            reg_info, reg_to_deref_contents, reg_info->byte_size, reg_value);
        if (error.Success()) {
          address = reg_value.GetAsUInt64();
          UNWIND_LOG(log,
                     "CFA value via dereferencing reg {0} ({1}): reg has val "
                     "{2:x}, CFA value is {3:x}",
                     regnum_to_deref.GetName(),
                     regnum_to_deref.GetAsKind(eRegisterKindLLDB),
                     reg_to_deref_contents, address);
          return true;
        } else {
          UNWIND_LOG(
              log,
              "Tried to deref reg {0} ({1}) [{2:x}] but memory read failed.",
              regnum_to_deref.GetName(),
              regnum_to_deref.GetAsKind(eRegisterKindLLDB),
              reg_to_deref_contents);
        }
      }
    }
    break;
  }
  case UnwindPlan::Row::FAValue::isRegisterPlusOffset: {
    UNWIND_LOG(log, "CFA value via register plus offset");
    RegisterNumber cfa_reg(m_thread, row_register_kind,
                           fa.GetRegisterNumber());
    if (ReadGPRValue(cfa_reg, cfa_reg_contents)) {
      if (!CallFrameAddressIsValid(abi_sp, cfa_reg_contents)) {
        UNWIND_LOG(
            log,
            "Got an invalid CFA register value - reg {0} ({1}), value {2:x}",
            cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
            cfa_reg_contents);
        return false;
      }
      address = cfa_reg_contents + fa.GetOffset();
      UNWIND_LOG(
          log,
          "CFA is {0:x}: Register {1} ({2}) contents are {3:x}, offset is {4}",
          address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB),
          cfa_reg_contents, fa.GetOffset());
      return true;
    }
    UNWIND_LOG(log, "unable to read CFA register {0} ({1})", cfa_reg.GetName(),
               cfa_reg.GetAsKind(eRegisterKindLLDB));
    break;
  }
  case UnwindPlan::Row::FAValue::isDWARFExpression: {
    UNWIND_LOG(log, "CFA value via DWARF expression");
    ExecutionContext exe_ctx(m_thread.shared_from_this());
    Process *process = exe_ctx.GetProcessPtr();
    DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(),
                            fa.GetDWARFExpressionLength(),
                            process->GetByteOrder(),
                            process->GetAddressByteSize());
    ModuleSP opcode_ctx;
    DWARFExpressionList dwarfexpr(opcode_ctx, dwarfdata, nullptr);
    dwarfexpr.GetMutableExpressionAtAddress()->SetRegisterKind(
        row_register_kind);
    llvm::Expected<Value> result =
        dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr);
    if (result) {
      address = result->GetScalar().ULongLong();
      UNWIND_LOG(log, "CFA value set by DWARF expression is {0:x}", address);
      return true;
    }
    LLDB_LOG_ERROR(log, result.takeError(),
                   "Failed to set CFA value via DWARF expression: {0}");
    break;
  }
  case UnwindPlan::Row::FAValue::isRaSearch: {
    UNWIND_LOG(log, "CFA value via heuristic search");
    Process &process = *m_thread.GetProcess();
    lldb::addr_t return_address_hint = GetReturnAddressHint(fa.GetOffset());
    if (return_address_hint == LLDB_INVALID_ADDRESS)
      return false;
    const unsigned max_iterations = 256;
    for (unsigned i = 0; i < max_iterations; ++i) {
      lldb::addr_t candidate_addr =
          return_address_hint + i * process.GetAddressByteSize();
      llvm::Expected<lldb::addr_t> candidate =
          process.ReadPointerFromMemory(candidate_addr);
      if (!candidate) {
        LLDB_LOG_ERROR(log, candidate.takeError(),
                       "Cannot read memory at {1:x}: {0}", candidate_addr);
        return false;
      }
      Address addr;
      uint32_t permissions;
      if (process.GetLoadAddressPermissions(*candidate, permissions) &&
          permissions & lldb::ePermissionsExecutable) {
        address = candidate_addr;
        UNWIND_LOG(log, "Heuristically found CFA: {0:x}", address);
        return true;
      }
    }
    UNWIND_LOG(log, "No suitable CFA found");
    break;
  }
  case UnwindPlan::Row::FAValue::isConstant: {
    address = fa.GetConstant();
    UNWIND_LOG(log, "CFA value set by constant is {0:x}", address);
    return true;
  }
  default:
    return false;
  }
  return false;
}

lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) {
  addr_t hint;
  if (!ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, hint))
    return LLDB_INVALID_ADDRESS;
  if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol)
    return LLDB_INVALID_ADDRESS;
  if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
    hint = abi_sp->FixCodeAddress(hint);

  hint += plan_offset;

  if (auto next = GetNextFrame()) {
    if (!next->m_sym_ctx.module_sp || !next->m_sym_ctx.symbol)
      return LLDB_INVALID_ADDRESS;
    if (auto expected_size =
            next->m_sym_ctx.module_sp->GetSymbolFile()->GetParameterStackSize(
                *next->m_sym_ctx.symbol))
      hint += *expected_size;
    else {
      LLDB_LOG_ERRORV(GetLog(LLDBLog::Unwind), expected_size.takeError(),
                      "Could not retrieve parameter size: {0}");
      return LLDB_INVALID_ADDRESS;
    }
  }
  return hint;
}

// Retrieve a general purpose register value for THIS frame, as saved by the
// NEXT frame, i.e. the frame that
// this frame called.  e.g.
//
//  foo () { }
//  bar () { foo (); }
//  main () { bar (); }
//
//  stopped in foo() so
//     frame 0 - foo
//     frame 1 - bar
//     frame 2 - main
//  and this RegisterContext is for frame 1 (bar) - if we want to get the pc
//  value for frame 1, we need to ask
//  where frame 0 (the "next" frame) saved that and retrieve the value.

bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind,
                                         uint32_t regnum, addr_t &value) {
  if (!IsValid())
    return false;

  uint32_t lldb_regnum;
  if (register_kind == eRegisterKindLLDB) {
    lldb_regnum = regnum;
  } else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
                 register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) {
    return false;
  }

  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum);
  assert(reg_info);
  if (!reg_info) {
    UNWIND_LOG(
        GetLog(LLDBLog::Unwind),
        "Could not find RegisterInfo definition for lldb register number {0}",
        lldb_regnum);
    return false;
  }

  uint32_t generic_regnum = LLDB_INVALID_REGNUM;
  if (register_kind == eRegisterKindGeneric)
    generic_regnum = regnum;
  else
    m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds(
        register_kind, regnum, eRegisterKindGeneric, generic_regnum);
  ABISP abi_sp = m_thread.GetProcess()->GetABI();

  RegisterValue reg_value;
  // if this is frame 0 (currently executing frame), get the requested reg
  // contents from the actual thread registers
  if (IsFrameZero()) {
    if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) {
      value = reg_value.GetAsUInt64();
      if (abi_sp && generic_regnum != LLDB_INVALID_REGNUM) {
        if (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
            generic_regnum == LLDB_REGNUM_GENERIC_RA)
          value = abi_sp->FixCodeAddress(value);
      }
      return true;
    }
    return false;
  }

  bool pc_register = false;
  if (generic_regnum != LLDB_INVALID_REGNUM &&
      (generic_regnum == LLDB_REGNUM_GENERIC_PC ||
       generic_regnum == LLDB_REGNUM_GENERIC_RA))
    pc_register = true;

  lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc;
  if (!m_parent_unwind.SearchForSavedLocationForRegister(
          lldb_regnum, regloc, m_frame_number - 1, pc_register)) {
    return false;
  }
  if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) {
    value = reg_value.GetAsUInt64();
    if (pc_register) {
      if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) {
        value = abi_sp->FixCodeAddress(value);
      }
    }
    return true;
  }
  return false;
}

bool RegisterContextUnwind::ReadGPRValue(const RegisterNumber &regnum,
                                         addr_t &value) {
  return ReadGPRValue(regnum.GetRegisterKind(), regnum.GetRegisterNumber(),
                      value);
}

// Find the value of a register in THIS frame

bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info,
                                         RegisterValue &value) {
  if (!IsValid())
    return false;

  const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
  Log *log = GetLog(LLDBLog::Unwind);
  UNWIND_LOG_VERBOSE(log, "looking for register saved location for reg {0}",
                     lldb_regnum);

  // If this is the 0th frame, hand this over to the live register context
  if (IsFrameZero()) {
    UNWIND_LOG_VERBOSE(log,
                       "passing along to the live register context for reg {0}",
                       lldb_regnum);
    return m_thread.GetRegisterContext()->ReadRegister(reg_info, value);
  }

  bool is_pc_regnum = false;
  if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC ||
      reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_RA) {
    is_pc_regnum = true;
  }

  lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc;
  // Find out where the NEXT frame saved THIS frame's register contents
  if (!m_parent_unwind.SearchForSavedLocationForRegister(
          lldb_regnum, regloc, m_frame_number - 1, is_pc_regnum))
    return false;

  bool result = ReadRegisterValueFromRegisterLocation(regloc, reg_info, value);
  if (result) {
    if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) {
      addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS);
      if (reg_value != LLDB_INVALID_ADDRESS) {
        if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
          value = abi_sp->FixCodeAddress(reg_value);
      }
    }
  }
  return result;
}

bool RegisterContextUnwind::WriteRegister(const RegisterInfo *reg_info,
                                          const RegisterValue &value) {
  if (!IsValid())
    return false;

  const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
  Log *log = GetLog(LLDBLog::Unwind);
  UNWIND_LOG_VERBOSE(log, "looking for register saved location for reg {0}",
                     lldb_regnum);

  // If this is the 0th frame, hand this over to the live register context
  if (IsFrameZero()) {
    UNWIND_LOG_VERBOSE(log,
                       "passing along to the live register context for reg {0}",
                       lldb_regnum);
    return m_thread.GetRegisterContext()->WriteRegister(reg_info, value);
  }

  lldb_private::UnwindLLDB::ConcreteRegisterLocation regloc;
  // Find out where the NEXT frame saved THIS frame's register contents
  if (!m_parent_unwind.SearchForSavedLocationForRegister(
          lldb_regnum, regloc, m_frame_number - 1, false))
    return false;

  return WriteRegisterValueToRegisterLocation(regloc, reg_info, value);
}

// Don't need to implement this one
bool RegisterContextUnwind::ReadAllRegisterValues(
    lldb::WritableDataBufferSP &data_sp) {
  return false;
}

// Don't need to implement this one
bool RegisterContextUnwind::WriteAllRegisterValues(
    const lldb::DataBufferSP &data_sp) {
  return false;
}

// Retrieve the pc value for THIS from

bool RegisterContextUnwind::GetCFA(addr_t &cfa) {
  if (!IsValid()) {
    return false;
  }
  if (m_cfa == LLDB_INVALID_ADDRESS) {
    return false;
  }
  cfa = m_cfa;
  return true;
}

RegisterContextUnwind::SharedPtr RegisterContextUnwind::GetNextFrame() const {
  RegisterContextUnwind::SharedPtr regctx;
  if (m_frame_number == 0)
    return regctx;
  return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number - 1);
}

RegisterContextUnwind::SharedPtr RegisterContextUnwind::GetPrevFrame() const {
  RegisterContextUnwind::SharedPtr regctx;
  return m_parent_unwind.GetRegisterContextForFrameNum(m_frame_number + 1);
}

// Retrieve the address of the start of the function of THIS frame

bool RegisterContextUnwind::GetStartPC(addr_t &start_pc) {
  if (!IsValid())
    return false;

  if (!m_start_pc.IsValid()) {
        bool read_successfully = ReadPC (start_pc);
        if (read_successfully)
        {
            ProcessSP process_sp (m_thread.GetProcess());
            if (process_sp)
            {
              if (ABISP abi_sp = process_sp->GetABI())
                start_pc = abi_sp->FixCodeAddress(start_pc);
            }
        }
        return read_successfully;
  }
  start_pc = m_start_pc.GetLoadAddress(CalculateTarget().get());
  return true;
}

// Retrieve the current pc value for THIS frame, as saved by the NEXT frame.

bool RegisterContextUnwind::ReadPC(addr_t &pc) {
  if (!IsValid())
    return false;

  bool above_trap_handler = false;
  if (GetNextFrame().get() && GetNextFrame()->IsValid() &&
      GetNextFrame()->IsTrapHandlerFrame())
    above_trap_handler = true;

  if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) {
    // A pc value of 0 or 1 is impossible in the middle of the stack -- it
    // indicates the end of a stack walk.
    // On the currently executing frame (or such a frame interrupted
    // asynchronously by sigtramp et al) this may occur if code has jumped
    // through a NULL pointer -- we want to be able to unwind past that frame
    // to help find the bug.

    if (ABISP abi_sp = m_thread.GetProcess()->GetABI())
      pc = abi_sp->FixCodeAddress(pc);

    return !(m_all_registers_available == false &&
             above_trap_handler == false && (pc == 0 || pc == 1));
  } else {
    return false;
  }
}
