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