diff options
Diffstat (limited to 'source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp')
| -rw-r--r-- | source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp | 147 | 
1 files changed, 147 insertions, 0 deletions
| diff --git a/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp new file mode 100644 index 0000000000000..52b32716e674a --- /dev/null +++ b/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp @@ -0,0 +1,147 @@ +//===-- TargetThreadWindowsLive.cpp------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Log.h" +#include "lldb/Core/Logging.h" +#include "lldb/Core/State.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Host/HostNativeThreadBase.h" +#include "lldb/Host/windows/HostThreadWindows.h" +#include "lldb/Host/windows/windows.h" +#include "lldb/Target/RegisterContext.h" + +#include "TargetThreadWindowsLive.h" +#include "ProcessWindows.h" +#include "ProcessWindowsLog.h" +#include "UnwindLLDB.h" + +#if defined(_WIN64) +#include "x64/RegisterContextWindowsLive_x64.h" +#else +#include "x86/RegisterContextWindowsLive_x86.h" +#endif + +using namespace lldb; +using namespace lldb_private; + +TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread) +    : TargetThreadWindows(process, thread) +    , m_host_thread(thread) +{ +} + +TargetThreadWindowsLive::~TargetThreadWindowsLive() +{ +    DestroyThread(); +} + +void +TargetThreadWindowsLive::RefreshStateAfterStop() +{ +    ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle()); +    SetState(eStateStopped); +    GetRegisterContext()->InvalidateIfNeeded(false); +} + +void +TargetThreadWindowsLive::WillResume(lldb::StateType resume_state) +{ +} + +void +TargetThreadWindowsLive::DidStop() +{ +} + +RegisterContextSP +TargetThreadWindowsLive::GetRegisterContext() +{ +    if (!m_reg_context_sp) +        m_reg_context_sp = CreateRegisterContextForFrameIndex(0); + +    return m_reg_context_sp; +} + +RegisterContextSP +TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame) +{ +    return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex()); +} + +RegisterContextSP +TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx) +{ +    if (!m_reg_context_sp) +    { +        ArchSpec arch = HostInfo::GetArchitecture(); +        switch (arch.GetMachine()) +        { +            case llvm::Triple::x86: +#if defined(_WIN64) +                // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64 +#else +                m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx)); +#endif +                break; +            case llvm::Triple::x86_64: +#if defined(_WIN64) +                m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx)); +#else +                // LLDB is 32-bit, but the target process is 64-bit.  We probably can't debug this. +#endif +            default: +                break; +        } +    } +    return m_reg_context_sp; +} + +bool +TargetThreadWindowsLive::CalculateStopInfo() +{ +    SetStopInfo(m_stop_info_sp); +    return true; +} + +Unwind * +TargetThreadWindowsLive::GetUnwinder() +{ +    // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK. +    if (m_unwinder_ap.get() == NULL) +        m_unwinder_ap.reset(new UnwindLLDB(*this)); +    return m_unwinder_ap.get(); +} + +bool +TargetThreadWindowsLive::DoResume() +{ +    StateType resume_state = GetTemporaryResumeState(); +    StateType current_state = GetState(); +    if (resume_state == current_state) +        return true; + +    if (resume_state == eStateStepping) +    { +        uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); +        uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0); +        flags_value |= 0x100; // Set the trap flag on the CPU +        GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value); +    } + +    if (resume_state == eStateStepping || resume_state == eStateRunning) +    { +        DWORD previous_suspend_count = 0; +        HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle(); +        do +        { +            previous_suspend_count = ::ResumeThread(thread_handle); +        } while (previous_suspend_count > 0); +    } +    return true; +} | 
