blob: bbc58a21cc0fcc65f767a517f0427118078e4ff6 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- UnwindLibUnwind.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "lldb/Target/Thread.h"
15#include "UnwindLibUnwind.h"
16#include "LibUnwindRegisterContext.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21UnwindLibUnwind::UnwindLibUnwind (Thread &thread, unw_addr_space_t addr_space) :
22 Unwind (thread),
23 m_addr_space (addr_space),
24 m_cursors()
25{
26 m_pc_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
27 m_sp_regnum = thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
28}
29
30uint32_t
31UnwindLibUnwind::GetFrameCount()
32{
33 if (m_cursors.empty())
34 {
35 unw_cursor_t cursor;
36 unw_init_remote (&cursor, m_addr_space, &m_thread);
37
38 m_cursors.push_back (cursor);
39
40 while (1)
41 {
42 int stepresult = unw_step (&cursor);
43 if (stepresult > 0)
44 m_cursors.push_back (cursor);
45 else
46 break;
47 }
48 }
49 return m_cursors.size();
50}
51
52bool
53UnwindLibUnwind::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
54{
55 const uint32_t frame_count = GetFrameCount();
56 if (idx < frame_count)
57 {
58 int pc_err = unw_get_reg (&m_cursors[idx], m_pc_regnum, &pc);
59 int sp_err = unw_get_reg (&m_cursors[idx], m_sp_regnum, &cfa);
60 return pc_err == UNW_ESUCCESS && sp_err == UNW_ESUCCESS;
61 }
62 return false;
63}
64
65RegisterContext *
66UnwindLibUnwind::CreateRegisterContextForFrame (StackFrame *frame)
67{
Greg Clayton4fb08152010-08-30 18:11:35 +000068 uint32_t idx = frame->GetUnwindFrameIndex ();
Chris Lattner24943d22010-06-08 16:52:24 +000069 const uint32_t frame_count = GetFrameCount();
70 if (idx < frame_count)
71 return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]);
72 return NULL;
73}