118a9135dSAdrian McCarthy //===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===// 218a9135dSAdrian McCarthy // 318a9135dSAdrian McCarthy // The LLVM Compiler Infrastructure 418a9135dSAdrian McCarthy // 518a9135dSAdrian McCarthy // This file is distributed under the University of Illinois Open Source 618a9135dSAdrian McCarthy // License. See LICENSE.TXT for details. 718a9135dSAdrian McCarthy // 818a9135dSAdrian McCarthy //===----------------------------------------------------------------------===// 918a9135dSAdrian McCarthy 1018a9135dSAdrian McCarthy #include "lldb/Core/Log.h" 1118a9135dSAdrian McCarthy #include "lldb/Core/Logging.h" 1218a9135dSAdrian McCarthy #include "lldb/Core/State.h" 1318a9135dSAdrian McCarthy #include "lldb/Host/HostInfo.h" 1418a9135dSAdrian McCarthy #include "lldb/Host/HostNativeThreadBase.h" 1518a9135dSAdrian McCarthy #include "lldb/Host/windows/HostThreadWindows.h" 1618a9135dSAdrian McCarthy #include "lldb/Host/windows/windows.h" 1718a9135dSAdrian McCarthy #include "lldb/Target/RegisterContext.h" 1818a9135dSAdrian McCarthy 1918a9135dSAdrian McCarthy #include "ProcessWindows.h" 2018a9135dSAdrian McCarthy #include "ProcessWindowsLog.h" 21b9c1b51eSKate Stone #include "TargetThreadWindows.h" 2218a9135dSAdrian McCarthy #include "UnwindLLDB.h" 2318a9135dSAdrian McCarthy 244ad5def9SAdrian McCarthy #if defined(_WIN64) 25*65abfb11SHafiz Abid Qadeer #include "x64/RegisterContextWindows_x64.h" 264ad5def9SAdrian McCarthy #else 274ad5def9SAdrian McCarthy #include "x86/RegisterContextWindows_x86.h" 284ad5def9SAdrian McCarthy #endif 294ad5def9SAdrian McCarthy 3018a9135dSAdrian McCarthy using namespace lldb; 3118a9135dSAdrian McCarthy using namespace lldb_private; 3218a9135dSAdrian McCarthy 33b9c1b51eSKate Stone TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, 34b9c1b51eSKate Stone const HostThread &thread) 35b9c1b51eSKate Stone : Thread(process, thread.GetNativeThread().GetThreadId()), 36b9c1b51eSKate Stone m_host_thread(thread) {} 3718a9135dSAdrian McCarthy 38b9c1b51eSKate Stone TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); } 3918a9135dSAdrian McCarthy 40b9c1b51eSKate Stone void TargetThreadWindows::RefreshStateAfterStop() { 4118a9135dSAdrian McCarthy ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle()); 4218a9135dSAdrian McCarthy SetState(eStateStopped); 4318a9135dSAdrian McCarthy GetRegisterContext()->InvalidateIfNeeded(false); 4418a9135dSAdrian McCarthy } 4518a9135dSAdrian McCarthy 46b9c1b51eSKate Stone void TargetThreadWindows::WillResume(lldb::StateType resume_state) {} 4718a9135dSAdrian McCarthy 48b9c1b51eSKate Stone void TargetThreadWindows::DidStop() {} 4918a9135dSAdrian McCarthy 504ad5def9SAdrian McCarthy RegisterContextSP TargetThreadWindows::GetRegisterContext() { 514ad5def9SAdrian McCarthy if (!m_reg_context_sp) 524ad5def9SAdrian McCarthy m_reg_context_sp = CreateRegisterContextForFrameIndex(0); 534ad5def9SAdrian McCarthy 544ad5def9SAdrian McCarthy return m_reg_context_sp; 554ad5def9SAdrian McCarthy } 564ad5def9SAdrian McCarthy 574ad5def9SAdrian McCarthy RegisterContextSP 584ad5def9SAdrian McCarthy TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) { 594ad5def9SAdrian McCarthy return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex()); 604ad5def9SAdrian McCarthy } 614ad5def9SAdrian McCarthy 624ad5def9SAdrian McCarthy RegisterContextSP 634ad5def9SAdrian McCarthy TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) { 644ad5def9SAdrian McCarthy if (!m_reg_context_sp) { 654ad5def9SAdrian McCarthy ArchSpec arch = HostInfo::GetArchitecture(); 664ad5def9SAdrian McCarthy switch (arch.GetMachine()) { 674ad5def9SAdrian McCarthy case llvm::Triple::x86: 684ad5def9SAdrian McCarthy #if defined(_WIN64) 694ad5def9SAdrian McCarthy // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64 704ad5def9SAdrian McCarthy #else 714ad5def9SAdrian McCarthy m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx)); 724ad5def9SAdrian McCarthy #endif 734ad5def9SAdrian McCarthy break; 744ad5def9SAdrian McCarthy case llvm::Triple::x86_64: 754ad5def9SAdrian McCarthy #if defined(_WIN64) 764ad5def9SAdrian McCarthy m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx)); 774ad5def9SAdrian McCarthy #else 784ad5def9SAdrian McCarthy // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug 794ad5def9SAdrian McCarthy // this. 804ad5def9SAdrian McCarthy #endif 814ad5def9SAdrian McCarthy default: 824ad5def9SAdrian McCarthy break; 834ad5def9SAdrian McCarthy } 844ad5def9SAdrian McCarthy } 854ad5def9SAdrian McCarthy return m_reg_context_sp; 864ad5def9SAdrian McCarthy } 874ad5def9SAdrian McCarthy 88b9c1b51eSKate Stone bool TargetThreadWindows::CalculateStopInfo() { 8918a9135dSAdrian McCarthy SetStopInfo(m_stop_info_sp); 9018a9135dSAdrian McCarthy return true; 9118a9135dSAdrian McCarthy } 9218a9135dSAdrian McCarthy 93b9c1b51eSKate Stone Unwind *TargetThreadWindows::GetUnwinder() { 94b9c1b51eSKate Stone // FIXME: Implement an unwinder based on the Windows unwinder exposed through 95b9c1b51eSKate Stone // DIA SDK. 9618a9135dSAdrian McCarthy if (m_unwinder_ap.get() == NULL) 9718a9135dSAdrian McCarthy m_unwinder_ap.reset(new UnwindLLDB(*this)); 9818a9135dSAdrian McCarthy return m_unwinder_ap.get(); 9918a9135dSAdrian McCarthy } 10018a9135dSAdrian McCarthy 101b9c1b51eSKate Stone bool TargetThreadWindows::DoResume() { 10218a9135dSAdrian McCarthy StateType resume_state = GetTemporaryResumeState(); 10318a9135dSAdrian McCarthy StateType current_state = GetState(); 10418a9135dSAdrian McCarthy if (resume_state == current_state) 10518a9135dSAdrian McCarthy return true; 10618a9135dSAdrian McCarthy 107b9c1b51eSKate Stone if (resume_state == eStateStepping) { 108b9c1b51eSKate Stone uint32_t flags_index = 109b9c1b51eSKate Stone GetRegisterContext()->ConvertRegisterKindToRegisterNumber( 110b9c1b51eSKate Stone eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 111b9c1b51eSKate Stone uint64_t flags_value = 112b9c1b51eSKate Stone GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0); 11318a9135dSAdrian McCarthy flags_value |= 0x100; // Set the trap flag on the CPU 11418a9135dSAdrian McCarthy GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value); 11518a9135dSAdrian McCarthy } 11618a9135dSAdrian McCarthy 117b9c1b51eSKate Stone if (resume_state == eStateStepping || resume_state == eStateRunning) { 11818a9135dSAdrian McCarthy DWORD previous_suspend_count = 0; 11918a9135dSAdrian McCarthy HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle(); 120b9c1b51eSKate Stone do { 12118a9135dSAdrian McCarthy previous_suspend_count = ::ResumeThread(thread_handle); 12218a9135dSAdrian McCarthy } while (previous_suspend_count > 0); 12318a9135dSAdrian McCarthy } 12418a9135dSAdrian McCarthy return true; 12518a9135dSAdrian McCarthy } 126