1*18a9135dSAdrian McCarthy //===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===//
2*18a9135dSAdrian McCarthy //
3*18a9135dSAdrian McCarthy //                     The LLVM Compiler Infrastructure
4*18a9135dSAdrian McCarthy //
5*18a9135dSAdrian McCarthy // This file is distributed under the University of Illinois Open Source
6*18a9135dSAdrian McCarthy // License. See LICENSE.TXT for details.
7*18a9135dSAdrian McCarthy //
8*18a9135dSAdrian McCarthy //===----------------------------------------------------------------------===//
9*18a9135dSAdrian McCarthy 
10*18a9135dSAdrian McCarthy #include "lldb/Core/Log.h"
11*18a9135dSAdrian McCarthy #include "lldb/Core/Logging.h"
12*18a9135dSAdrian McCarthy #include "lldb/Core/State.h"
13*18a9135dSAdrian McCarthy #include "lldb/Host/HostInfo.h"
14*18a9135dSAdrian McCarthy #include "lldb/Host/HostNativeThreadBase.h"
15*18a9135dSAdrian McCarthy #include "lldb/Host/windows/HostThreadWindows.h"
16*18a9135dSAdrian McCarthy #include "lldb/Host/windows/windows.h"
17*18a9135dSAdrian McCarthy #include "lldb/Target/RegisterContext.h"
18*18a9135dSAdrian McCarthy 
19*18a9135dSAdrian McCarthy #include "TargetThreadWindows.h"
20*18a9135dSAdrian McCarthy #include "ProcessWindows.h"
21*18a9135dSAdrian McCarthy #include "ProcessWindowsLog.h"
22*18a9135dSAdrian McCarthy #include "UnwindLLDB.h"
23*18a9135dSAdrian McCarthy 
24*18a9135dSAdrian McCarthy using namespace lldb;
25*18a9135dSAdrian McCarthy using namespace lldb_private;
26*18a9135dSAdrian McCarthy 
27*18a9135dSAdrian McCarthy TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
28*18a9135dSAdrian McCarthy     : Thread(process, thread.GetNativeThread().GetThreadId())
29*18a9135dSAdrian McCarthy     , m_host_thread(thread)
30*18a9135dSAdrian McCarthy {
31*18a9135dSAdrian McCarthy }
32*18a9135dSAdrian McCarthy 
33*18a9135dSAdrian McCarthy TargetThreadWindows::~TargetThreadWindows()
34*18a9135dSAdrian McCarthy {
35*18a9135dSAdrian McCarthy     DestroyThread();
36*18a9135dSAdrian McCarthy }
37*18a9135dSAdrian McCarthy 
38*18a9135dSAdrian McCarthy void
39*18a9135dSAdrian McCarthy TargetThreadWindows::RefreshStateAfterStop()
40*18a9135dSAdrian McCarthy {
41*18a9135dSAdrian McCarthy     ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
42*18a9135dSAdrian McCarthy     SetState(eStateStopped);
43*18a9135dSAdrian McCarthy     GetRegisterContext()->InvalidateIfNeeded(false);
44*18a9135dSAdrian McCarthy }
45*18a9135dSAdrian McCarthy 
46*18a9135dSAdrian McCarthy void
47*18a9135dSAdrian McCarthy TargetThreadWindows::WillResume(lldb::StateType resume_state)
48*18a9135dSAdrian McCarthy {
49*18a9135dSAdrian McCarthy }
50*18a9135dSAdrian McCarthy 
51*18a9135dSAdrian McCarthy void
52*18a9135dSAdrian McCarthy TargetThreadWindows::DidStop()
53*18a9135dSAdrian McCarthy {
54*18a9135dSAdrian McCarthy }
55*18a9135dSAdrian McCarthy 
56*18a9135dSAdrian McCarthy bool
57*18a9135dSAdrian McCarthy TargetThreadWindows::CalculateStopInfo()
58*18a9135dSAdrian McCarthy {
59*18a9135dSAdrian McCarthy     SetStopInfo(m_stop_info_sp);
60*18a9135dSAdrian McCarthy     return true;
61*18a9135dSAdrian McCarthy }
62*18a9135dSAdrian McCarthy 
63*18a9135dSAdrian McCarthy Unwind *
64*18a9135dSAdrian McCarthy TargetThreadWindows::GetUnwinder()
65*18a9135dSAdrian McCarthy {
66*18a9135dSAdrian McCarthy     // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
67*18a9135dSAdrian McCarthy     if (m_unwinder_ap.get() == NULL)
68*18a9135dSAdrian McCarthy         m_unwinder_ap.reset(new UnwindLLDB(*this));
69*18a9135dSAdrian McCarthy     return m_unwinder_ap.get();
70*18a9135dSAdrian McCarthy }
71*18a9135dSAdrian McCarthy 
72*18a9135dSAdrian McCarthy bool
73*18a9135dSAdrian McCarthy TargetThreadWindows::DoResume()
74*18a9135dSAdrian McCarthy {
75*18a9135dSAdrian McCarthy     StateType resume_state = GetTemporaryResumeState();
76*18a9135dSAdrian McCarthy     StateType current_state = GetState();
77*18a9135dSAdrian McCarthy     if (resume_state == current_state)
78*18a9135dSAdrian McCarthy         return true;
79*18a9135dSAdrian McCarthy 
80*18a9135dSAdrian McCarthy     if (resume_state == eStateStepping)
81*18a9135dSAdrian McCarthy     {
82*18a9135dSAdrian McCarthy         uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
83*18a9135dSAdrian McCarthy         uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
84*18a9135dSAdrian McCarthy         flags_value |= 0x100; // Set the trap flag on the CPU
85*18a9135dSAdrian McCarthy         GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
86*18a9135dSAdrian McCarthy     }
87*18a9135dSAdrian McCarthy 
88*18a9135dSAdrian McCarthy     if (resume_state == eStateStepping || resume_state == eStateRunning)
89*18a9135dSAdrian McCarthy     {
90*18a9135dSAdrian McCarthy         DWORD previous_suspend_count = 0;
91*18a9135dSAdrian McCarthy         HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
92*18a9135dSAdrian McCarthy         do
93*18a9135dSAdrian McCarthy         {
94*18a9135dSAdrian McCarthy             previous_suspend_count = ::ResumeThread(thread_handle);
95*18a9135dSAdrian McCarthy         } while (previous_suspend_count > 0);
96*18a9135dSAdrian McCarthy     }
97*18a9135dSAdrian McCarthy     return true;
98*18a9135dSAdrian McCarthy }
99