//===-- RegisterContextLLDB.cpp --------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ArmUnwindInfo.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/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.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 "RegisterContextLLDB.h"

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();
}

RegisterContextLLDB::RegisterContextLLDB
(
    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_start_pc (),
    m_current_pc (),
    m_current_offset (0),
    m_current_offset_backed_up_one (0),
    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
RegisterContextLLDB::IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset)
{
    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
        valid_pc_offset = m_current_offset;
        return true;
    }

    // if m_current_offset <= 0, we've got nothing else to try
    if (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.SetOffset(m_current_pc.GetOffset() - 1);
    if (unwind_plan_sp->PlanValidAtAddress(pc_minus_one))
    {
        // *valid_pc_offset = m_current_offset - 1;
        valid_pc_offset = m_current_pc.GetOffset() - 1;
        return true;
    }

    return false;
}

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

void
RegisterContextLLDB::InitializeZerothFrame()
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
    ExecutionContext exe_ctx(m_thread.shared_from_this());
    RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();

    if (reg_ctx_sp.get() == NULL)
    {
        m_frame_type = eNotAValidFrame;
        UnwindLogMsg ("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;
        UnwindLogMsg ("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.)
    ABI *abi = process->GetABI().get();
    if (abi)
        current_pc = abi->FixCodeAddress(current_pc);

    // 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)
    {
        UnwindLogMsg ("using architectural default unwind method");
    }

    // We require either a symbol or function in the symbols context to be successfully
    // filled in or this context is of no use to us.
    const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
    if (pc_module_sp.get()
        && (pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, m_sym_ctx) & resolve_scope))
    {
        m_sym_ctx_valid = true;
    }

    if (m_sym_ctx.symbol)
    {
        UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
                      current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
    }
    else if (m_sym_ctx.function)
    {
        UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'",
                      current_pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
    }
    else
    {
        UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", current_pc);
    }

    AddressRange addr_range;
    m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range);

    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 (addr_range.GetBaseAddress().IsValid())
    {
        m_start_pc = addr_range.GetBaseAddress();
        if (m_current_pc.GetSection() == m_start_pc.GetSection())
        {
            m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
        }
        else if (m_current_pc.GetModule() == m_start_pc.GetModule())
        {
            // This means that whatever symbol we kicked up isn't really correct
            // --- we should not cross section boundaries ... We really should NULL out
            // the function/symbol in this case unless there is a bad assumption
            // here due to inlined functions?
            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 = -1;
        m_current_offset_backed_up_one = -1;
    }

    // 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 ();

    UnwindPlan::RowSP active_row;
    lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
    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 ();
        if (active_row.get() && 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()));
            UnwindLogMsg ("%s", active_row_strm.GetString().c_str());
        }
    }

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


    if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
    {
        // Try the fall back unwind plan since the
        // full unwind plan failed.
        FuncUnwindersSP func_unwinders_sp;
        UnwindPlanSP call_site_unwind_plan;
        bool cfa_status = false;

        if (m_sym_ctx_valid)
        {
            func_unwinders_sp = pc_module_sp->GetObjectFile()->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_current_offset_backed_up_one);

        if (call_site_unwind_plan.get() != nullptr)
        {
            m_fallback_unwind_plan_sp = call_site_unwind_plan;
            if(TryFallbackUnwindPlan())
                cfa_status = true;
        }
        if (!cfa_status)
        {
            UnwindLogMsg ("could not read CFA value for first frame.");
            m_frame_type = eNotAValidFrame;
            return;
        }
    }

    UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 " using %s UnwindPlan",
            (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
            (uint64_t) m_cfa,
            m_full_unwind_plan_sp->GetSourceName().GetCString());
}

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

