summaryrefslogtreecommitdiff
path: root/source/Plugins/Process/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/Utility')
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.cpp95
-rw-r--r--source/Plugins/Process/Utility/HistoryThread.h114
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.cpp79
-rw-r--r--source/Plugins/Process/Utility/HistoryUnwind.h51
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp141
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.cpp138
-rw-r--r--source/Plugins/Process/Utility/RegisterContextHistory.h79
7 files changed, 619 insertions, 78 deletions
diff --git a/source/Plugins/Process/Utility/HistoryThread.cpp b/source/Plugins/Process/Utility/HistoryThread.cpp
new file mode 100644
index 000000000000..521136295fd5
--- /dev/null
+++ b/source/Plugins/Process/Utility/HistoryThread.cpp
@@ -0,0 +1,95 @@
+//===-- HistoryThread.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-private.h"
+
+#include "Plugins/Process/Utility/HistoryUnwind.h"
+#include "Plugins/Process/Utility/HistoryThread.h"
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Target/StackFrameList.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+HistoryThread::HistoryThread (lldb_private::Process &process,
+ lldb::tid_t tid,
+ std::vector<lldb::addr_t> pcs,
+ uint32_t stop_id,
+ bool stop_id_is_valid) :
+ Thread (process, LLDB_INVALID_THREAD_ID),
+ m_framelist_mutex(),
+ m_framelist(),
+ m_pcs (pcs),
+ m_stop_id (stop_id),
+ m_stop_id_is_valid (stop_id_is_valid),
+ m_extended_unwind_token (LLDB_INVALID_ADDRESS),
+ m_queue_name (),
+ m_thread_name (),
+ m_originating_unique_thread_id (tid),
+ m_queue_id (LLDB_INVALID_QUEUE_ID)
+{
+ m_unwinder_ap.reset (new HistoryUnwind (*this, pcs, stop_id, stop_id_is_valid));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf ("%p HistoryThread::HistoryThread", this);
+}
+
+HistoryThread::~HistoryThread ()
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf ("%p HistoryThread::~HistoryThread (tid=0x%" PRIx64 ")", this, GetID());
+ DestroyThread();
+}
+
+lldb::RegisterContextSP
+HistoryThread::GetRegisterContext ()
+{
+ RegisterContextSP rctx ;
+ if (m_pcs.size() > 0)
+ {
+ rctx.reset (new RegisterContextHistory (*this, 0, GetProcess()->GetAddressByteSize(), m_pcs[0]));
+ }
+ return rctx;
+
+}
+
+lldb::RegisterContextSP
+HistoryThread::CreateRegisterContextForFrame (StackFrame *frame)
+{
+ return m_unwinder_ap->CreateRegisterContextForFrame (frame);
+}
+
+lldb::StackFrameListSP
+HistoryThread::GetStackFrameList ()
+{
+ Mutex::Locker (m_framelist_mutex);
+ if (m_framelist.get() == NULL)
+ {
+ m_framelist.reset (new StackFrameList (*this, StackFrameListSP(), true));
+ }
+
+ return m_framelist;
+}
+
+uint32_t
+HistoryThread::GetExtendedBacktraceOriginatingIndexID ()
+{
+ if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID)
+ {
+ if (GetProcess()->HasAssignedIndexIDToThread (m_originating_unique_thread_id))
+ {
+ return GetProcess()->AssignIndexIDToThread (m_originating_unique_thread_id);
+ }
+ }
+ return LLDB_INVALID_THREAD_ID;
+}
diff --git a/source/Plugins/Process/Utility/HistoryThread.h b/source/Plugins/Process/Utility/HistoryThread.h
new file mode 100644
index 000000000000..01fdd1608706
--- /dev/null
+++ b/source/Plugins/Process/Utility/HistoryThread.h
@@ -0,0 +1,114 @@
+//===-- HistoryThread.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_HistoryThread_h_
+#define liblldb_HistoryThread_h_
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Event.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Core/UserSettingsController.h"
+#include "lldb/Target/ExecutionContextScope.h"
+#include "lldb/Target/StackFrameList.h"
+#include "lldb/Target/Thread.h"
+
+namespace lldb_private {
+
+class HistoryThread : public lldb_private::Thread
+{
+public:
+ HistoryThread (lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid);
+
+ virtual ~HistoryThread ();
+
+ virtual lldb::RegisterContextSP
+ GetRegisterContext ();
+
+ virtual lldb::RegisterContextSP
+ CreateRegisterContextForFrame (StackFrame *frame);
+
+ virtual void
+ RefreshStateAfterStop() { }
+
+ bool
+ CalculateStopInfo () { return false; }
+
+ void
+ SetExtendedBacktraceToken (uint64_t token)
+ {
+ m_extended_unwind_token = token;
+ }
+
+ uint64_t
+ GetExtendedBacktraceToken ()
+ {
+ return m_extended_unwind_token;
+ }
+
+ const char *
+ GetQueueName ()
+ {
+ return m_queue_name.c_str();
+ }
+
+ void
+ SetQueueName (const char *name)
+ {
+ m_queue_name = name;
+ }
+
+ lldb::queue_id_t
+ GetQueueID ()
+ {
+ return m_queue_id;
+ }
+
+ void
+ SetQueueID (lldb::queue_id_t queue)
+ {
+ m_queue_id = queue;
+ }
+
+ const char *
+ GetThreadName ()
+ {
+ return m_thread_name.c_str();
+ }
+
+ uint32_t
+ GetExtendedBacktraceOriginatingIndexID ();
+
+ void
+ SetThreadName (const char *name)
+ {
+ m_thread_name = name;
+ }
+
+protected:
+ virtual lldb::StackFrameListSP
+ GetStackFrameList ();
+
+ mutable Mutex m_framelist_mutex;
+ lldb::StackFrameListSP m_framelist;
+ std::vector<lldb::addr_t> m_pcs;
+ uint32_t m_stop_id;
+ bool m_stop_id_is_valid;
+
+ uint64_t m_extended_unwind_token;
+ std::string m_queue_name;
+ std::string m_thread_name;
+ lldb::tid_t m_originating_unique_thread_id;
+ lldb::queue_id_t m_queue_id;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_HistoryThread_h_
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.cpp b/source/Plugins/Process/Utility/HistoryUnwind.cpp
new file mode 100644
index 000000000000..86665fd17b13
--- /dev/null
+++ b/source/Plugins/Process/Utility/HistoryUnwind.cpp
@@ -0,0 +1,79 @@
+//===-- HistoryUnwind.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-private.h"
+
+#include "Plugins/Process/Utility/RegisterContextHistory.h"
+#include "Plugins/Process/Utility/HistoryUnwind.h"
+
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+HistoryUnwind::HistoryUnwind (Thread &thread,
+ std::vector<lldb::addr_t> pcs,
+ uint32_t stop_id,
+ bool stop_id_is_valid) :
+ Unwind (thread),
+ m_pcs (pcs),
+ m_stop_id (stop_id),
+ m_stop_id_is_valid (stop_id_is_valid)
+{
+}
+
+HistoryUnwind::~HistoryUnwind ()
+{
+}
+
+void
+HistoryUnwind::DoClear ()
+{
+ Mutex::Locker locker(m_unwind_mutex);
+ m_pcs.clear();
+ m_stop_id_is_valid = false;
+}
+
+lldb::RegisterContextSP
+HistoryUnwind::DoCreateRegisterContextForFrame (StackFrame *frame)
+{
+ RegisterContextSP rctx;
+ if (frame)
+ {
+ addr_t pc = frame->GetFrameCodeAddress().GetLoadAddress (&frame->GetThread()->GetProcess()->GetTarget());
+ if (pc != LLDB_INVALID_ADDRESS)
+ {
+ rctx.reset (new RegisterContextHistory (*frame->GetThread().get(), frame->GetConcreteFrameIndex(),
+ frame->GetThread()->GetProcess()->GetAddressByteSize(), pc));
+ }
+ }
+ return rctx;
+}
+
+bool
+HistoryUnwind::DoGetFrameInfoAtIndex (uint32_t frame_idx, lldb::addr_t& cfa, lldb::addr_t& pc)
+{
+ Mutex::Locker (m_unwind_mutex);
+ if (frame_idx < m_pcs.size())
+ {
+ cfa = frame_idx;
+ pc = m_pcs[frame_idx];
+ return true;
+ }
+ return false;
+}
+
+uint32_t
+HistoryUnwind::DoGetFrameCount ()
+{
+ return m_pcs.size();
+}
diff --git a/source/Plugins/Process/Utility/HistoryUnwind.h b/source/Plugins/Process/Utility/HistoryUnwind.h
new file mode 100644
index 000000000000..0661b8028608
--- /dev/null
+++ b/source/Plugins/Process/Utility/HistoryUnwind.h
@@ -0,0 +1,51 @@
+//===-- HistoryUnwind.h -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_HistoryUnwind_h_
+#define liblldb_HistoryUnwind_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Unwind.h"
+
+namespace lldb_private {
+
+class HistoryUnwind : public lldb_private::Unwind
+{
+public:
+ HistoryUnwind (Thread &thread, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid);
+
+ virtual ~HistoryUnwind ();
+
+protected:
+ void
+ DoClear();
+
+ lldb::RegisterContextSP
+ DoCreateRegisterContextForFrame (StackFrame *frame);
+
+ bool
+ DoGetFrameInfoAtIndex (uint32_t frame_idx,
+ lldb::addr_t& cfa,
+ lldb::addr_t& pc);
+ uint32_t
+ DoGetFrameCount ();
+
+private:
+
+ std::vector<lldb::addr_t> m_pcs;
+ uint32_t m_stop_id;
+ bool m_stop_id_is_valid;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_HistoryUnwind_h_
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 8b22d6457ada..6d1b04f7f1a7 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -59,11 +59,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
{
const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
- const bool stop_other_threads = true;
- const bool unwind_on_error = true;
- const bool ignore_breakpoints = true;
- const bool try_all_threads = true;
- const uint32_t timeout_usec = 500000;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug (false);
+ options.SetTimeoutUsec(500000);
addr_t prot_arg, flags_arg = 0;
if (prot == eMmapProtNone)
@@ -88,19 +90,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
{
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
+ lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
ThreadPlanCallFunction *call_function_thread_plan
= new ThreadPlanCallFunction (*thread,
mmap_range.GetBaseAddress(),
clang_void_ptr_type,
- stop_other_threads,
- unwind_on_error,
- ignore_breakpoints,
- &addr,
- &length,
- &prot_arg,
- &flags_arg,
- &fd,
- &offset);
+ args,
+ options);
lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
if (call_plan_sp)
{
@@ -115,12 +111,8 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
ExecutionContext exe_ctx;
frame->CalculateExecutionContext (exe_ctx);
ExecutionResults result = process->RunThreadPlan (exe_ctx,
- call_plan_sp,
- stop_other_threads,
- try_all_threads,
- unwind_on_error,
- ignore_breakpoints,
- timeout_usec,
+ call_plan_sp,
+ options,
error_strm);
if (result == eExecutionCompleted)
{
@@ -169,56 +161,52 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
SymbolContext sc;
if (sc_list.GetContextAtIndex(0, sc))
{
- const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
- const bool stop_other_threads = true;
- const bool unwind_on_error = true;
- const bool ignore_breakpoints = true;
- const bool try_all_threads = true;
- const uint32_t timeout_usec = 500000;
+ const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = false;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug (false);
+ options.SetTimeoutUsec(500000);
- AddressRange munmap_range;
- if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
- {
- lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
+ AddressRange munmap_range;
+ if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
+ {
+ lldb::addr_t args[] = { addr, length };
+ lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
munmap_range.GetBaseAddress(),
ClangASTType(),
- stop_other_threads,
- unwind_on_error,
- ignore_breakpoints,
- &addr,
- &length));
- if (call_plan_sp)
- {
- StreamFile error_strm;
- // This plan is a utility plan, so set it to discard itself when done.
- call_plan_sp->SetIsMasterPlan (true);
- call_plan_sp->SetOkayToDiscard(true);
+ args,
+ options));
+ if (call_plan_sp)
+ {
+ StreamFile error_strm;
+ // This plan is a utility plan, so set it to discard itself when done.
+ call_plan_sp->SetIsMasterPlan (true);
+ call_plan_sp->SetOkayToDiscard(true);
- StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
- if (frame)
- {
- ExecutionContext exe_ctx;
- frame->CalculateExecutionContext (exe_ctx);
- ExecutionResults result = process->RunThreadPlan (exe_ctx,
- call_plan_sp,
- stop_other_threads,
- try_all_threads,
- unwind_on_error,
- ignore_breakpoints,
- timeout_usec,
- error_strm);
- if (result == eExecutionCompleted)
- {
- return true;
- }
- }
- }
- }
- }
- }
+ StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ if (frame)
+ {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext (exe_ctx);
+ ExecutionResults result = process->RunThreadPlan (exe_ctx,
+ call_plan_sp,
+ options,
+ error_strm);
+ if (result == eExecutionCompleted)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
- return false;
+ return false;
}
bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) {
@@ -226,11 +214,13 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t
if (thread == NULL || address == NULL)
return false;
- const bool stop_other_threads = true;
- const bool unwind_on_error = true;
- const bool ignore_breakpoints = true;
- const bool try_all_threads = true;
- const uint32_t timeout_usec = 500000;
+ EvaluateExpressionOptions options;
+ options.SetStopOthers(true);
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetTryAllThreads(true);
+ options.SetDebug (false);
+ options.SetTimeoutUsec(500000);
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
@@ -238,9 +228,8 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t
= new ThreadPlanCallFunction (*thread,
*address,
clang_void_ptr_type,
- stop_other_threads,
- unwind_on_error,
- ignore_breakpoints);
+ llvm::ArrayRef<addr_t>(),
+ options);
lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
if (call_plan_sp)
{
@@ -256,11 +245,7 @@ bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t
frame->CalculateExecutionContext (exe_ctx);
ExecutionResults result = process->RunThreadPlan (exe_ctx,
call_plan_sp,
- stop_other_threads,
- try_all_threads,
- unwind_on_error,
- ignore_breakpoints,
- timeout_usec,
+ options,
error_strm);
if (result == eExecutionCompleted)
{
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
new file mode 100644
index 000000000000..b7adb202ba49
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.cpp
@@ -0,0 +1,138 @@
+//===-- RegisterContextHistory.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Symbol/FuncUnwinders.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/DynamicLoader.h"
+
+#include "RegisterContextHistory.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextHistory::RegisterContextHistory (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size, addr_t pc_value) :
+RegisterContext (thread, concrete_frame_idx),
+ m_pc_value (pc_value)
+{
+ m_reg_set0.name = "General Purpose Registers";
+ m_reg_set0.short_name = "GPR";
+ m_reg_set0.num_registers = 1;
+ m_reg_set0.registers = new uint32_t(0);
+
+ m_pc_reg_info.name = "pc";
+ m_pc_reg_info.alt_name = "pc";
+ m_pc_reg_info.byte_offset = 0;
+ m_pc_reg_info.byte_size = address_byte_size;
+ m_pc_reg_info.encoding = eEncodingUint;
+ m_pc_reg_info.format = eFormatPointer;
+ m_pc_reg_info.invalidate_regs = NULL;
+ m_pc_reg_info.value_regs = NULL;
+ m_pc_reg_info.kinds[eRegisterKindGCC] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+ m_pc_reg_info.kinds[eRegisterKindGDB] = LLDB_INVALID_REGNUM;
+ m_pc_reg_info.kinds[eRegisterKindLLDB] = LLDB_INVALID_REGNUM;
+}
+
+RegisterContextHistory::~RegisterContextHistory ()
+{
+ delete m_reg_set0.registers;
+ delete m_pc_reg_info.invalidate_regs;
+ delete m_pc_reg_info.value_regs;
+}
+
+void
+RegisterContextHistory::InvalidateAllRegisters () {}
+
+size_t
+RegisterContextHistory::GetRegisterCount ()
+{
+ return 1;
+}
+
+const lldb_private::RegisterInfo *
+RegisterContextHistory::GetRegisterInfoAtIndex (size_t reg)
+{
+ if (reg)
+ return NULL;
+ return &m_pc_reg_info;
+}
+
+size_t
+RegisterContextHistory::GetRegisterSetCount ()
+{
+ return 1;
+}
+
+const lldb_private::RegisterSet *
+RegisterContextHistory::GetRegisterSet (size_t reg_set)
+{
+ if (reg_set)
+ return NULL;
+ return &m_reg_set0;
+}
+
+bool
+RegisterContextHistory::ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
+{
+ if (!reg_info)
+ return false;
+ uint32_t reg_number = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_number == LLDB_REGNUM_GENERIC_PC)
+ {
+ value.SetUInt(m_pc_value, reg_info->byte_size);
+ return true;
+ }
+ return false;
+}
+
+bool
+RegisterContextHistory::WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
+{
+ return false;
+}
+
+bool
+RegisterContextHistory::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
+{
+ return false;
+}
+
+bool
+RegisterContextHistory::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
+{
+ return false;
+}
+
+uint32_t
+RegisterContextHistory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num)
+{
+ if (kind == eRegisterKindGeneric && num == LLDB_REGNUM_GENERIC_PC)
+ return 0;
+ return LLDB_INVALID_REGNUM;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextHistory.h b/source/Plugins/Process/Utility/RegisterContextHistory.h
new file mode 100644
index 000000000000..58e16080b52e
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextHistory.h
@@ -0,0 +1,79 @@
+//===-- RegisterContextHistory.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_RegisterContextHistory_h_
+#define lldb_RegisterContextHistory_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Symbol/SymbolContext.h"
+
+namespace lldb_private {
+
+class RegisterContextHistory : public lldb_private::RegisterContext
+{
+public:
+ typedef std::shared_ptr<RegisterContextHistory> SharedPtr;
+
+ RegisterContextHistory (Thread &thread, uint32_t concrete_frame_idx, uint32_t address_byte_size, lldb::addr_t pc_value);
+
+ ///
+ // pure virtual functions from the base class that we must implement
+ ///
+
+ virtual
+ ~RegisterContextHistory ();
+
+ virtual void
+ InvalidateAllRegisters ();
+
+ virtual size_t
+ GetRegisterCount ();
+
+ virtual const lldb_private::RegisterInfo *
+ GetRegisterInfoAtIndex (size_t reg);
+
+ virtual size_t
+ GetRegisterSetCount ();
+
+ virtual const lldb_private::RegisterSet *
+ GetRegisterSet (size_t reg_set);
+
+ virtual bool
+ ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+
+ virtual bool
+ WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+
+ virtual bool
+ ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
+
+ virtual bool
+ WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
+
+ virtual uint32_t
+ ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
+
+private:
+ //------------------------------------------------------------------
+ // For RegisterContextLLDB only
+ //------------------------------------------------------------------
+
+ lldb_private::RegisterSet m_reg_set0; // register set 0 (PC only)
+ lldb_private::RegisterInfo m_pc_reg_info;
+
+ lldb::addr_t m_pc_value;
+
+ DISALLOW_COPY_AND_ASSIGN (RegisterContextHistory);
+};
+} // namespace lldb_private
+
+#endif // lldb_RegisterContextHistory_h_