forked from OSchip/llvm-project
Refactor LLDB's Windows process plugin (NFC)
The Windows process plugin was broken up into multiple pieces a while back in order to share code between debugging live processes and minidumps (postmortem) debugging. The minidump portion was replaced by a cross-platform solution. This left the plugin split into a formerly "common" base classes and the derived classes for live debugging. This extra layer made the code harder to understand and work with. This patch simplifies these class hierarchies by rolling the live debugging concrete classes up to the base classes. Last week I posted my intent to make this change to lldb-dev, and I didn't hear any objections. This involved moving code and changing references to classes like ProcessWindowsLive to ProcessWindows. It still builds for both 32- and 64-bit, and the tests still pass on 32-bit. (Tests on 64-bit weren't passing before this refactor for unrelated reasons.) llvm-svn: 287770
This commit is contained in:
parent
5abf14ba51
commit
4ad5def9b0
|
@ -90,7 +90,6 @@ set( LLDB_USED_LIBS
|
|||
# Windows-only libraries
|
||||
if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
|
||||
list(APPEND LLDB_USED_LIBS
|
||||
lldbPluginProcessWindows
|
||||
lldbPluginProcessWindowsCommon
|
||||
Ws2_32
|
||||
Rpcrt4
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "Plugins/Process/Windows/Live/ProcessWindowsLive.h"
|
||||
#include "Plugins/Process/Windows/Common/ProcessWindows.h"
|
||||
#include "lldb/Host/windows/windows.h"
|
||||
#endif
|
||||
|
||||
|
@ -333,7 +333,7 @@ void SystemInitializerFull::Initialize() {
|
|||
OCamlLanguage::Initialize();
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
ProcessWindowsLive::Initialize();
|
||||
ProcessWindows::Initialize();
|
||||
#endif
|
||||
#if defined(__FreeBSD__)
|
||||
ProcessFreeBSD::Initialize();
|
||||
|
|
|
@ -7,7 +7,6 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
|||
elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
add_subdirectory(POSIX)
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
add_subdirectory(Windows/Live)
|
||||
add_subdirectory(Windows/Common)
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
add_subdirectory(MacOSX-Kernel)
|
||||
|
|
|
@ -2,9 +2,11 @@ include_directories(.)
|
|||
include_directories(../../Utility)
|
||||
|
||||
set(PROC_WINDOWS_COMMON_SOURCES
|
||||
RegisterContextWindows.cpp
|
||||
DebuggerThread.cpp
|
||||
LocalDebugDelegate.cpp
|
||||
ProcessWindows.cpp
|
||||
ProcessWindowsLog.cpp
|
||||
RegisterContextWindows.cpp
|
||||
TargetThreadWindows.cpp
|
||||
)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//===-- DebuggerThread.DebuggerThread --------------------------------------*-
|
||||
//C++ -*-===//
|
||||
// C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
|
@ -8,7 +8,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "LocalDebugDelegate.h"
|
||||
#include "ProcessWindowsLive.h"
|
||||
#include "ProcessWindows.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
@ -17,57 +17,57 @@ LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
|
|||
: m_process(process) {}
|
||||
|
||||
void LocalDebugDelegate::OnExitProcess(uint32_t exit_code) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnExitProcess(exit_code);
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnDebuggerConnected(image_base);
|
||||
}
|
||||
|
||||
ExceptionResult
|
||||
LocalDebugDelegate::OnDebugException(bool first_chance,
|
||||
const ExceptionRecord &record) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
return process->OnDebugException(first_chance, record);
|
||||
else
|
||||
return ExceptionResult::MaskException;
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnCreateThread(const HostThread &thread) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnCreateThread(thread);
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id,
|
||||
uint32_t exit_code) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnExitThread(thread_id, exit_code);
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb::addr_t module_addr) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnLoadDll(module_spec, module_addr);
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnUnloadDll(module_addr);
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnDebugString(const std::string &string) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnDebugString(string);
|
||||
}
|
||||
|
||||
void LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type) {
|
||||
if (ProcessWindowsLiveSP process = GetProcessPointer())
|
||||
if (ProcessWindowsSP process = GetProcessPointer())
|
||||
process->OnDebuggerError(error, type);
|
||||
}
|
||||
|
||||
ProcessWindowsLiveSP LocalDebugDelegate::GetProcessPointer() {
|
||||
ProcessWindowsSP LocalDebugDelegate::GetProcessPointer() {
|
||||
ProcessSP process = m_process.lock();
|
||||
return std::static_pointer_cast<ProcessWindowsLive>(process);
|
||||
return std::static_pointer_cast<ProcessWindows>(process);
|
||||
}
|
|
@ -18,19 +18,17 @@
|
|||
|
||||
namespace lldb_private {
|
||||
|
||||
class ProcessWindowsLive;
|
||||
typedef std::shared_ptr<ProcessWindowsLive> ProcessWindowsLiveSP;
|
||||
class ProcessWindows;
|
||||
typedef std::shared_ptr<ProcessWindows> ProcessWindowsSP;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// LocalDebugDelegate
|
||||
//
|
||||
// LocalDebugDelegate creates a connection between a ProcessWindowsLive and the
|
||||
// debug driver. This serves to decouple ProcessWindowsLive from the debug
|
||||
// driver.
|
||||
// It would be possible to get a similar decoupling by just having
|
||||
// ProcessWindowsLive implement this interface directly. There are two reasons
|
||||
// why
|
||||
// we don't do this:
|
||||
// LocalDebugDelegate creates a connection between a ProcessWindows and the
|
||||
// debug driver. This serves to decouple ProcessWindows from the debug
|
||||
// driver. It would be possible to get a similar decoupling by just having
|
||||
// ProcessWindows implement this interface directly. There are two reasons
|
||||
// why we don't do this:
|
||||
//
|
||||
// 1) In the future when we add support for local debugging through LLGS, and we
|
||||
// go through the Native*Protocol interface, it is likely we will need the
|
||||
|
@ -60,7 +58,7 @@ public:
|
|||
void OnDebuggerError(const Error &error, uint32_t type) override;
|
||||
|
||||
private:
|
||||
ProcessWindowsLiveSP GetProcessPointer();
|
||||
ProcessWindowsSP GetProcessPointer();
|
||||
|
||||
lldb::ProcessWP m_process;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -15,10 +15,32 @@
|
|||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
#include "llvm/Support/Mutex.h"
|
||||
|
||||
#include "IDebugDelegate.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ProcessWindows : public lldb_private::Process {
|
||||
class HostProcess;
|
||||
class ProcessWindowsData;
|
||||
|
||||
class ProcessWindows : public Process, public IDebugDelegate {
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Static functions.
|
||||
//------------------------------------------------------------------
|
||||
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
|
||||
lldb::ListenerSP listener_sp,
|
||||
const FileSpec *);
|
||||
|
||||
static void Initialize();
|
||||
|
||||
static void Terminate();
|
||||
|
||||
static lldb_private::ConstString GetPluginNameStatic();
|
||||
|
||||
static const char *GetPluginDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and destructors
|
||||
//------------------------------------------------------------------
|
||||
|
@ -26,22 +48,71 @@ public:
|
|||
|
||||
~ProcessWindows();
|
||||
|
||||
size_t GetSTDOUT(char *buf, size_t buf_size,
|
||||
lldb_private::Error &error) override;
|
||||
size_t GetSTDERR(char *buf, size_t buf_size,
|
||||
lldb_private::Error &error) override;
|
||||
size_t PutSTDIN(const char *buf, size_t buf_size,
|
||||
lldb_private::Error &error) override;
|
||||
size_t GetSTDOUT(char *buf, size_t buf_size, Error &error) override;
|
||||
size_t GetSTDERR(char *buf, size_t buf_size, Error &error) override;
|
||||
size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) override;
|
||||
|
||||
// lldb_private::Process overrides
|
||||
ConstString GetPluginName() override;
|
||||
uint32_t GetPluginVersion() override;
|
||||
|
||||
Error EnableBreakpointSite(BreakpointSite *bp_site) override;
|
||||
Error DisableBreakpointSite(BreakpointSite *bp_site) override;
|
||||
|
||||
Error DoDetach(bool keep_stopped) override;
|
||||
Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
|
||||
Error DoAttachToProcessWithID(
|
||||
lldb::pid_t pid,
|
||||
const lldb_private::ProcessAttachInfo &attach_info) override;
|
||||
Error DoResume() override;
|
||||
Error DoDestroy() override;
|
||||
Error DoHalt(bool &caused_stop) override;
|
||||
|
||||
void DidLaunch() override;
|
||||
void DidAttach(lldb_private::ArchSpec &arch_spec) override;
|
||||
|
||||
void RefreshStateAfterStop() override;
|
||||
|
||||
bool CanDebug(lldb::TargetSP target_sp,
|
||||
bool plugin_specified_by_name) override;
|
||||
bool DestroyRequiresHalt() override { return false; }
|
||||
bool UpdateThreadList(ThreadList &old_thread_list,
|
||||
ThreadList &new_thread_list) override;
|
||||
bool IsAlive() override;
|
||||
|
||||
size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
|
||||
Error &error) override;
|
||||
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
|
||||
Error &error) override;
|
||||
Error GetMemoryRegionInfo(lldb::addr_t vm_addr,
|
||||
MemoryRegionInfo &info) override;
|
||||
|
||||
lldb::addr_t GetImageInfoAddress() override;
|
||||
|
||||
protected:
|
||||
// IDebugDelegate overrides.
|
||||
void OnExitProcess(uint32_t exit_code) override;
|
||||
void OnDebuggerConnected(lldb::addr_t image_base) override;
|
||||
ExceptionResult OnDebugException(bool first_chance,
|
||||
const ExceptionRecord &record) override;
|
||||
void OnCreateThread(const HostThread &thread) override;
|
||||
void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
|
||||
void OnLoadDll(const ModuleSpec &module_spec,
|
||||
lldb::addr_t module_addr) override;
|
||||
void OnUnloadDll(lldb::addr_t module_addr) override;
|
||||
void OnDebugString(const std::string &string) override;
|
||||
void OnDebuggerError(const Error &error, uint32_t type) override;
|
||||
|
||||
private:
|
||||
Error WaitForDebuggerConnection(DebuggerThreadSP debugger,
|
||||
HostProcess &process);
|
||||
|
||||
// These decode the page protection bits.
|
||||
static bool IsPageReadable(uint32_t protect);
|
||||
|
||||
static bool IsPageWritable(uint32_t protect);
|
||||
|
||||
static bool IsPageExecutable(uint32_t protect);
|
||||
|
||||
llvm::sys::Mutex m_mutex;
|
||||
std::unique_ptr<ProcessWindowsData> m_session_data;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
#include "TargetThreadWindows.h"
|
||||
#include "UnwindLLDB.h"
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include "x86/RegisterContextWindows_x64.h"
|
||||
#else
|
||||
#include "x86/RegisterContextWindows_x86.h"
|
||||
#endif
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
@ -41,6 +47,44 @@ void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
|
|||
|
||||
void TargetThreadWindows::DidStop() {}
|
||||
|
||||
RegisterContextSP TargetThreadWindows::GetRegisterContext() {
|
||||
if (!m_reg_context_sp)
|
||||
m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
|
||||
|
||||
return m_reg_context_sp;
|
||||
}
|
||||
|
||||
RegisterContextSP
|
||||
TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
|
||||
return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
|
||||
}
|
||||
|
||||
RegisterContextSP
|
||||
TargetThreadWindows::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 RegisterContextWindows_x86(*this, idx));
|
||||
#endif
|
||||
break;
|
||||
case llvm::Triple::x86_64:
|
||||
#if defined(_WIN64)
|
||||
m_reg_context_sp.reset(new RegisterContextWindows_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 TargetThreadWindows::CalculateStopInfo() {
|
||||
SetStopInfo(m_stop_info_sp);
|
||||
return true;
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
#include "RegisterContextWindows.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class ProcessWindows;
|
||||
class HostThread;
|
||||
|
@ -29,6 +31,9 @@ public:
|
|||
void RefreshStateAfterStop() override;
|
||||
void WillResume(lldb::StateType resume_state) override;
|
||||
void DidStop() override;
|
||||
lldb::RegisterContextSP GetRegisterContext() override;
|
||||
lldb::RegisterContextSP
|
||||
CreateRegisterContextForFrame(StackFrame *frame) override;
|
||||
bool CalculateStopInfo() override;
|
||||
Unwind *GetUnwinder() override;
|
||||
|
||||
|
@ -37,6 +42,8 @@ public:
|
|||
HostThread GetHostThread() const { return m_host_thread; }
|
||||
|
||||
private:
|
||||
lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
|
||||
|
||||
HostThread m_host_thread;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "ProcessWindowsLog.h"
|
||||
#include "RegisterContextWindows_x86.h"
|
||||
#include "RegisterContext_x86.h"
|
||||
#include "TargetThreadWindows.h"
|
||||
#include "lldb-x86-register-enums.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
@ -208,6 +209,80 @@ bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info,
|
||||
const RegisterValue ®_value) {
|
||||
// Since we cannot only write a single register value to the inferior, we need
|
||||
// to make sure
|
||||
// our cached copy of the register values are fresh. Otherwise when writing
|
||||
// EAX, for example,
|
||||
// we may also overwrite some other register with a stale value.
|
||||
if (!CacheAllRegisterValues())
|
||||
return false;
|
||||
|
||||
uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
|
||||
switch (reg) {
|
||||
case lldb_eax_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Eax = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_ebx_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Ebx = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_ecx_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Ecx = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_edx_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Edx = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_edi_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Edi = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_esi_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Esi = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_ebp_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Ebp = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_esp_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Esp = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_eip_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Eip = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_eflags_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.EFlags = reg_value.GetAsUInt32();
|
||||
break;
|
||||
default:
|
||||
WINWARN_IFALL(WINDOWS_LOG_REGISTERS,
|
||||
"Write value 0x%x to unknown register %u",
|
||||
reg_value.GetAsUInt32(), reg);
|
||||
}
|
||||
|
||||
// Physically update the registers in the target process.
|
||||
TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
|
||||
return ::SetThreadContext(
|
||||
wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
|
||||
}
|
||||
|
||||
bool RegisterContextWindows_x86::ReadRegisterHelper(
|
||||
DWORD flags_required, const char *reg_name, DWORD value,
|
||||
RegisterValue ®_value) const {
|
||||
|
|
|
@ -40,6 +40,9 @@ public:
|
|||
bool ReadRegister(const RegisterInfo *reg_info,
|
||||
RegisterValue ®_value) override;
|
||||
|
||||
bool WriteRegister(const RegisterInfo *reg_info,
|
||||
const RegisterValue ®_value) override;
|
||||
|
||||
private:
|
||||
bool ReadRegisterHelper(DWORD flags_required, const char *reg_name,
|
||||
DWORD value, RegisterValue ®_value) const;
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
include_directories(.)
|
||||
include_directories(../../Utility)
|
||||
include_directories(../Common)
|
||||
|
||||
set(PROC_WINDOWS_SOURCES
|
||||
DebuggerThread.cpp
|
||||
LocalDebugDelegate.cpp
|
||||
ProcessWindowsLive.cpp
|
||||
TargetThreadWindowsLive.cpp
|
||||
)
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES}
|
||||
x86/RegisterContextWindowsLive_x86.cpp
|
||||
)
|
||||
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES}
|
||||
x64/RegisterContextWindowsLive_x64.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_lldb_library(lldbPluginProcessWindows
|
||||
${PROC_WINDOWS_SOURCES}
|
||||
)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,129 +0,0 @@
|
|||
//===-- ProcessWindowsLive.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
|
||||
#define liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
|
||||
|
||||
// C Includes
|
||||
|
||||
// C++ Includes
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "ForwardDecl.h"
|
||||
#include "IDebugDelegate.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Host/HostThread.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
#include "llvm/Support/Mutex.h"
|
||||
|
||||
#include "Plugins/Process/Windows/Common/ProcessWindows.h"
|
||||
|
||||
class ProcessMonitor;
|
||||
|
||||
namespace lldb_private {
|
||||
class HostProcess;
|
||||
class ProcessWindowsData;
|
||||
|
||||
class ProcessWindowsLive : public lldb_private::ProcessWindows,
|
||||
public lldb_private::IDebugDelegate {
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Static functions.
|
||||
//------------------------------------------------------------------
|
||||
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
|
||||
lldb::ListenerSP listener_sp,
|
||||
const lldb_private::FileSpec *);
|
||||
|
||||
static void Initialize();
|
||||
|
||||
static void Terminate();
|
||||
|
||||
static lldb_private::ConstString GetPluginNameStatic();
|
||||
|
||||
static const char *GetPluginDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and destructors
|
||||
//------------------------------------------------------------------
|
||||
ProcessWindowsLive(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
|
||||
|
||||
~ProcessWindowsLive();
|
||||
|
||||
// lldb_private::Process overrides
|
||||
lldb_private::ConstString GetPluginName() override;
|
||||
uint32_t GetPluginVersion() override;
|
||||
|
||||
lldb_private::Error
|
||||
EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
|
||||
lldb_private::Error
|
||||
DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
|
||||
|
||||
lldb_private::Error DoDetach(bool keep_stopped) override;
|
||||
lldb_private::Error
|
||||
DoLaunch(lldb_private::Module *exe_module,
|
||||
lldb_private::ProcessLaunchInfo &launch_info) override;
|
||||
lldb_private::Error DoAttachToProcessWithID(
|
||||
lldb::pid_t pid,
|
||||
const lldb_private::ProcessAttachInfo &attach_info) override;
|
||||
lldb_private::Error DoResume() override;
|
||||
lldb_private::Error DoDestroy() override;
|
||||
lldb_private::Error DoHalt(bool &caused_stop) override;
|
||||
|
||||
void DidLaunch() override;
|
||||
void DidAttach(lldb_private::ArchSpec &arch_spec) override;
|
||||
|
||||
void RefreshStateAfterStop() override;
|
||||
|
||||
bool CanDebug(lldb::TargetSP target_sp,
|
||||
bool plugin_specified_by_name) override;
|
||||
bool DestroyRequiresHalt() override { return false; }
|
||||
bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
|
||||
lldb_private::ThreadList &new_thread_list) override;
|
||||
bool IsAlive() override;
|
||||
|
||||
size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
|
||||
lldb_private::Error &error) override;
|
||||
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
|
||||
lldb_private::Error &error) override;
|
||||
lldb_private::Error
|
||||
GetMemoryRegionInfo(lldb::addr_t vm_addr,
|
||||
lldb_private::MemoryRegionInfo &info) override;
|
||||
|
||||
// IDebugDelegate overrides.
|
||||
void OnExitProcess(uint32_t exit_code) override;
|
||||
void OnDebuggerConnected(lldb::addr_t image_base) override;
|
||||
ExceptionResult
|
||||
OnDebugException(bool first_chance,
|
||||
const lldb_private::ExceptionRecord &record) override;
|
||||
void OnCreateThread(const lldb_private::HostThread &thread) override;
|
||||
void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
|
||||
void OnLoadDll(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb::addr_t module_addr) override;
|
||||
void OnUnloadDll(lldb::addr_t module_addr) override;
|
||||
void OnDebugString(const std::string &string) override;
|
||||
void OnDebuggerError(const lldb_private::Error &error,
|
||||
uint32_t type) override;
|
||||
|
||||
private:
|
||||
lldb_private::Error
|
||||
WaitForDebuggerConnection(lldb_private::DebuggerThreadSP debugger,
|
||||
lldb_private::HostProcess &process);
|
||||
|
||||
llvm::sys::Mutex m_mutex;
|
||||
|
||||
// Data for the active debugging session.
|
||||
std::unique_ptr<lldb_private::ProcessWindowsData> m_session_data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_
|
|
@ -1,124 +0,0 @@
|
|||
//===-- 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 "ProcessWindows.h"
|
||||
#include "ProcessWindowsLog.h"
|
||||
#include "TargetThreadWindowsLive.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;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
//===-- TargetThreadWindowsLive.h -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
|
||||
#define liblldb_Plugins_Process_Windows_TargetThreadWindowsLive_H_
|
||||
|
||||
#include "lldb/Host/HostThread.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
#include "Plugins/Process/Windows/Common/TargetThreadWindows.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class ProcessWindows;
|
||||
class HostThread;
|
||||
class StackFrame;
|
||||
|
||||
class TargetThreadWindowsLive : public lldb_private::TargetThreadWindows {
|
||||
public:
|
||||
TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread);
|
||||
virtual ~TargetThreadWindowsLive();
|
||||
|
||||
// lldb_private::Thread overrides
|
||||
void RefreshStateAfterStop() override;
|
||||
void WillResume(lldb::StateType resume_state) override;
|
||||
void DidStop() override;
|
||||
lldb::RegisterContextSP GetRegisterContext() override;
|
||||
lldb::RegisterContextSP
|
||||
CreateRegisterContextForFrame(StackFrame *frame) override;
|
||||
bool CalculateStopInfo() override;
|
||||
Unwind *GetUnwinder() override;
|
||||
|
||||
bool DoResume();
|
||||
|
||||
HostThread GetHostThread() const { return m_host_thread; }
|
||||
|
||||
private:
|
||||
lldb::RegisterContextSP CreateRegisterContextForFrameIndex(uint32_t idx);
|
||||
|
||||
HostThread m_host_thread;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,166 +0,0 @@
|
|||
//===-- RegisterContextWindowsLive_x64.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/Error.h"
|
||||
#include "lldb/Core/RegisterValue.h"
|
||||
#include "lldb/Host/windows/HostThreadWindows.h"
|
||||
#include "lldb/Host/windows/windows.h"
|
||||
#include "lldb/lldb-private-types.h"
|
||||
|
||||
#include "RegisterContextWindowsLive_x64.h"
|
||||
#include "TargetThreadWindows.h"
|
||||
#include "lldb-x86-register-enums.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
RegisterContextWindowsLive_x64::RegisterContextWindowsLive_x64(
|
||||
Thread &thread, uint32_t concrete_frame_idx)
|
||||
: RegisterContextWindows_x64(thread, concrete_frame_idx) {}
|
||||
|
||||
RegisterContextWindowsLive_x64::~RegisterContextWindowsLive_x64() {}
|
||||
|
||||
bool RegisterContextWindowsLive_x64::ReadRegister(const RegisterInfo *reg_info,
|
||||
RegisterValue ®_value) {
|
||||
if (!CacheAllRegisterValues())
|
||||
return false;
|
||||
|
||||
switch (reg_info->kinds[eRegisterKindLLDB]) {
|
||||
case lldb_rax_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rax);
|
||||
break;
|
||||
case lldb_rbx_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rbx);
|
||||
break;
|
||||
case lldb_rcx_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rcx);
|
||||
break;
|
||||
case lldb_rdx_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rdx);
|
||||
break;
|
||||
case lldb_rdi_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rdi);
|
||||
break;
|
||||
case lldb_rsi_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rsi);
|
||||
break;
|
||||
case lldb_r8_x86_64:
|
||||
reg_value.SetUInt64(m_context.R8);
|
||||
break;
|
||||
case lldb_r9_x86_64:
|
||||
reg_value.SetUInt64(m_context.R9);
|
||||
break;
|
||||
case lldb_r10_x86_64:
|
||||
reg_value.SetUInt64(m_context.R10);
|
||||
break;
|
||||
case lldb_r11_x86_64:
|
||||
reg_value.SetUInt64(m_context.R11);
|
||||
break;
|
||||
case lldb_r12_x86_64:
|
||||
reg_value.SetUInt64(m_context.R12);
|
||||
break;
|
||||
case lldb_r13_x86_64:
|
||||
reg_value.SetUInt64(m_context.R13);
|
||||
break;
|
||||
case lldb_r14_x86_64:
|
||||
reg_value.SetUInt64(m_context.R14);
|
||||
break;
|
||||
case lldb_r15_x86_64:
|
||||
reg_value.SetUInt64(m_context.R15);
|
||||
break;
|
||||
case lldb_rbp_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rbp);
|
||||
break;
|
||||
case lldb_rsp_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rsp);
|
||||
break;
|
||||
case lldb_rip_x86_64:
|
||||
reg_value.SetUInt64(m_context.Rip);
|
||||
break;
|
||||
case lldb_rflags_x86_64:
|
||||
reg_value.SetUInt64(m_context.EFlags);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RegisterContextWindowsLive_x64::WriteRegister(
|
||||
const RegisterInfo *reg_info, const RegisterValue ®_value) {
|
||||
// Since we cannot only write a single register value to the inferior, we need
|
||||
// to make sure
|
||||
// our cached copy of the register values are fresh. Otherwise when writing
|
||||
// EAX, for example,
|
||||
// we may also overwrite some other register with a stale value.
|
||||
if (!CacheAllRegisterValues())
|
||||
return false;
|
||||
|
||||
switch (reg_info->kinds[eRegisterKindLLDB]) {
|
||||
case lldb_rax_x86_64:
|
||||
m_context.Rax = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rbx_x86_64:
|
||||
m_context.Rbx = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rcx_x86_64:
|
||||
m_context.Rcx = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rdx_x86_64:
|
||||
m_context.Rdx = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rdi_x86_64:
|
||||
m_context.Rdi = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rsi_x86_64:
|
||||
m_context.Rsi = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r8_x86_64:
|
||||
m_context.R8 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r9_x86_64:
|
||||
m_context.R9 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r10_x86_64:
|
||||
m_context.R10 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r11_x86_64:
|
||||
m_context.R11 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r12_x86_64:
|
||||
m_context.R12 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r13_x86_64:
|
||||
m_context.R13 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r14_x86_64:
|
||||
m_context.R14 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_r15_x86_64:
|
||||
m_context.R15 = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rbp_x86_64:
|
||||
m_context.Rbp = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rsp_x86_64:
|
||||
m_context.Rsp = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rip_x86_64:
|
||||
m_context.Rip = reg_value.GetAsUInt64();
|
||||
break;
|
||||
case lldb_rflags_x86_64:
|
||||
m_context.EFlags = reg_value.GetAsUInt64();
|
||||
break;
|
||||
}
|
||||
|
||||
// Physically update the registers in the target process.
|
||||
TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
|
||||
return ::SetThreadContext(
|
||||
wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//===-- RegisterContextWindowsLive_x64.h ------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_RegisterContextWindowsLive_x64_H_
|
||||
#define liblldb_RegisterContextWindowsLive_x64_H_
|
||||
|
||||
#include "../../Common/x64/RegisterContextWindows_x64.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class Thread;
|
||||
|
||||
class RegisterContextWindowsLive_x64 : public RegisterContextWindows_x64 {
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
RegisterContextWindowsLive_x64(Thread &thread, uint32_t concrete_frame_idx);
|
||||
|
||||
virtual ~RegisterContextWindowsLive_x64();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Subclasses must override these functions
|
||||
//------------------------------------------------------------------
|
||||
bool ReadRegister(const RegisterInfo *reg_info,
|
||||
RegisterValue ®_value) override;
|
||||
|
||||
bool WriteRegister(const RegisterInfo *reg_info,
|
||||
const RegisterValue ®_value) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef liblldb_RegisterContextWindowsLive_x64_H_
|
|
@ -1,108 +0,0 @@
|
|||
//===-- RegisterContextWindowsLive_x86.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/Error.h"
|
||||
#include "lldb/Core/RegisterValue.h"
|
||||
#include "lldb/Host/windows/HostThreadWindows.h"
|
||||
#include "lldb/Host/windows/windows.h"
|
||||
#include "lldb/lldb-private-types.h"
|
||||
|
||||
#include "ProcessWindowsLog.h"
|
||||
#include "RegisterContextWindowsLive_x86.h"
|
||||
#include "TargetThreadWindows.h"
|
||||
#include "lldb-x86-register-enums.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
RegisterContextWindowsLive_x86::RegisterContextWindowsLive_x86(
|
||||
Thread &thread, uint32_t concrete_frame_idx)
|
||||
: RegisterContextWindows_x86(thread, concrete_frame_idx) {}
|
||||
|
||||
RegisterContextWindowsLive_x86::~RegisterContextWindowsLive_x86() {}
|
||||
|
||||
bool RegisterContextWindowsLive_x86::WriteRegister(
|
||||
const RegisterInfo *reg_info, const RegisterValue ®_value) {
|
||||
// Since we cannot only write a single register value to the inferior, we need
|
||||
// to make sure
|
||||
// our cached copy of the register values are fresh. Otherwise when writing
|
||||
// EAX, for example,
|
||||
// we may also overwrite some other register with a stale value.
|
||||
if (!CacheAllRegisterValues())
|
||||
return false;
|
||||
|
||||
uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
|
||||
switch (reg) {
|
||||
case lldb_eax_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Eax = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_ebx_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Ebx = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_ecx_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Ecx = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_edx_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Edx = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_edi_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Edi = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_esi_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Esi = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_ebp_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Ebp = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_esp_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Esp = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_eip_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.Eip = reg_value.GetAsUInt32();
|
||||
break;
|
||||
case lldb_eflags_i386:
|
||||
WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS",
|
||||
reg_value.GetAsUInt32());
|
||||
m_context.EFlags = reg_value.GetAsUInt32();
|
||||
break;
|
||||
default:
|
||||
WINWARN_IFALL(WINDOWS_LOG_REGISTERS,
|
||||
"Write value 0x%x to unknown register %u",
|
||||
reg_value.GetAsUInt32(), reg);
|
||||
}
|
||||
|
||||
// Physically update the registers in the target process.
|
||||
TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
|
||||
return ::SetThreadContext(
|
||||
wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
|
||||
}
|
||||
|
||||
} // namespace lldb_private
|
|
@ -1,34 +0,0 @@
|
|||
//===-- RegisterContextWindowsLive_x86.h ------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_RegisterContextWindowsLive_x86_H_
|
||||
#define liblldb_RegisterContextWindowsLive_x86_H_
|
||||
|
||||
#include "../../Common/x86/RegisterContextWindows_x86.h"
|
||||
#include "lldb/lldb-forward.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class Thread;
|
||||
|
||||
class RegisterContextWindowsLive_x86 : public RegisterContextWindows_x86 {
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
RegisterContextWindowsLive_x86(Thread &thread, uint32_t concrete_frame_idx);
|
||||
|
||||
virtual ~RegisterContextWindowsLive_x86();
|
||||
|
||||
bool WriteRegister(const RegisterInfo *reg_info,
|
||||
const RegisterValue ®_value) override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // #ifndef liblldb_RegisterContextWindowsLive_x86_H_
|
Loading…
Reference in New Issue