//===-- 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/FuncUnwinders.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/DynamicLoader.h"

#include "RegisterContextLLDB.h"

using namespace lldb;
using namespace lldb_private;

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_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 == eSigtrampFrame
        || next_frame->m_frame_type == eDebuggerFrame)
    {
        m_all_registers_available = true;
    }
}

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

    addr_t current_pc = reg_ctx_sp->GetPC();

    if (current_pc == LLDB_INVALID_ADDRESS)
    {
        m_frame_type = eNotAValidFrame;
        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.
    process->GetTarget().GetSectionLoadList().ResolveLoadAddress (current_pc, m_current_pc);

    // 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 that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
    if (pc_module_sp.get()
        && (pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
    {
        m_sym_ctx_valid = true;
    }

    AddressRange addr_range;
    m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range);

    static ConstString g_sigtramp_name ("_sigtramp");
    if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == g_sigtramp_name) ||
        (m_sym_ctx.symbol   && m_sym_ctx.symbol->GetName()   == g_sigtramp_name))
    {
        m_frame_type = eSigtrampFrame;
    }
    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;
    int cfa_offset = 0;
    int row_register_kind = -1;
    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())
    {
        m_frame_type = eNotAValidFrame;
        return;
    }


    addr_t cfa_regval;
    if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
    {
        m_frame_type = eNotAValidFrame;
        return;
    }
    else
    {
    }
    cfa_offset = active_row->GetCFAOffset ();

    m_cfa = cfa_regval + cfa_offset;

    UnwindLogMsg ("cfa_regval = 0x%16.16" PRIx64 " (cfa_regval = 0x%16.16" PRIx64 ", cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
    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;
        return;
    }

    if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
    {
        m_frame_type = eNotAValidFrame;
        return;
    }
    if (!m_thread.GetRegisterContext())
    {
        m_frame_type = eNotAValidFrame;
        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%16.16" PRIx64, pc);
        addr_t reg_val;
        if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
            UnwindLogMsg ("fp = 0x%16.16" PRIx64, reg_val);
        if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
            UnwindLogMsg ("sp = 0x%16.16" PRIx64, reg_val);
    }

    // A pc of 0x0 means it's the end of the stack crawl
    if (pc == 0)
    {
        m_frame_type = eNotAValidFrame;
        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);

    process->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc);

    // 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;
                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;
            addr_t cfa_regval;
            int row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
            UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0);
            if (row.get())
            {
                uint32_t cfa_regnum = row->GetCFARegister();
                int cfa_offset = row->GetCFAOffset();
                if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval))
                {
                    UnwindLogMsg ("failed to get cfa value");
                    if (m_frame_type != eSkipFrame)   // don't override eSkipFrame
                    {
                        m_frame_type = eNormalFrame;
                    }
                    return;
                }
                m_cfa = cfa_regval + cfa_offset;

                // A couple of sanity checks..
                if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
                {
                    UnwindLogMsg ("could not find a valid cfa address");
                    m_frame_type = eNotAValidFrame;
                    return;
                }

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

            UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64, (uint64_t) m_cfa);
            return;
        }
        m_frame_type = eNotAValidFrame;
        return;
    }

    // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us.
    if ((pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
    {
        m_sym_ctx_valid = true;
    }

    AddressRange addr_range;
    if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 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 != eSigtrampFrame
        && 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)
    {
        Address temporary_pc(m_current_pc);
        temporary_pc.SetOffset(m_current_pc.GetOffset() - 1);
        m_sym_ctx.Clear(false);
        m_sym_ctx_valid = false;
        if ((pc_module_sp->ResolveSymbolContextForAddress (temporary_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
        {
            m_sym_ctx_valid = true;
        }
        if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false,  addr_range))
        {
            m_sym_ctx_valid = false;
        }
    }

    // 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 = m_current_pc.GetOffset() - m_start_pc.GetOffset();
        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--;
    }
    else
    {
        m_start_pc = m_current_pc;
        m_current_offset = -1;
        m_current_offset_backed_up_one = -1;
    }

    static ConstString sigtramp_name ("_sigtramp");
    if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
        || (m_sym_ctx.symbol && m_sym_ctx.symbol->GetMangled().GetMangledName() == sigtramp_name))
    {
        m_frame_type = eSigtrampFrame;
    }
    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;
    int cfa_offset = 0;
    int row_register_kind = -1;

    // 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 ();
        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 ("active row: %s", active_row_strm.GetString().c_str());
            }
        }
    }

    if (!active_row.get())
    {
        m_frame_type = eNotAValidFrame;
        return;
    }

    addr_t cfa_regval;
    if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval))
    {
        UnwindLogMsg ("failed to get cfa reg %d/%d", row_register_kind, active_row->GetCFARegister());
        m_frame_type = eNotAValidFrame;
        return;
    }
    cfa_offset = active_row->GetCFAOffset ();

    m_cfa = cfa_regval + cfa_offset;

    UnwindLogMsg ("cfa_regval = 0x%16.16" PRIx64 " (cfa_regval = 0x%16.16" PRIx64 ", cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);

    // A couple of sanity checks..
    if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
    {
        UnwindLogMsg ("could not find a valid cfa address");
        m_frame_type = eNotAValidFrame;
        return;
    }

    // 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.
    addr_t next_frame_cfa;
    addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
    if (GetNextFrame().get() && GetNextFrame()->GetCFA(next_frame_cfa))
    {
        bool repeating_frames = false;
        if (next_frame_cfa == m_cfa)
        {
            repeating_frames = true;
        }
        else
        {
            if (GetNextFrame()->GetNextFrame() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa)
                && next_next_frame_cfa == m_cfa)
            {
                repeating_frames = true;
            }
        }
        if (repeating_frames && abi->FunctionCallsChangeCFA())
        {
            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::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 eSigtrampFrame/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 == eSigtrampFrame || m_frame_type == eDebuggerFrame)
        return unwind_plan_sp;

    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (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 eSigtrampFrame/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);
    }

    bool behaves_like_zeroth_frame = false;
    if (IsFrameZero ()
        || GetNextFrame()->m_frame_type == eSigtrampFrame
        || 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 the symbol context has a function for the symbol, then we don't need to do this check.

    if ((!m_sym_ctx_valid  || m_sym_ctx.function == 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->GetLoadAddressPermissions(current_pc_addr, permissions)
                && (permissions & ePermissionsExecutable) == 0))
        {
            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, try using architectural default unwind.
    if (!func_unwinders_sp)
    {
        m_frame_type = eNormalFrame;
        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 == eSigtrampFrame)
    {
        m_fast_unwind_plan_sp.reset();
        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
        if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
            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))
    {
        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (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)
    {
        unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread);
        if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
        {
            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
    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
    {
        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.
    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread);
    if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
    {
        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.
    UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString());
    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 (uint32_t 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::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::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;
}

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

// 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)
{
    // 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 (lldb_regnum);
        if (iterator != m_registers.end())
        {
            regloc = iterator->second;
            UnwindLogMsg ("supplying caller's saved reg %d's location, cached", lldb_regnum);
            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
        }
    }

    static uint32_t sp_regnum = LLDB_INVALID_REGNUM;
    static uint32_t pc_regnum = LLDB_INVALID_REGNUM;
    static bool generic_registers_initialized = false;
    if (!generic_registers_initialized)
    {
        m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, eRegisterKindLLDB, sp_regnum);
        m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, eRegisterKindLLDB, pc_regnum);
        generic_registers_initialized = true;
    }

    // Are we looking for the CALLER's stack pointer?  The stack pointer is defined to be the same as THIS frame's
    // CFA so just return the CFA value.  This is true on x86-32/x86-64 at least.
    if (sp_regnum != LLDB_INVALID_REGNUM && sp_regnum == lldb_regnum)
    {
        // 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[lldb_regnum] = regloc;
        UnwindLogMsg ("supplying caller's stack pointer (%d) value, computed from CFA", lldb_regnum);
        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 = (RegisterKind)-1;

    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 ();
        uint32_t row_regnum;
        if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
        {
            UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
                    lldb_regnum, (int) unwindplan_registerkind);
            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
        }
        if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
        {
            UnwindLogMsg ("supplying caller's saved reg %d's location using FastUnwindPlan", lldb_regnum);
            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)
        {
            UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
            unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
            uint32_t row_regnum;
            bool row_register_rewritten_to_return_address_reg = false;

            // 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 (lldb_regnum == pc_regnum && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
            {
               row_regnum = m_full_unwind_plan_sp->GetReturnAddressRegister();
               row_register_rewritten_to_return_address_reg = true;
               UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead",
                       row_regnum);
            }
            else
            {
                if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
                {
                    if (unwindplan_registerkind == eRegisterKindGeneric)
                        UnwindLogMsg ("could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme", lldb_regnum);
                    else
                        UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
                                lldb_regnum, (int) unwindplan_registerkind);
                    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
                }
            }

            if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
            {
                have_unwindplan_regloc = true;
                UnwindLogMsg ("supplying caller's saved reg %d's location using %s UnwindPlan", lldb_regnum,
                              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 
                && row_register_rewritten_to_return_address_reg == true 
                && IsFrameZero()
                && row_regnum != LLDB_INVALID_REGNUM)
            {
                uint32_t ra_regnum_in_lldb_reg_numbering;
                if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, row_regnum, eRegisterKindLLDB, ra_regnum_in_lldb_reg_numbering))
                {
                    lldb_private::UnwindLLDB::RegisterLocation new_regloc;
                    new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
                    new_regloc.location.register_number = ra_regnum_in_lldb_reg_numbering;
                    m_registers[lldb_regnum] = new_regloc;
                    regloc = new_regloc;
                    UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0, saved in %d", lldb_regnum, ra_regnum_in_lldb_reg_numbering);
                    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
            uint32_t arch_default_ra_regnum = LLDB_INVALID_REGNUM; 
            if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, unwindplan_registerkind, arch_default_ra_regnum)
                && arch_default_ra_regnum != LLDB_INVALID_REGNUM
                && pc_regnum != LLDB_INVALID_REGNUM
                && pc_regnum == lldb_regnum
                && unwindplan_regloc.IsInOtherRegister()
                && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum
                && 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
                InvalidateFullUnwindPlan();

                // Now re-fetch the pc value we're searching for
                uint32_t arch_default_pc_reg = LLDB_INVALID_REGNUM;
                UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
                if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, m_full_unwind_plan_sp->GetRegisterKind(), arch_default_pc_reg)
                    && arch_default_pc_reg != LLDB_INVALID_REGNUM
                    && active_row
                    && active_row->GetRegisterInfo (arch_default_pc_reg, unwindplan_regloc))
                {
                    have_unwindplan_regloc = true;
                }
                else
                {
                    have_unwindplan_regloc = false;
                }
            }
        }
    }


    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(lldb_regnum);
            if (reg_info && abi->RegisterIsVolatile (reg_info))
            {
                UnwindLogMsg ("did not supply reg location for %d because it is volatile", lldb_regnum);
                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::eRegisterInRegister;
            new_regloc.location.register_number = lldb_regnum;
            m_registers[lldb_regnum] = new_regloc;
            regloc = new_regloc;
            UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0", lldb_regnum);
            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
        }
        else
        UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
        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[lldb_regnum] = new_regloc;
        UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }

    if (unwindplan_regloc.IsSame())
    {
        if (IsFrameZero ())
        {
            UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
        }
        else
        {
            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
        }
    }

    if (unwindplan_regloc.IsCFAPlusOffset())
    {
        int offset = unwindplan_regloc.GetOffset();
        regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
        regloc.location.inferred_value = m_cfa + offset;
        m_registers[lldb_regnum] = regloc;
        UnwindLogMsg ("supplying caller's register %d, value is CFA plus offset", lldb_regnum);
        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[lldb_regnum] = regloc;
        UnwindLogMsg ("supplying caller's register %d from the stack, saved at CFA plus offset", lldb_regnum);
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }

    if (unwindplan_regloc.IsInOtherRegister())
    {
        uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber();
        uint32_t row_regnum_in_lldb;
        if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
        {
            UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
            return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
        }
        regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
        regloc.location.register_number = row_regnum_in_lldb;
        m_registers[lldb_regnum] = regloc;
        UnwindLogMsg ("supplying caller's register %d, saved in register %d", lldb_regnum, row_regnum_in_lldb);
        return UnwindLLDB::RegisterSearchResult::eRegisterFound;
    }

    if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
    {
        DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
                                 unwindplan_regloc.GetDWARFExpressionLength(),
                                 process->GetByteOrder(), process->GetAddressByteSize());
        DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength());
        dwarfexpr.SetRegisterKind (unwindplan_registerkind);
        Value result;
        Error error;
        if (dwarfexpr.Evaluate (&exe_ctx, NULL, 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[lldb_regnum] = regloc;
                UnwindLogMsg ("supplying caller's register %d via DWARF expression (IsDWARFExpression)", lldb_regnum);
                return UnwindLLDB::RegisterSearchResult::eRegisterFound;
            }
            else
            {
                regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
                regloc.location.target_memory_location = val;
                m_registers[lldb_regnum] = regloc;
                UnwindLogMsg ("supplying caller's register %d via DWARF expression (IsAtDWARFExpression)", lldb_regnum);
                return UnwindLLDB::RegisterSearchResult::eRegisterFound;
            }
        }
        UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed", lldb_regnum);
        return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
    }

    UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);

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

    return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}