void
RegisterContextLLDB::InitializeNonZerothFrame()
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
    if (IsFrameZero ())
    {
        m_frame_type = eNotAValidFrame;
        UnwindLogMsg ("non-zeroth frame tests positive for IsFrameZero -- that shouldn't happen.");
        return;
    }

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

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

    if (log)
    {
        UnwindLogMsg ("pc = 0x%" PRIx64, pc);
        addr_t reg_val;
        if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
            UnwindLogMsg ("fp = 0x%" PRIx64, reg_val);
        if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
            UnwindLogMsg ("sp = 0x%" PRIx64, 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 == false)
        {
            m_frame_type = eNotAValidFrame;
            UnwindLogMsg ("this frame has a pc of 0x0");
            return;
        }
    }

    ExecutionContext exe_ctx(m_thread.shared_from_this());
    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.
    ABI *abi = process->GetABI().get();
    if (abi)
        pc = abi->FixCodeAddress(pc);

    m_current_pc.SetLoadAddress (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)
    {
        UnwindLogMsg ("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())
            {
                UnwindLogMsg ("had a pc of 0x%" PRIx64 " which is not in executable memory but on frame 1 -- allowing it once.",
                         (uint64_t) 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;
                UnwindLogMsg ("pc is in a non-executable section of memory and this isn't the 2nd frame in the stack walk.");
                return;
            }
        }

        if (abi)
        {
            m_fast_unwind_plan_sp.reset ();
            m_full_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
            abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp);
            if (m_frame_type != eSkipFrame)  // don't override eSkipFrame
            {
                m_frame_type = eNormalFrame;
            }
            m_all_registers_available = false;
            m_current_offset = -1;
            m_current_offset_backed_up_one = -1;
            RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
            UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
            if (row.get())
            {
                if (!ReadCFAValueForRow (row_register_kind, row, m_cfa))
                {
                    UnwindLogMsg ("failed to get cfa value");
                    if (m_frame_type != eSkipFrame)   // don't override eSkipFrame
                    {
                        m_frame_type = eNotAValidFrame;
                    }
                    return;
                }

                // A couple of sanity checks..
                if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1)
                {
                    UnwindLogMsg ("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;
                    UnwindLogMsg ("the CFA points to a region of memory that is not readable");
                    return;
                }
            }
            else
            {
                UnwindLogMsg ("could not find a row for function offset zero");
                m_frame_type = eNotAValidFrame;
                return;
            }

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

            UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64, (uint64_t) m_cfa);
            return;
        }
        m_frame_type = eNotAValidFrame;
        UnwindLogMsg ("could not find any symbol for this pc, or a default unwind plan, to continue unwind.");
        return;
    }

    bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function...
                                           // This will handle the case where the saved pc does not point to 
                                           // a function/symbol because it is beyond the bounds of the correct
                                           // function and there's no symbol there.  ResolveSymbolContextForAddress
                                           // will fail to find a symbol, back up the pc by 1 and re-search.
    const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
    uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc,
                                                                            resolve_scope,
                                                                            m_sym_ctx, resolve_tail_call_address);

    // We require either a symbol or function in the symbols context to be successfully
    // filled in or this context is of no use to us.
    if (resolve_scope & resolved_scope)
    {
        m_sym_ctx_valid = true;
    }

    if (m_sym_ctx.symbol)
    {
        UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'",
                      pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
    }
    else if (m_sym_ctx.function)
    {
        UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'",
                      pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
    }
    else
    {
        UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", pc);
    }

    AddressRange addr_range;
    if (!m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range))
    {
        m_sym_ctx_valid = false;
    }

    bool decr_pc_and_recompute_addr_range = false;

    // If the symbol lookup failed...
    if (m_sym_ctx_valid == false)
       decr_pc_and_recompute_addr_range = true;

    // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp),
    // and our "current" pc is the start of a function...
    if (m_sym_ctx_valid
        && GetNextFrame()->m_frame_type != eTrapHandlerFrame
        && GetNextFrame()->m_frame_type != eDebuggerFrame
        && addr_range.GetBaseAddress().IsValid()
        && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()
        && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset())
    {
        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)
    {
        UnwindLogMsg ("Backing up the pc value of 0x%" PRIx64 " by 1 and re-doing symbol lookup; old symbol was %s",
                      pc, GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
        Address temporary_pc;
        temporary_pc.SetLoadAddress (pc - 1, &process->GetTarget());
        m_sym_ctx.Clear (false);
        m_sym_ctx_valid = false;
        uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol;
        
        ModuleSP temporary_module_sp = temporary_pc.GetModule();
        if (temporary_module_sp &&
            temporary_module_sp->ResolveSymbolContextForAddress (temporary_pc, resolve_scope, m_sym_ctx) & resolve_scope)
        {
            if (m_sym_ctx.GetAddressRange (resolve_scope, 0, false,  addr_range))
                m_sym_ctx_valid = true;
        }
        UnwindLogMsg ("Symbol is now %s", GetSymbolOrFunctionName(m_sym_ctx).AsCString(""));
    }

    // 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 (addr_range.GetBaseAddress().IsValid())
    {
        m_start_pc = addr_range.GetBaseAddress();
        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 = -1;
        m_current_offset_backed_up_one = -1;
    }

    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;
        }
    }

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

    UnwindPlan::RowSP active_row;
    RegisterKind row_register_kind = eRegisterKindGeneric;

    // 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 ();
        if (active_row.get() && 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()));
            UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
        }
    }
    else
    {
        m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
        int valid_offset = -1;
        if (IsUnwindPlanValidForCurrentPC(m_full_unwind_plan_sp, valid_offset))
        {
            active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (valid_offset);
            row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
            if (active_row.get() && 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()));
                UnwindLogMsg ("active row: %s", active_row_strm.GetString().c_str());
            }
        }
    }

    if (!active_row.get())
    {
        m_frame_type = eNotAValidFrame;
        UnwindLogMsg ("could not find unwind row for this pc");
        return;
    }

    if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
    {
        UnwindLogMsg ("failed to get cfa");
        m_frame_type = eNotAValidFrame;
        return;
    }

    UnwindLogMsg ("m_cfa = 0x%" PRIx64, m_cfa);

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

    UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64,
            (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
}

