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