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/State.h" 11 #include "lldb/Host/HostInfo.h" 12 #include "lldb/Host/HostNativeThreadBase.h" 13 #include "lldb/Host/windows/HostThreadWindows.h" 14 #include "lldb/Host/windows/windows.h" 15 #include "lldb/Target/RegisterContext.h" 16 #include "lldb/Utility/Log.h" 17 #include "lldb/Utility/Logging.h" 18 19 #include "ProcessWindows.h" 20 #include "ProcessWindowsLog.h" 21 #include "TargetThreadWindows.h" 22 #include "UnwindLLDB.h" 23 24 #if defined(_WIN64) 25 #include "x64/RegisterContextWindows_x64.h" 26 #else 27 #include "x86/RegisterContextWindows_x86.h" 28 #endif 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, 34 const HostThread &thread) 35 : Thread(process, thread.GetNativeThread().GetThreadId()), 36 m_host_thread(thread) {} 37 38 TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); } 39 40 void TargetThreadWindows::RefreshStateAfterStop() { 41 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle()); 42 SetState(eStateStopped); 43 GetRegisterContext()->InvalidateIfNeeded(false); 44 } 45 46 void TargetThreadWindows::WillResume(lldb::StateType resume_state) {} 47 48 void TargetThreadWindows::DidStop() {} 49 50 RegisterContextSP TargetThreadWindows::GetRegisterContext() { 51 if (!m_reg_context_sp) 52 m_reg_context_sp = CreateRegisterContextForFrameIndex(0); 53 54 return m_reg_context_sp; 55 } 56 57 RegisterContextSP 58 TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) { 59 return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex()); 60 } 61 62 RegisterContextSP 63 TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) { 64 if (!m_reg_context_sp) { 65 ArchSpec arch = HostInfo::GetArchitecture(); 66 switch (arch.GetMachine()) { 67 case llvm::Triple::x86: 68 #if defined(_WIN64) 69 // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64 70 #else 71 m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx)); 72 #endif 73 break; 74 case llvm::Triple::x86_64: 75 #if defined(_WIN64) 76 m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx)); 77 #else 78 // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug 79 // this. 80 #endif 81 default: 82 break; 83 } 84 } 85 return m_reg_context_sp; 86 } 87 88 bool TargetThreadWindows::CalculateStopInfo() { 89 SetStopInfo(m_stop_info_sp); 90 return true; 91 } 92 93 Unwind *TargetThreadWindows::GetUnwinder() { 94 // FIXME: Implement an unwinder based on the Windows unwinder exposed through 95 // DIA SDK. 96 if (m_unwinder_ap.get() == NULL) 97 m_unwinder_ap.reset(new UnwindLLDB(*this)); 98 return m_unwinder_ap.get(); 99 } 100 101 bool TargetThreadWindows::DoResume() { 102 StateType resume_state = GetTemporaryResumeState(); 103 StateType current_state = GetState(); 104 if (resume_state == current_state) 105 return true; 106 107 if (resume_state == eStateStepping) { 108 uint32_t flags_index = 109 GetRegisterContext()->ConvertRegisterKindToRegisterNumber( 110 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 111 uint64_t flags_value = 112 GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0); 113 flags_value |= 0x100; // Set the trap flag on the CPU 114 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value); 115 } 116 117 if (resume_state == eStateStepping || resume_state == eStateRunning) { 118 DWORD previous_suspend_count = 0; 119 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle(); 120 do { 121 previous_suspend_count = ::ResumeThread(thread_handle); 122 } while (previous_suspend_count > 0); 123 } 124 return true; 125 } 126