bool
RegisterContextLLDB::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 compiance) 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 very unlikely)

    RegisterContextLLDB::SharedPtr next_frame = GetNextFrame();
    if (next_frame)
    {
        RegisterContextLLDB::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
RegisterContextLLDB::IsFrameZero () const
{
    return m_frame_number == 0;
}


// 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, -1 if unknown

UnwindPlanSP
RegisterContextLLDB::GetFastUnwindPlanForFrame ()
{
    UnwindPlanSP unwind_plan_sp;
    ModuleSP pc_module_sp (m_current_pc.GetModule());

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

    if (IsFrameZero ())
        return unwind_plan_sp;

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

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

    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (*m_thread.CalculateTarget(), m_thread);
    if (unwind_plan_sp)
    {
        if (unwind_plan_sp->PlanValidAtAddress (m_current_pc))
        {
            Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
            if (log && log->GetVerbose())
            {
                if (m_fast_unwind_plan_sp)
                    UnwindLogMsgVerbose ("frame, and has a fast UnwindPlan");
                else
                    UnwindLogMsgVerbose ("frame");
            }
            m_frame_type = eNormalFrame;
            return unwind_plan_sp;
        }
        else
        {
            unwind_plan_sp.reset();
        }
    }
    return unwind_plan_sp;
}

// 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, -1 if unknown

UnwindPlanSP
RegisterContextLLDB::GetFullUnwindPlanForFrame ()
{
    UnwindPlanSP unwind_plan_sp;
    UnwindPlanSP arch_default_unwind_plan_sp;
    ExecutionContext exe_ctx(m_thread.shared_from_this());
    Process *process = exe_ctx.GetProcessPtr();
    ABI *abi = process ? process->GetABI().get() : NULL;
    if (abi)
    {
        arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
        abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
    }
    else
    {
        UnwindLogMsg ("unable to get architectural default UnwindPlan from ABI plugin");
    }

    bool behaves_like_zeroth_frame = false;
    if (IsFrameZero ()
        || GetNextFrame()->m_frame_type == eTrapHandlerFrame
        || GetNextFrame()->m_frame_type == eDebuggerFrame)
    {
        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 == NULL && m_sym_ctx.symbol == NULL)) && 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)
            {
                unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
                abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp);
                m_frame_type = eNormalFrame;
                return unwind_plan_sp;
            }
        }
    }

    // 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() == NULL)
    {
        m_frame_type = eNormalFrame;
        return arch_default_unwind_plan_sp;
    }

    FuncUnwindersSP func_unwinders_sp;
    if (m_sym_ctx_valid)
    {
        func_unwinders_sp = pc_module_sp->GetObjectFile()->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.
        DWARFCallFrameInfo *eh_frame = pc_module_sp->GetObjectFile()->GetUnwindTable().GetEHFrameInfo();
        if (eh_frame)
        {
            unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
            if (eh_frame->GetUnwindPlan (m_current_pc, *unwind_plan_sp))
                return unwind_plan_sp;
            else
                unwind_plan_sp.reset();
        }

        ArmUnwindInfo *arm_exidx = pc_module_sp->GetObjectFile()->GetUnwindTable().GetArmUnwindInfo();
        if (arm_exidx)
        {
            unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
            if (arm_exidx->GetUnwindPlan (exe_ctx.GetTargetRef(), m_current_pc, *unwind_plan_sp))
                return unwind_plan_sp;
            else
                unwind_plan_sp.reset();
        }

        return arch_default_unwind_plan_sp;
    }

    // If we're in _sigtramp(), unwinding past this frame requires special knowledge.  On Mac OS X this knowledge
    // is properly encoded in the eh_frame section, so prefer that if available.
    // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of
    // how to unwind out of sigtramp.
    if (m_frame_type == eTrapHandlerFrame && process)
    {
        m_fast_unwind_plan_sp.reset();
        unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
        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)
        unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
        if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
        {
            UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
                           unwind_plan_sp->GetSourceName().GetCString());
            return unwind_plan_sp;
        }
    }

    // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions
    if (behaves_like_zeroth_frame && process)
    {
        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one);
        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.
                UnwindPlanSP call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
                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;
                }
            }
            UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
            return 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_current_offset_backed_up_one);
    }
    int valid_offset = -1;
    if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset))
    {
        UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
        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, m_current_offset_backed_up_one);
    }
    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.
        UnwindPlanSP call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
        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, valid_offset))
    {
        UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
        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_backed_up_one == 0)
    {
        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry (m_thread);
        if (unwind_plan_sp)
        {
            UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString());
            return unwind_plan_sp;
        }
    }

    // If nothing else, use the architectural default UnwindPlan and hope that does the job.
    if (arch_default_unwind_plan_sp)
        UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString());
    else
        UnwindLogMsg ("Unable to find any UnwindPlan for full unwind of this frame.");

    return arch_default_unwind_plan_sp;
}


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

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

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

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

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

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

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

    switch (regloc.type)
    {
    case UnwindLLDB::RegisterLocation::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::RegisterLocation::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::RegisterLocation::eRegisterValueInferred:
        success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size);
        break;

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

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

    bool success = false;

    switch (regloc.type)
    {
        case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext:
            {
                const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
                success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value);
            }
            break;
        case UnwindLLDB::RegisterLocation::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::RegisterLocation::eRegisterValueInferred:
        case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
            break;
        case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
            assert ("FIXME debugger inferior function call unwind");
            break;
        case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
            {
                Error error (WriteRegisterValueToMemory (reg_info,
                                                         regloc.location.target_memory_location,
                                                         reg_info->byte_size,
                                                         value));
                success = error.Success();
            }
            break;
        default:
            assert ("Unknown RegisterLocation type.");
            break;
    }
    return success;
}


