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