118a9135dSAdrian McCarthy //===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===//
218a9135dSAdrian McCarthy //
318a9135dSAdrian McCarthy //                     The LLVM Compiler Infrastructure
418a9135dSAdrian McCarthy //
518a9135dSAdrian McCarthy // This file is distributed under the University of Illinois Open Source
618a9135dSAdrian McCarthy // License. See LICENSE.TXT for details.
718a9135dSAdrian McCarthy //
818a9135dSAdrian McCarthy //===----------------------------------------------------------------------===//
918a9135dSAdrian McCarthy 
1018a9135dSAdrian McCarthy #include "lldb/Core/Log.h"
1118a9135dSAdrian McCarthy #include "lldb/Core/Logging.h"
1218a9135dSAdrian McCarthy #include "lldb/Core/State.h"
1318a9135dSAdrian McCarthy #include "lldb/Host/HostInfo.h"
1418a9135dSAdrian McCarthy #include "lldb/Host/HostNativeThreadBase.h"
1518a9135dSAdrian McCarthy #include "lldb/Host/windows/HostThreadWindows.h"
1618a9135dSAdrian McCarthy #include "lldb/Host/windows/windows.h"
1718a9135dSAdrian McCarthy #include "lldb/Target/RegisterContext.h"
1818a9135dSAdrian McCarthy 
1918a9135dSAdrian McCarthy #include "ProcessWindows.h"
2018a9135dSAdrian McCarthy #include "ProcessWindowsLog.h"
21*b9c1b51eSKate Stone #include "TargetThreadWindows.h"
2218a9135dSAdrian McCarthy #include "UnwindLLDB.h"
2318a9135dSAdrian McCarthy 
2418a9135dSAdrian McCarthy using namespace lldb;
2518a9135dSAdrian McCarthy using namespace lldb_private;
2618a9135dSAdrian McCarthy 
27*b9c1b51eSKate Stone TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
28*b9c1b51eSKate Stone                                          const HostThread &thread)
29*b9c1b51eSKate Stone     : Thread(process, thread.GetNativeThread().GetThreadId()),
30*b9c1b51eSKate Stone       m_host_thread(thread) {}
3118a9135dSAdrian McCarthy 
32*b9c1b51eSKate Stone TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
3318a9135dSAdrian McCarthy 
34*b9c1b51eSKate Stone void TargetThreadWindows::RefreshStateAfterStop() {
3518a9135dSAdrian McCarthy   ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
3618a9135dSAdrian McCarthy   SetState(eStateStopped);
3718a9135dSAdrian McCarthy   GetRegisterContext()->InvalidateIfNeeded(false);
3818a9135dSAdrian McCarthy }
3918a9135dSAdrian McCarthy 
40*b9c1b51eSKate Stone void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
4118a9135dSAdrian McCarthy 
42*b9c1b51eSKate Stone void TargetThreadWindows::DidStop() {}
4318a9135dSAdrian McCarthy 
44*b9c1b51eSKate Stone bool TargetThreadWindows::CalculateStopInfo() {
4518a9135dSAdrian McCarthy   SetStopInfo(m_stop_info_sp);
4618a9135dSAdrian McCarthy   return true;
4718a9135dSAdrian McCarthy }
4818a9135dSAdrian McCarthy 
49*b9c1b51eSKate Stone Unwind *TargetThreadWindows::GetUnwinder() {
50*b9c1b51eSKate Stone   // FIXME: Implement an unwinder based on the Windows unwinder exposed through
51*b9c1b51eSKate Stone   // DIA SDK.
5218a9135dSAdrian McCarthy   if (m_unwinder_ap.get() == NULL)
5318a9135dSAdrian McCarthy     m_unwinder_ap.reset(new UnwindLLDB(*this));
5418a9135dSAdrian McCarthy   return m_unwinder_ap.get();
5518a9135dSAdrian McCarthy }
5618a9135dSAdrian McCarthy 
57*b9c1b51eSKate Stone bool TargetThreadWindows::DoResume() {
5818a9135dSAdrian McCarthy   StateType resume_state = GetTemporaryResumeState();
5918a9135dSAdrian McCarthy   StateType current_state = GetState();
6018a9135dSAdrian McCarthy   if (resume_state == current_state)
6118a9135dSAdrian McCarthy     return true;
6218a9135dSAdrian McCarthy 
63*b9c1b51eSKate Stone   if (resume_state == eStateStepping) {
64*b9c1b51eSKate Stone     uint32_t flags_index =
65*b9c1b51eSKate Stone         GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
66*b9c1b51eSKate Stone             eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
67*b9c1b51eSKate Stone     uint64_t flags_value =
68*b9c1b51eSKate Stone         GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
6918a9135dSAdrian McCarthy     flags_value |= 0x100; // Set the trap flag on the CPU
7018a9135dSAdrian McCarthy     GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
7118a9135dSAdrian McCarthy   }
7218a9135dSAdrian McCarthy 
73*b9c1b51eSKate Stone   if (resume_state == eStateStepping || resume_state == eStateRunning) {
7418a9135dSAdrian McCarthy     DWORD previous_suspend_count = 0;
7518a9135dSAdrian McCarthy     HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
76*b9c1b51eSKate Stone     do {
7718a9135dSAdrian McCarthy       previous_suspend_count = ::ResumeThread(thread_handle);
7818a9135dSAdrian McCarthy     } while (previous_suspend_count > 0);
7918a9135dSAdrian McCarthy   }
8018a9135dSAdrian McCarthy   return true;
8118a9135dSAdrian McCarthy }
82