Restructure the relationship between UnwindLLDB and the

RegisterContextLLDBs it contains.

Previously RegisterContextLLDB objects had a pointer to their "next"
frame down the stack.  e.g. stack starts at frame 0; frame 3 has a
pointer to frame 2.  This is used to retreive callee saved register
values.  When debugging an inferior that has blown out its own stack,
however, this could result in lldb blowing out its own stack while
recursing down to retrieve register values.

RegisterContextLLDB no longer has a pointer to its next frame; it 
has a reference to the UnwindLLDB which contains it.  When it needs
to retrieve a reg value, it asks the UnwindLLDB for that reg value
and UnwindLLDB iterates through the frames until it finds a location.

llvm-svn: 143423
This commit is contained in:
Jason Molenda 2011-11-01 03:21:25 +00:00
parent 2b59cf30e4
commit 707fec479c
4 changed files with 154 additions and 100 deletions

View File

@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
#include "RegisterContextLLDB.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
@ -28,20 +27,21 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.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
uint32_t frame_number,
UnwindLLDB& unwind_lldb
) :
RegisterContext (thread, frame_number),
m_thread(thread),
m_next_frame(next_frame),
m_fast_unwind_plan_sp (),
m_full_unwind_plan_sp (),
m_all_registers_available(false),
@ -54,7 +54,8 @@ RegisterContextLLDB::RegisterContextLLDB
m_sym_ctx(sym_ctx),
m_sym_ctx_valid (false),
m_frame_number (frame_number),
m_registers()
m_registers(),
m_parent_unwind (unwind_lldb)
{
m_sym_ctx.Clear();
m_sym_ctx_valid = false;
@ -70,8 +71,8 @@ RegisterContextLLDB::RegisterContextLLDB
// This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
if (IsFrameZero()
|| m_next_frame->m_frame_type == eSigtrampFrame
|| m_next_frame->m_frame_type == eDebuggerFrame)
|| next_frame->m_frame_type == eSigtrampFrame
|| next_frame->m_frame_type == eDebuggerFrame)
{
m_all_registers_available = true;
}
@ -207,7 +208,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
return;
}
if (!m_next_frame->IsValid())
if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
{
m_frame_type = eNotAValidFrame;
return;
@ -331,8 +332,8 @@ RegisterContextLLDB::InitializeNonZerothFrame()
// 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
&& m_next_frame->m_frame_type != eSigtrampFrame
&& m_next_frame->m_frame_type != eDebuggerFrame
&& 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())
@ -453,7 +454,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
// 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 (m_next_frame.get() && m_next_frame->GetCFA(next_frame_cfa))
if (GetNextFrame().get() && GetNextFrame()->GetCFA(next_frame_cfa))
{
bool repeating_frames = false;
if (next_frame_cfa == m_cfa)
@ -462,7 +463,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
}
else
{
if (m_next_frame->GetNextFrame() && m_next_frame->GetNextFrame()->GetCFA(next_next_frame_cfa)
if (GetNextFrame()->GetNextFrame() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa)
&& next_next_frame_cfa == m_cfa)
{
repeating_frames = true;
@ -492,10 +493,7 @@ RegisterContextLLDB::InitializeNonZerothFrame()
bool
RegisterContextLLDB::IsFrameZero () const
{
if (m_next_frame.get () == NULL)
return true;
else
return false;
return m_frame_number == 0;
}
@ -575,8 +573,8 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame ()
bool behaves_like_zeroth_frame = false;
if (IsFrameZero ()
|| m_next_frame->m_frame_type == eSigtrampFrame
|| m_next_frame->m_frame_type == eDebuggerFrame)
|| 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
@ -720,7 +718,7 @@ RegisterContextLLDB::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_
}
bool
RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (RegisterLocation regloc,
RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const RegisterInfo *reg_info,
RegisterValue &value)
{
@ -730,7 +728,7 @@ RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (RegisterLocation reg
switch (regloc.type)
{
case eRegisterInRegister:
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
{
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
if (IsFrameZero ())
@ -739,20 +737,20 @@ RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (RegisterLocation reg
}
else
{
success = m_next_frame->ReadRegister (other_reg_info, value);
success = GetNextFrame()->ReadRegister (other_reg_info, value);
}
}
break;
case eRegisterValueInferred:
case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size);
break;
case eRegisterNotSaved:
case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
break;
case eRegisterSavedAtHostMemoryLocation:
case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
assert ("FIXME debugger inferior function call unwind");
break;
case eRegisterSavedAtMemoryLocation:
case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
{
Error error (ReadRegisterValueFromMemory(reg_info,
regloc.location.target_memory_location,
@ -769,7 +767,7 @@ RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (RegisterLocation reg
}
bool
RegisterContextLLDB::WriteRegisterValueToRegisterLocation (RegisterLocation regloc,
RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const RegisterInfo *reg_info,
const RegisterValue &value)
{
@ -780,7 +778,7 @@ RegisterContextLLDB::WriteRegisterValueToRegisterLocation (RegisterLocation regl
switch (regloc.type)
{
case eRegisterInRegister:
case UnwindLLDB::RegisterLocation::eRegisterInRegister:
{
const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
if (IsFrameZero ())
@ -789,17 +787,17 @@ RegisterContextLLDB::WriteRegisterValueToRegisterLocation (RegisterLocation regl
}
else
{
success = m_next_frame->WriteRegister (other_reg_info, value);
success = GetNextFrame()->WriteRegister (other_reg_info, value);
}
}
break;
case eRegisterValueInferred:
case eRegisterNotSaved:
case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
break;
case eRegisterSavedAtHostMemoryLocation:
case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
assert ("FIXME debugger inferior function call unwind");
break;
case eRegisterSavedAtMemoryLocation:
case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
{
Error error (WriteRegisterValueToMemory (reg_info,
regloc.location.target_memory_location,
@ -825,14 +823,14 @@ RegisterContextLLDB::IsValid () const
// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
bool
RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLocation &regloc)
RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, bool check_next_frame)
{
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
// Have we already found this register location?
if (!m_registers.empty())
{
std::map<uint32_t, RegisterLocation>::const_iterator iterator;
std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator;
iterator = m_registers.find (lldb_regnum);
if (iterator != m_registers.end())
{
@ -849,7 +847,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
{
// 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 = eRegisterValueInferred;
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = m_cfa;
m_registers[lldb_regnum] = regloc;
return true;
@ -930,7 +928,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
if (have_unwindplan_regloc == false)
{
// If a volatile register is being requested, we don't want to forward m_next_frame's register contents
// 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 = m_thread.GetProcess().GetABI().get();
if (abi)
@ -951,8 +949,8 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
if (IsFrameZero ())
{
// This is frame 0 - we should return the actual live register context value
RegisterLocation new_regloc;
new_regloc.type = eRegisterInRegister;
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;
@ -960,7 +958,8 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
}
else
{
return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc);
if (check_next_frame)
return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1);
}
if (log)
{
@ -974,8 +973,8 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
// unwindplan_regloc has valid contents about where to retrieve the register
if (unwindplan_regloc.IsUnspecified())
{
RegisterLocation new_regloc;
new_regloc.type = eRegisterNotSaved;
lldb_private::UnwindLLDB::RegisterLocation new_regloc;
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
m_registers[lldb_regnum] = new_regloc;
if (log)
{
@ -1000,14 +999,17 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
}
else
{
return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc);
if (check_next_frame)
return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1);
else
return false;
}
}
if (unwindplan_regloc.IsCFAPlusOffset())
{
int offset = unwindplan_regloc.GetOffset();
regloc.type = eRegisterValueInferred;
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = m_cfa + offset;
m_registers[lldb_regnum] = regloc;
return true;
@ -1016,7 +1018,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
if (unwindplan_regloc.IsAtCFAPlusOffset())
{
int offset = unwindplan_regloc.GetOffset();
regloc.type = eRegisterSavedAtMemoryLocation;
regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
regloc.location.target_memory_location = m_cfa + offset;
m_registers[lldb_regnum] = regloc;
return true;
@ -1036,7 +1038,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
}
return false;
}
regloc.type = eRegisterInRegister;
regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
regloc.location.register_number = row_regnum_in_lldb;
m_registers[lldb_regnum] = regloc;
return true;
@ -1058,14 +1060,14 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
val = result.GetScalar().ULongLong();
if (unwindplan_regloc.IsDWARFExpression())
{
regloc.type = eRegisterValueInferred;
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = val;
m_registers[lldb_regnum] = regloc;
return true;
}
else
{
regloc.type = eRegisterSavedAtMemoryLocation;
regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
regloc.location.target_memory_location = val;
m_registers[lldb_regnum] = regloc;
return true;
@ -1135,8 +1137,8 @@ RegisterContextLLDB::ReadGPRValue (int register_kind, uint32_t regnum, addr_t &v
return false;
}
RegisterLocation regloc;
if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
lldb_private::UnwindLLDB::RegisterLocation regloc;
if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
{
return false;
}
@ -1177,9 +1179,9 @@ RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &
return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
}
RegisterLocation regloc;
lldb_private::UnwindLLDB::RegisterLocation regloc;
// Find out where the NEXT frame saved THIS frame's register contents
if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
return false;
return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
@ -1212,9 +1214,9 @@ RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const Register
return m_thread.GetRegisterContext()->WriteRegister (reg_info, value);
}
RegisterLocation regloc;
lldb_private::UnwindLLDB::RegisterLocation regloc;
// Find out where the NEXT frame saved THIS frame's register contents
if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
return false;
return WriteRegisterValueToRegisterLocation (regloc, reg_info, value);
@ -1253,9 +1255,12 @@ RegisterContextLLDB::GetCFA (addr_t& cfa)
RegisterContextLLDB::SharedPtr
RegisterContextLLDB::GetNextFrame ()
RegisterContextLLDB::GetNextFrame () const
{
return m_next_frame;
RegisterContextLLDB::SharedPtr regctx;
if (m_frame_number == 0)
return regctx;
return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number - 1);
}
// Retrieve the address of the start of the function of THIS frame
@ -1302,3 +1307,4 @@ RegisterContextLLDB::ReadPC (addr_t& pc)
return false;
}
}

View File

@ -16,6 +16,11 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Symbol/SymbolContext.h"
#include "UnwindLLDB.h"
namespace lldb_private {
class UnwindLLDB;
class RegisterContextLLDB : public lldb_private::RegisterContext
{
@ -25,7 +30,7 @@ public:
RegisterContextLLDB (lldb_private::Thread &thread,
const SharedPtr& next_frame,
lldb_private::SymbolContext& sym_ctx,
uint32_t frame_number);
uint32_t frame_number, lldb_private::UnwindLLDB& unwind_lldb);
///
// pure virtual functions from the base class that we must implement
@ -86,33 +91,11 @@ private:
eNotAValidFrame // this frame is invalid for some reason - most likely it is past the top (end) of the stack
};
enum RegisterLocationTypes
{
eRegisterNotSaved = 0, // register was not preserved by callee. If volatile reg, is unavailable
eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
eRegisterInRegister, // register is available in a (possible other) register (register_number)
eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
eRegisterValueInferred // register val was computed (and is in inferred_value)
};
struct RegisterLocation
{
int type;
union
{
lldb::addr_t target_memory_location;
uint32_t register_number; // in eRegisterKindLLDB register numbering system
void* host_memory_location;
uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset
} location;
};
// UnwindLLDB needs to pass around references to RegisterLocations
friend class UnwindLLDB;
// Indicates whether this frame is frame zero -- the currently
// executing frame -- or not. If it is not frame zero, m_next_frame's
// shared pointer holds a pointer to the RegisterContextLLDB
// object "below" this frame, i.e. this frame called m_next_frame's
// function.
// executing frame -- or not.
bool
IsFrameZero () const;
@ -123,7 +106,7 @@ private:
InitializeNonZerothFrame();
SharedPtr
GetNextFrame ();
GetNextFrame () const;
// Provide a location for where THIS function saved the CALLER's register value
// Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
@ -137,22 +120,25 @@ private:
// stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
// as the requesting frame's.
//
// NB this function takes a "check_next_frame" boolean which indicates whether it should call back to the
// containing UnwindLLDB object to iterate the search down the stack (true) or if this call should look for
// a register save for that reg in the current frame only (false). Allows UnwindLLDB to iterate through the
// RegisterContextLLDB's instead of using recursion to find saved register values.
bool
SavedLocationForRegister (uint32_t lldb_regnum, RegisterLocation &regloc);
SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, bool check_next_frame);
bool
ReadRegisterValueFromRegisterLocation (RegisterLocation regloc,
ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const lldb_private::RegisterInfo *reg_info,
lldb_private::RegisterValue &value);
bool
WriteRegisterValueToRegisterLocation (RegisterLocation regloc,
WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
const lldb_private::RegisterInfo *reg_info,
const lldb_private::RegisterValue &value);
// Get the contents of a general purpose (address-size) register for this frame
// (usually retrieved from the m_next_frame)
// m_base_reg_ectx and m_next_frame should both be initialized appropriately before calling.
// (usually retrieved from the next frame)
bool
ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
@ -164,8 +150,6 @@ private:
lldb_private::Thread& m_thread;
SharedPtr m_next_frame;
///
// The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
// i.e. where THIS frame saved them
@ -194,9 +178,11 @@ private:
lldb_private::SymbolContext& m_sym_ctx;
bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
uint32_t m_frame_number; // What stack frame level this frame is - used for debug logging
uint32_t m_frame_number; // What stack frame this RegisterContext is
std::map<uint32_t, RegisterLocation> m_registers; // where to find reg values for this frame
std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> m_registers; // where to find reg values for this frame
lldb_private::UnwindLLDB& m_parent_unwind; // The UnwindLLDB that is creating this RegisterContextLLDB
//------------------------------------------------------------------
// For RegisterContextLLDB only
@ -205,4 +191,6 @@ private:
DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB);
};
} // namespace lldb_private
#endif // lldb_RegisterContextLLDB_h_

View File

@ -69,10 +69,10 @@ UnwindLLDB::AddFirstFrame ()
{
// First, set up the 0th (initial) frame
CursorSP first_cursor_sp(new Cursor ());
RegisterContextLLDB::SharedPtr reg_ctx_sp (new RegisterContextLLDB (m_thread,
RegisterContextLLDB::SharedPtr(),
RegisterContextLLDBSharedPtr reg_ctx_sp (new RegisterContextLLDB (m_thread,
RegisterContextLLDBSharedPtr(),
first_cursor_sp->sctx,
0));
0, *this));
if (reg_ctx_sp.get() == NULL)
return false;
@ -104,10 +104,10 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
return false;
uint32_t cur_idx = m_frames.size ();
RegisterContextLLDB::SharedPtr reg_ctx_sp(new RegisterContextLLDB (m_thread,
RegisterContextLLDBSharedPtr reg_ctx_sp(new RegisterContextLLDB (m_thread,
m_frames[cur_idx - 1]->reg_ctx,
cursor_sp->sctx,
cur_idx));
cur_idx, *this));
if (reg_ctx_sp.get() == NULL)
return false;
@ -225,3 +225,28 @@ UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
reg_ctx_sp = m_frames[idx]->reg_ctx;
return reg_ctx_sp;
}
UnwindLLDB::RegisterContextLLDBSharedPtr
UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
{
RegisterContextLLDBSharedPtr reg_ctx_sp;
if (frame_num >= m_frames.size())
return reg_ctx_sp;
reg_ctx_sp = m_frames[frame_num]->reg_ctx;
return reg_ctx_sp;
}
bool
UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num)
{
int64_t frame_num = starting_frame_num;
if (frame_num >= m_frames.size())
return false;
while (frame_num >= 0)
{
if (m_frames[frame_num]->reg_ctx->SavedLocationForRegister (lldb_regnum, regloc, false))
return true;
frame_num--;
}
return false;
}

View File

@ -18,10 +18,10 @@
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Unwind.h"
#include "RegisterContextLLDB.h"
namespace lldb_private {
class RegisterContextLLDB;
class UnwindLLDB : public lldb_private::Unwind
{
public:
@ -29,8 +29,29 @@ public:
virtual
~UnwindLLDB() { }
protected:
friend class lldb_private::RegisterContextLLDB;
struct RegisterLocation {
enum RegisterLocationTypes
{
eRegisterNotSaved = 0, // register was not preserved by callee. If volatile reg, is unavailable
eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
eRegisterInRegister, // register is available in a (possible other) register (register_number)
eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
eRegisterValueInferred // register val was computed (and is in inferred_value)
};
int type;
union
{
lldb::addr_t target_memory_location;
uint32_t register_number; // in eRegisterKindLLDB register numbering system
void* host_memory_location;
uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset
} location;
};
void
DoClear()
{
@ -48,13 +69,27 @@ protected:
lldb::RegisterContextSP
DoCreateRegisterContextForFrame (lldb_private::StackFrame *frame);
typedef lldb::SharedPtr<lldb_private::RegisterContextLLDB>::Type RegisterContextLLDBSharedPtr;
// Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame 1's RegisterContextLLDB)
// The RegisterContext for frame_num must already exist or this returns an empty shared pointer.
RegisterContextLLDBSharedPtr
GetRegisterContextForFrameNum (uint32_t frame_num);
// Iterate over the RegisterContextLLDB's in our m_frames vector, look for the first one that
// has a saved location for this reg.
bool
SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num);
private:
struct Cursor
{
lldb::addr_t start_pc; // The start address of the function/symbol for this frame - current pc if unknown
lldb::addr_t cfa; // The canonical frame address for this stack frame
lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & provide to the StackFrame creation
RegisterContextLLDB::SharedPtr reg_ctx; // These are all RegisterContextLLDB's
RegisterContextLLDBSharedPtr reg_ctx; // These are all RegisterContextLLDB's
Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { }
private: