summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp')
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp73
1 files changed, 73 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp
new file mode 100644
index 00000000000..1b6fa58dcd4
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp
@@ -0,0 +1,73 @@
+//===-- 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;
+}
OpenPOWER on IntegriCloud