blob: 1b6fa58dcd4846ffff33aaa0d327e718b15e6c09 [file] [log] [blame]
//===-- 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->GetID();
const uint32_t frame_count = GetFrameCount();
if (idx < frame_count)
return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]);
return NULL;
}