bool
RegisterContextLLDB::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 differnece between
// "the unwind plan below this frame failed" versus "we successfully completed the stack walk" so
// this method helps to disambiguate that.

bool
RegisterContextLLDB::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
RegisterContextLLDB::IsSkipFrame () const
{
    return m_frame_type == eSkipFrame;
}

bool
RegisterContextLLDB::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;
}

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

enum UnwindLLDB::RegisterSearchResult
RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc)
{
    RegisterNumber regnum (m_thread, eRegisterKindLLDB, lldb_regnum);

    // Have we already found this register location?
    if (!m_registers.empty())
    {
        std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator;
        iterator = m_registers.find (regnum.GetAsKind (eRegisterKindLLDB));
        if (iterator != m_registers.end())
        {
            regloc = iterator->second;
            UnwindLogMsg ("supplying caller's saved %s (%d)'s location, cached", 
                           regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
        }
    }

    // Look through the available UnwindPlans for the register location.

    UnwindPlan::Row::RegisterLocation unwindplan_regloc;
    bool have_unwindplan_regloc = false;
    RegisterKind unwindplan_registerkind = kNumRegisterKinds;

    if (m_fast_unwind_plan_sp)
    {
        UnwindPlan::RowSP active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
        unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind ();
        if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM)
        {
            UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme",
                    regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind);
            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
        }
        if (active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
        {
            UnwindLogMsg ("supplying caller's saved %s (%d)'s location using FastUnwindPlan", 
                          regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
            have_unwindplan_regloc = true;
        }
    }

    if (!have_unwindplan_regloc)
    {
        // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet
        if (!m_full_unwind_plan_sp)
            m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();

        if (m_full_unwind_plan_sp)
        {
            RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);

            UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
            unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();

            RegisterNumber return_address_reg;

            // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm),
            // look for the return address register number in the UnwindPlan's row.
            if (pc_regnum.IsValid()
                && pc_regnum == regnum
                && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
            {
                
                return_address_reg.init (m_thread, m_full_unwind_plan_sp->GetRegisterKind(), m_full_unwind_plan_sp->GetReturnAddressRegister());
                regnum = return_address_reg;
                UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting %s (%d) instead",
                              return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB));
            }
            else
            {
                if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM)
                {
                    if (unwindplan_registerkind == eRegisterKindGeneric)
                    {
                        UnwindLogMsg ("could not convert lldb regnum %s (%d) into eRegisterKindGeneric reg numbering scheme", 
                                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
                    }
                    else
                    {
                        UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme",
                                    regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind);
                    }
                    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
                }
            }

            if (regnum.IsValid() 
                && active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
            {
                have_unwindplan_regloc = true;
                UnwindLogMsg ("supplying caller's saved %s (%d)'s location using %s UnwindPlan", 
                              regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
                              m_full_unwind_plan_sp->GetSourceName().GetCString());
            }

            // This is frame 0 and we're retrieving the PC and it's saved in a Return Address register and
            // it hasn't been saved anywhere yet -- that is, it's still live in the actual register.
            // Handle this specially.

            if (have_unwindplan_regloc == false 
                && return_address_reg.IsValid()
                && IsFrameZero())
            {
                if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM)
                {
                    lldb_private::UnwindLLDB::RegisterLocation new_regloc;
                    new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
                    new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB);
                    m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
                    regloc = new_regloc;
                    UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0, saved in %d", 
                                  return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB), 
                                  return_address_reg.GetAsKind (eRegisterKindLLDB));
                    return UnwindLLDB::RegisterSearchResult::eRegisterFound;
                }
            }

            // If this architecture stores the return address in a register (it defines a Return Address register)
            // and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the
            // RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this
            // is an impossible situation and the instruction emulation code has likely been misled.  
            // If this stack frame meets those criteria, we need to throw away the Full UnwindPlan that the 
            // instruction emulation came up with and fall back to the architecture's Default UnwindPlan so
            // the stack walk can get past this point.

            // Special note:  If the Full UnwindPlan was generated from the compiler, don't second-guess it 
            // when we're at a call site location.

            // arch_default_ra_regnum is the return address register # in the Full UnwindPlan register numbering
            RegisterNumber arch_default_ra_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);

            if (arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM
                && pc_regnum == regnum
                && unwindplan_regloc.IsInOtherRegister()
                && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum.GetAsKind (unwindplan_registerkind)
                && m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes
                && !m_all_registers_available)
            {
                UnwindLogMsg ("%s UnwindPlan tried to restore the pc from the link register but this is a non-zero frame",
                              m_full_unwind_plan_sp->GetSourceName().GetCString());

                // Throw away the full unwindplan; install the arch default unwindplan
                if (ForceSwitchToFallbackUnwindPlan())
                {
                    // Update for the possibly new unwind plan
                    unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
                    UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);

                    // Sanity check: Verify that we can fetch a pc value and CFA value with this unwind plan

                    RegisterNumber arch_default_pc_reg (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
                    bool can_fetch_pc_value = false;
                    bool can_fetch_cfa = false;
                    addr_t cfa_value;
                    if (active_row)
                    {
                        if (arch_default_pc_reg.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM
                            && active_row->GetRegisterInfo (arch_default_pc_reg.GetAsKind (unwindplan_registerkind), unwindplan_regloc))
                        {
                            can_fetch_pc_value = true;
                        }
                        if (ReadCFAValueForRow (unwindplan_registerkind, active_row, cfa_value))
                        {
                            can_fetch_cfa = true;
                        }
                    }

                    if (can_fetch_pc_value && can_fetch_cfa)
                    {
                        have_unwindplan_regloc = true;
                    }
                    else
                    {
                        have_unwindplan_regloc = false;
                    }
                }
                else
                {
                    // We were unable to fall back to another unwind plan
                    have_unwindplan_regloc = false;
                }
            }
        }
    }

    if (have_unwindplan_regloc == false)
    {
        // Did the UnwindPlan fail to give us the caller's stack pointer?  
        // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as
        // the caller's stack pointer.  This is true on x86-32/x86-64 at least.

        RegisterNumber sp_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
        if (sp_regnum.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM 
            && sp_regnum.GetAsKind (eRegisterKindLLDB) == regnum.GetAsKind (eRegisterKindLLDB))
        {
            // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value)
            assert (sizeof (addr_t) <= sizeof (uint64_t));
            regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
            regloc.location.inferred_value = m_cfa;
            m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
            UnwindLogMsg ("supplying caller's stack pointer %s (%d) value, computed from CFA", 
                        regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
        }
    }

    ExecutionContext exe_ctx(m_thread.shared_from_this());
    Process *process = exe_ctx.GetProcessPtr();
    if (have_unwindplan_regloc == false)
    {
        // If a volatile register is being requested, we don't want to forward the next frame's register contents
        // up the stack -- the register is not retrievable at this frame.
        ABI *abi = process ? process->GetABI().get() : NULL;
        if (abi)
        {
            const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB));
            if (reg_info && abi->RegisterIsVolatile (reg_info))
            {
                UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
                              regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
                return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
            }
        }

        if (IsFrameZero ())
        {
            // This is frame 0 - we should return the actual live register context value
            lldb_private::UnwindLLDB::RegisterLocation new_regloc;
            new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext;
            new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
            m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
            regloc = new_regloc;
            UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0", 
                           regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
        }
        else
        {
            std::string unwindplan_name ("");
            if (m_full_unwind_plan_sp)
            {
                unwindplan_name += "via '";
                unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString();
                unwindplan_name += "'";
            }
            UnwindLogMsg ("no save location for %s (%d) %s", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB),
                      unwindplan_name.c_str());
        }
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }

    // unwindplan_regloc has valid contents about where to retrieve the register
    if (unwindplan_regloc.IsUnspecified())
    {
        lldb_private::UnwindLLDB::RegisterLocation new_regloc;
        new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc;
        UnwindLogMsg ("save location for %s (%d) is unspecified, continue searching", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }

    if (unwindplan_regloc.IsSame())
    {
        regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
        regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB);
        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
        UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }

    if (unwindplan_regloc.IsCFAPlusOffset())
    {
        int offset = unwindplan_regloc.GetOffset();
        regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
        regloc.location.inferred_value = m_cfa + offset;
        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
        UnwindLogMsg ("supplying caller's register %s (%d), value is CFA plus offset %d [value is 0x%" PRIx64 "]", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
                      offset, regloc.location.inferred_value);
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }

    if (unwindplan_regloc.IsAtCFAPlusOffset())
    {
        int offset = unwindplan_regloc.GetOffset();
        regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
        regloc.location.target_memory_location = m_cfa + offset;
        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
        UnwindLogMsg ("supplying caller's register %s (%d) from the stack, saved at CFA plus offset %d [saved at 0x%" PRIx64 "]", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
                      offset, regloc.location.target_memory_location);
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }

    if (unwindplan_regloc.IsInOtherRegister())
    {
        uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
        RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum);
        if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_REGNUM)
        {
            UnwindLogMsg ("could not supply caller's %s (%d) location - was saved in another reg but couldn't convert that regnum", 
                          regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
        }
        regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
        regloc.location.register_number = row_regnum.GetAsKind (eRegisterKindLLDB);
        m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
        UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), 
                      row_regnum.GetName(), row_regnum.GetAsKind (eRegisterKindLLDB));
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }

    if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
    {
        DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
                                 unwindplan_regloc.GetDWARFExpressionLength(),
                                 process->GetByteOrder(), process->GetAddressByteSize());
        ModuleSP opcode_ctx;
        DWARFExpression dwarfexpr (opcode_ctx,
                                   dwarfdata,
                                   nullptr,
                                   0,
                                   unwindplan_regloc.GetDWARFExpressionLength());
        dwarfexpr.SetRegisterKind (unwindplan_registerkind);
        Value result;
        Error error;
        if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
        {
            addr_t val;
            val = result.GetScalar().ULongLong();
            if (unwindplan_regloc.IsDWARFExpression())
             {
                regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
                regloc.location.inferred_value = val;
                m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
                UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsDWARFExpression)", 
                              regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
                return UnwindLLDB::RegisterSearchResult::eRegisterFound;
            }
            else
            {
                regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
                regloc.location.target_memory_location = val;
                m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
                UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsAtDWARFExpression)", 
                              regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
                return UnwindLLDB::RegisterSearchResult::eRegisterFound;
            }
        }
        UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for %s (%d) but failed", 
                      regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }

    UnwindLogMsg ("no save location for %s (%d) in this stack frame", 
                   regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));

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

    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}

