1 //===-- TargetThreadWindows.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 #include "lldb/Core/Log.h"
11 #include "lldb/Core/Logging.h"
12 #include "lldb/Core/State.h"
13 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Host/HostNativeThreadBase.h"
15 #include "lldb/Host/windows/HostThreadWindows.h"
16 #include "lldb/Host/windows/windows.h"
17 #include "lldb/Target/RegisterContext.h"
18 
19 #include "ProcessWindows.h"
20 #include "ProcessWindowsLog.h"
21 #include "TargetThreadWindows.h"
22 #include "UnwindLLDB.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
28                                          const HostThread &thread)
29     : Thread(process, thread.GetNativeThread().GetThreadId()),
30       m_host_thread(thread) {}
31 
32 TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
33 
34 void TargetThreadWindows::RefreshStateAfterStop() {
35   ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
36   SetState(eStateStopped);
37   GetRegisterContext()->InvalidateIfNeeded(false);
38 }
39 
40 void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
41 
42 void TargetThreadWindows::DidStop() {}
43 
44 bool TargetThreadWindows::CalculateStopInfo() {
45   SetStopInfo(m_stop_info_sp);
46   return true;
47 }
48 
49 Unwind *TargetThreadWindows::GetUnwinder() {
50   // FIXME: Implement an unwinder based on the Windows unwinder exposed through
51   // DIA SDK.
52   if (m_unwinder_ap.get() == NULL)
53     m_unwinder_ap.reset(new UnwindLLDB(*this));
54   return m_unwinder_ap.get();
55 }
56 
57 bool TargetThreadWindows::DoResume() {
58   StateType resume_state = GetTemporaryResumeState();
59   StateType current_state = GetState();
60   if (resume_state == current_state)
61     return true;
62 
63   if (resume_state == eStateStepping) {
64     uint32_t flags_index =
65         GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
66             eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
67     uint64_t flags_value =
68         GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
69     flags_value |= 0x100; // Set the trap flag on the CPU
70     GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
71   }
72 
73   if (resume_state == eStateStepping || resume_state == eStateRunning) {
74     DWORD previous_suspend_count = 0;
75     HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
76     do {
77       previous_suspend_count = ::ResumeThread(thread_handle);
78     } while (previous_suspend_count > 0);
79   }
80   return true;
81 }
82