Files
clang-p2996/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp
Greg Clayton 59e8fc1c74 Clarified the intent of the SymbolContextScope class in the header
documentation. Symbol now inherits from the symbol
context scope so that the StackID can use a "SymbolContextScope *"
instead of a blockID (which could have been the same as some other
blockID from another symbol file). 

Modified the stacks that are created on subsequent stops to reuse
the previous stack frame objects which will allow for some internal
optimization using pointer comparisons during stepping. 

llvm-svn: 112495
2010-08-30 18:11:35 +00:00

74 lines
2.1 KiB
C++

//===-- UnwindLibUnwind.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/Thread.h"
#include "UnwindLibUnwind.h"
#include "LibUnwindRegisterContext.h"
using namespace lldb;
using namespace lldb_private;
UnwindLibUnwind::UnwindLibUnwind (Thread &thread, unw_addr_space_t addr_space) :
Unwind (thread),
m_addr_space (addr_space),
m_cursors()
{
m_pc_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
m_sp_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
}
uint32_t
UnwindLibUnwind::GetFrameCount()
{
if (m_cursors.empty())
{
unw_cursor_t cursor;
unw_init_remote (&cursor, m_addr_space, &m_thread);
m_cursors.push_back (cursor);
while (1)
{
int stepresult = unw_step (&cursor);
if (stepresult > 0)
m_cursors.push_back (cursor);
else
break;
}
}
return m_cursors.size();
}
bool
UnwindLibUnwind::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
{
const uint32_t frame_count = GetFrameCount();
if (idx < frame_count)
{
int pc_err = unw_get_reg (&m_cursors[idx], m_pc_regnum, &pc);
int sp_err = unw_get_reg (&m_cursors[idx], m_sp_regnum, &cfa);
return pc_err == UNW_ESUCCESS && sp_err == UNW_ESUCCESS;
}
return false;
}
RegisterContext *
UnwindLibUnwind::CreateRegisterContextForFrame (StackFrame *frame)
{
uint32_t idx = frame->GetUnwindFrameIndex ();
const uint32_t frame_count = GetFrameCount();
if (idx < frame_count)
return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]);
return NULL;
}