// 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
RegisterContextLLDB::TryFallbackUnwindPlan ()
{
    if (m_fallback_unwind_plan_sp.get() == nullptr)
        return false;

    if (m_full_unwind_plan_sp.get() == 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;
    addr_t old_this_frame_cfa_value = m_cfa;
    UnwindLLDB::RegisterLocation 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();
            }
        }
    }

    // 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.get() == 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'.
    UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
    addr_t old_cfa = m_cfa;

    m_registers.clear();

    m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;

    UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
    
    if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
    {
        addr_t new_cfa;
        if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa)
            || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS)
        {
            UnwindLogMsg ("failed to get cfa with fallback unwindplan");
            m_fallback_unwind_plan_sp.reset();
            m_full_unwind_plan_sp = original_full_unwind_plan_sp;
            m_cfa = old_cfa;
            return false;
        }
        m_cfa = new_cfa;

        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 (new_caller_pc_value == LLDB_INVALID_ADDRESS)
        {
            UnwindLogMsg ("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;
            return false;
        }

        if (old_caller_pc_value != LLDB_INVALID_ADDRESS)
        {
            if (old_caller_pc_value == new_caller_pc_value && new_cfa == old_this_frame_cfa_value)
            {
                UnwindLogMsg ("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;
                m_cfa = old_cfa;
                return false;
            }
        }

        UnwindLogMsg ("trying to unwind from this function with the UnwindPlan '%s' because UnwindPlan '%s' failed.", 
                      m_fallback_unwind_plan_sp->GetSourceName().GetCString(),
                      original_full_unwind_plan_sp->GetSourceName().GetCString());

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

    return true;
}

bool
RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan ()
{
    if (m_fallback_unwind_plan_sp.get() == NULL)
        return false;

    if (m_full_unwind_plan_sp.get() == NULL)
        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;
    }

    UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
    
    if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
    {
        addr_t new_cfa;
        if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa)
            || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS)
        {
            UnwindLogMsg ("failed to get cfa with fallback unwindplan");
            m_fallback_unwind_plan_sp.reset();
            return false;
        }

        m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
        m_fallback_unwind_plan_sp.reset();

        m_registers.clear();

        m_cfa = new_cfa;

        UnwindLogMsg ("switched unconditionally to the fallback unwindplan %s", m_full_unwind_plan_sp->GetSourceName().GetCString());
        return true;
    }
    return false;
}