// If the Full unwindplan has been determined to be incorrect, this method will
// replace it with the architecture's default unwindplna, if one is defined.
// It will also find the FuncUnwinders object for this function and replace the
// Full unwind method for the function there so we don't use the errant Full unwindplan
// again in the future of this debug session.
// We're most likely doing this because the Full unwindplan was generated by assembly
// instruction profiling and the profiler got something wrong.

void
RegisterContextLLDB::InvalidateFullUnwindPlan ()
{
    UnwindPlan::Row::RegisterLocation unwindplan_regloc;
    ExecutionContext exe_ctx (m_thread.shared_from_this());
    Process *process = exe_ctx.GetProcessPtr();
    ABI *abi = process ? process->GetABI().get() : NULL;
    if (abi)
    {
        UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp;
        UnwindPlanSP arch_default_unwind_plan_sp;
        arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric));
        abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp);
        if (arch_default_unwind_plan_sp)
        {
            UnwindPlan::RowSP active_row = arch_default_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
        
            if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM)
            {
                FuncUnwindersSP func_unwinders_sp;
                if (m_sym_ctx_valid && m_current_pc.IsValid() && m_current_pc.GetModule())
                {
                    func_unwinders_sp = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
                    if (func_unwinders_sp)
                    {
                        func_unwinders_sp->InvalidateNonCallSiteUnwindPlan (m_thread);
                    }
                }
                m_registers.clear();
                m_full_unwind_plan_sp = arch_default_unwind_plan_sp;
                addr_t cfa_regval;
                if (ReadGPRValue (arch_default_unwind_plan_sp->GetRegisterKind(), active_row->GetCFARegister(), cfa_regval))
                {
                    m_cfa = cfa_regval + active_row->GetCFAOffset ();
                }

                UnwindLogMsg ("full unwind plan '%s' has been replaced by architecture default unwind plan '%s' for this function from now on.",
                              original_full_unwind_plan_sp->GetSourceName().GetCString(), arch_default_unwind_plan_sp->GetSourceName().GetCString());
            }
        }
    }
}

// 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 (int 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;
}

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

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

