148 lines
4.0 KiB
C++
148 lines
4.0 KiB
C++
//===-- 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;
|
|
}
|