bool
RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind,
                                         const UnwindPlan::RowSP &row,
                                         addr_t &cfa_value)
{
    RegisterValue reg_value;

    cfa_value = LLDB_INVALID_ADDRESS;
    addr_t cfa_reg_contents;

    switch (row->GetCFAValue().GetValueType())
    {
    case UnwindPlan::Row::CFAValue::isRegisterDereferenced:
        {
            RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
            if (ReadGPRValue (cfa_reg, cfa_reg_contents))
            {
                const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB));
                RegisterValue reg_value;
                if (reg_info)
                {
                    Error error = ReadRegisterValueFromMemory(reg_info,
                                                              cfa_reg_contents,
                                                              reg_info->byte_size,
                                                              reg_value);
                    if (error.Success ())
                    {
                        cfa_value = reg_value.GetAsUInt64();
                        UnwindLogMsg ("CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64,
                                      cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
                                      cfa_reg_contents, cfa_value);
                        return true;
                    }
                    else
                    {
                        UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64 "] but memory read failed.",
                                      cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
                                      cfa_reg_contents);
                    }
                }
            }
            break;
        }
    case UnwindPlan::Row::CFAValue::isRegisterPlusOffset:
        {
            RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
            if (ReadGPRValue (cfa_reg, cfa_reg_contents))
            {
                if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1)
                {
                    UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
                                  cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
                                  cfa_reg_contents);
                    cfa_reg_contents = LLDB_INVALID_ADDRESS;
                    return false;
                }
                cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset();
                UnwindLogMsg ("CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d",
                              cfa_value,
                              cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
                              cfa_reg_contents, row->GetCFAValue().GetOffset());
                return true;
            }
            break;
        }
    case UnwindPlan::Row::CFAValue::isDWARFExpression:
        {
            ExecutionContext exe_ctx(m_thread.shared_from_this());
            Process *process = exe_ctx.GetProcessPtr();
            DataExtractor dwarfdata (row->GetCFAValue().GetDWARFExpressionBytes(),
                                     row->GetCFAValue().GetDWARFExpressionLength(),
                                     process->GetByteOrder(), process->GetAddressByteSize());
            ModuleSP opcode_ctx;
            DWARFExpression dwarfexpr (opcode_ctx,
                                       dwarfdata,
                                       nullptr,
                                       0,
                                       row->GetCFAValue().GetDWARFExpressionLength());
            dwarfexpr.SetRegisterKind (row_register_kind);
            Value result;
            Error error;
            if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error))
            {
                cfa_value = result.GetScalar().ULongLong();

                UnwindLogMsg ("CFA value set by DWARF expression is 0x%" PRIx64, cfa_value);
                return true;
            }
            UnwindLogMsg ("Failed to set CFA value via DWARF expression: %s", error.AsCString());
            break;
        }
    default:
        return false;
    }
    return false;
}

