summaryrefslogtreecommitdiffstats
path: root/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp')
-rw-r--r--source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
new file mode 100644
index 0000000..52b3271
--- /dev/null
+++ b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp
@@ -0,0 +1,147 @@
+//===-- TargetThreadWindowsLive.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/Core/Log.h"
+#include "lldb/Core/Logging.h"
+#include "lldb/Core/State.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/HostNativeThreadBase.h"
+#include "lldb/Host/windows/HostThreadWindows.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/Target/RegisterContext.h"
+
+#include "TargetThreadWindowsLive.h"
+#include "ProcessWindows.h"
+#include "ProcessWindowsLog.h"
+#include "UnwindLLDB.h"
+
+#if defined(_WIN64)
+#include "x64/RegisterContextWindowsLive_x64.h"
+#else
+#include "x86/RegisterContextWindowsLive_x86.h"
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread)
+ : TargetThreadWindows(process, thread)
+ , m_host_thread(thread)
+{
+}
+
+TargetThreadWindowsLive::~TargetThreadWindowsLive()
+{
+ DestroyThread();
+}
+
+void
+TargetThreadWindowsLive::RefreshStateAfterStop()
+{
+ ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
+ SetState(eStateStopped);
+ GetRegisterContext()->InvalidateIfNeeded(false);
+}
+
+void
+TargetThreadWindowsLive::WillResume(lldb::StateType resume_state)
+{
+}
+
+void
+TargetThreadWindowsLive::DidStop()
+{
+}
+
+RegisterContextSP
+TargetThreadWindowsLive::GetRegisterContext()
+{
+ if (!m_reg_context_sp)
+ m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
+
+ return m_reg_context_sp;
+}
+
+RegisterContextSP
+TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame)
+{
+ return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
+}
+
+RegisterContextSP
+TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx)
+{
+ if (!m_reg_context_sp)
+ {
+ ArchSpec arch = HostInfo::GetArchitecture();
+ switch (arch.GetMachine())
+ {
+ case llvm::Triple::x86:
+#if defined(_WIN64)
+ // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
+#else
+ m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
+#endif
+ break;
+ case llvm::Triple::x86_64:
+#if defined(_WIN64)
+ m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
+#else
+ // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
+#endif
+ default:
+ break;
+ }
+ }
+ return m_reg_context_sp;
+}
+
+bool
+TargetThreadWindowsLive::CalculateStopInfo()
+{
+ SetStopInfo(m_stop_info_sp);
+ return true;
+}
+
+Unwind *
+TargetThreadWindowsLive::GetUnwinder()
+{
+ // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
+ if (m_unwinder_ap.get() == NULL)
+ m_unwinder_ap.reset(new UnwindLLDB(*this));
+ return m_unwinder_ap.get();
+}
+
+bool
+TargetThreadWindowsLive::DoResume()
+{
+ StateType resume_state = GetTemporaryResumeState();
+ StateType current_state = GetState();
+ if (resume_state == current_state)
+ return true;
+
+ if (resume_state == eStateStepping)
+ {
+ uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
+ flags_value |= 0x100; // Set the trap flag on the CPU
+ GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
+ }
+
+ if (resume_state == eStateStepping || resume_state == eStateRunning)
+ {
+ DWORD previous_suspend_count = 0;
+ HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
+ do
+ {
+ previous_suspend_count = ::ResumeThread(thread_handle);
+ } while (previous_suspend_count > 0);
+ }
+ return true;
+}
OpenPOWER on IntegriCloud