// 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
RegisterContextLLDB::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);
    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();
            return true;
        }
        return false;
    }

    bool pc_register = false;
    uint32_t generic_regnum;
    if (register_kind == eRegisterKindGeneric && regnum == LLDB_REGNUM_GENERIC_PC)
    {
        pc_register = true;
    }
    else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindGeneric, generic_regnum)
             && generic_regnum == LLDB_REGNUM_GENERIC_PC)
    {
        pc_register = true;
    }

    lldb_private::UnwindLLDB::RegisterLocation 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();
        return true;
    }
    return false;
}

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

// Find the value of a register in THIS frame

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

    const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
    UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);

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

    lldb_private::UnwindLLDB::RegisterLocation 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 ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
}

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

    const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB];
    UnwindLogMsgVerbose ("looking for register saved location for reg %d", lldb_regnum);

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

    lldb_private::UnwindLLDB::RegisterLocation 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
RegisterContextLLDB::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
{
    return false;
}

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

// Retrieve the pc value for THIS from

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


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

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

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

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

    if (!m_start_pc.IsValid())
    {
        return ReadPC (start_pc);
    }
    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
RegisterContextLLDB::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 (m_all_registers_available == false
            && above_trap_handler == false
            && (pc == 0 || pc == 1))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    else
    {
        return false;
    }
}


void
RegisterContextLLDB::UnwindLogMsg (const char *fmt, ...)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
    if (log)
    {
        va_list args;
        va_start (args, fmt);

        char *logmsg;
        if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
        {
            if (logmsg)
                free (logmsg);
            va_end (args);
            return;
        }
        va_end (args);

        log->Printf ("%*sth%d/fr%u %s",
                      m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
                      logmsg);
        free (logmsg);
    }
}

void
RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
    if (log && log->GetVerbose())
    {
        va_list args;
        va_start (args, fmt);

        char *logmsg;
        if (vasprintf (&logmsg, fmt, args) == -1 || logmsg == NULL)
        {
            if (logmsg)
                free (logmsg);
            va_end (args);
            return;
        }
        va_end (args);

        log->Printf ("%*sth%d/fr%u %s",
                      m_frame_number < 100 ? m_frame_number : 100, "", m_thread.GetIndexID(), m_frame_number,
                      logmsg);
        free (logmsg);
    }
}


