diff options
author | Zachary Turner <zturner@google.com> | 2015-04-27 22:58:57 +0000 |
---|---|---|
committer | Zachary Turner <zturner@google.com> | 2015-04-27 22:58:57 +0000 |
commit | 7cc3494deabb58d810cb1e56636d033572ae4ee4 (patch) | |
tree | 2eb397ba21f08be15ff8e6610b54f7efa378c8d2 | |
parent | 675e539f542edd992e2d03e9b633a01e142d50b6 (diff) | |
download | bcm5719-llvm-7cc3494deabb58d810cb1e56636d033572ae4ee4.tar.gz bcm5719-llvm-7cc3494deabb58d810cb1e56636d033572ae4ee4.zip |
[Windows] Add a RegisterContextWindows_x64.
With this patch, LLDB can debug x64 executables on Windows with
the same level of functionality as for x86 executables.
llvm-svn: 235935
8 files changed, 605 insertions, 161 deletions
diff --git a/lldb/source/Plugins/Process/Windows/CMakeLists.txt b/lldb/source/Plugins/Process/Windows/CMakeLists.txt index cc2dd554fa8..c0f210e0d00 100644 --- a/lldb/source/Plugins/Process/Windows/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Windows/CMakeLists.txt @@ -1,26 +1,26 @@ set(LLVM_NO_RTTI 1) -macro(add_process_windows_subdirectory group) - list(APPEND PROC_WINDOWS_SOURCES ${ARGN}) - source_group(${group} FILES ${ARGN}) -endmacro() - include_directories(.) include_directories(../Utility) -add_process_windows_subdirectory(common +set(PROC_WINDOWS_SOURCES DebuggerThread.cpp DynamicLoaderWindows.cpp LocalDebugDelegate.cpp ProcessWindows.cpp ProcessWindowsLog.cpp + RegisterContextWindows.cpp TargetThreadWindows.cpp ) if (CMAKE_SIZEOF_VOID_P EQUAL 4) - add_process_windows_subdirectory(x86 - x86/RegisterContextWindows_x86.cpp - ) + set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES} + x86/RegisterContextWindows_x86.cpp + ) +elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES} + x64/RegisterContextWindows_x64.cpp + ) endif() add_lldb_library(lldbPluginProcessWindows diff --git a/lldb/source/Plugins/Process/Windows/RegisterContextWindows.cpp b/lldb/source/Plugins/Process/Windows/RegisterContextWindows.cpp new file mode 100644 index 00000000000..1a025c221bb --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/RegisterContextWindows.cpp @@ -0,0 +1,149 @@ +//===-- RegisterContextWindows.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/lldb-private-types.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/Error.h" +#include "lldb/Host/windows/HostThreadWindows.h" +#include "lldb/Host/windows/windows.h" + +#include "RegisterContextWindows.h" +#include "TargetThreadWindows.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace lldb; +using namespace lldb_private; + +const DWORD kWinContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + +//------------------------------------------------------------------ +// Constructors and Destructors +//------------------------------------------------------------------ +RegisterContextWindows::RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx) + : RegisterContext(thread, concrete_frame_idx) + , m_context() + , m_context_stale(true) +{ +} + +RegisterContextWindows::~RegisterContextWindows() +{ +} + +void +RegisterContextWindows::InvalidateAllRegisters() +{ + m_context_stale = true; +} + +bool +RegisterContextWindows::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) +{ + if (!CacheAllRegisterValues()) + return false; + if (data_sp->GetByteSize() < sizeof(m_context)) + { + data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0)); + } + memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context)); + return true; +} + +bool +RegisterContextWindows::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) +{ + assert(data_sp->GetByteSize() >= sizeof(m_context)); + memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context)); + + TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); + if (!::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context)) + return false; + + return true; +} + +uint32_t +RegisterContextWindows::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) +{ + const uint32_t num_regs = GetRegisterCount(); + + assert(kind < kNumRegisterKinds); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) + { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); + + if (reg_info->kinds[kind] == num) + return reg_idx; + } + + return LLDB_INVALID_REGNUM; +} + +//------------------------------------------------------------------ +// Subclasses can these functions if desired +//------------------------------------------------------------------ +uint32_t +RegisterContextWindows::NumSupportedHardwareBreakpoints() +{ + // Support for hardware breakpoints not yet implemented. + return 0; +} + +uint32_t +RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) +{ + return 0; +} + +bool +RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx) +{ + return false; +} + +uint32_t +RegisterContextWindows::NumSupportedHardwareWatchpoints() +{ + // Support for hardware watchpoints not yet implemented. + return 0; +} + +uint32_t +RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) +{ + return 0; +} + +bool +RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index) +{ + return false; +} + +bool +RegisterContextWindows::HardwareSingleStep(bool enable) +{ + return false; +} + +bool +RegisterContextWindows::CacheAllRegisterValues() +{ + if (!m_context_stale) + return true; + + TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); + memset(&m_context, 0, sizeof(m_context)); + m_context.ContextFlags = kWinContextFlags; + if (!::GetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context)) + return false; + m_context_stale = false; + return true; +} diff --git a/lldb/source/Plugins/Process/Windows/RegisterContextWindows.h b/lldb/source/Plugins/Process/Windows/RegisterContextWindows.h new file mode 100644 index 00000000000..e9eaf3bc34b --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/RegisterContextWindows.h @@ -0,0 +1,69 @@ +//===-- RegisterContextWindows.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_RegisterContextWindows_H_ +#define liblldb_RegisterContextWindows_H_ + +#include "lldb/lldb-forward.h" +#include "lldb/Target/RegisterContext.h" + +namespace lldb_private +{ + +class Thread; + +class RegisterContextWindows : public lldb_private::RegisterContext +{ + public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx); + + virtual ~RegisterContextWindows(); + + //------------------------------------------------------------------ + // Subclasses must override these functions + //------------------------------------------------------------------ + void InvalidateAllRegisters() override; + + bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; + + bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override; + + //------------------------------------------------------------------ + // Subclasses can override these functions if desired + //------------------------------------------------------------------ + uint32_t NumSupportedHardwareBreakpoints() override; + + uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; + + bool ClearHardwareBreakpoint(uint32_t hw_idx) override; + + uint32_t NumSupportedHardwareWatchpoints() override; + + uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override; + + bool ClearHardwareWatchpoint(uint32_t hw_index) override; + + bool HardwareSingleStep(bool enable) override; + + protected: + bool CacheAllRegisterValues(); + + CONTEXT m_context; + + private: + bool m_context_stale; +}; +} + +#endif // #ifndef liblldb_RegisterContextPOSIX_x86_H_ diff --git a/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp index 6cc60ee04a3..e358062534a 100644 --- a/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp @@ -17,7 +17,9 @@ #include "ProcessWindows.h" #include "UnwindLLDB.h" -#if !defined(_WIN64) +#if defined(_WIN64) +#include "x64/RegisterContextWindows_x64.h" +#else #include "x86/RegisterContextWindows_x86.h" #endif @@ -86,7 +88,7 @@ TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) break; case llvm::Triple::x86_64: #if defined(_WIN64) - // FIXME: This is a 64-bit process, create a RegisterContextWindows_x86_64 + 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 diff --git a/lldb/source/Plugins/Process/Windows/x64/RegisterContextWindows_x64.cpp b/lldb/source/Plugins/Process/Windows/x64/RegisterContextWindows_x64.cpp new file mode 100644 index 00000000000..2ea7572d574 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/x64/RegisterContextWindows_x64.cpp @@ -0,0 +1,323 @@ +//===-- RegisterContextWindows_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/lldb-private-types.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Host/windows/HostThreadWindows.h" +#include "lldb/Host/windows/windows.h" + +#include "lldb-x86-register-enums.h" +#include "RegisterContext_x86.h" +#include "RegisterContextWindows_x64.h" +#include "TargetThreadWindows.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace lldb; +using namespace lldb_private; + +#define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase +#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary + +namespace +{ + +// This enum defines the layout of the global RegisterInfo array. This is necessary because +// lldb register sets are defined in terms of indices into the register array. As such, the +// order of RegisterInfos defined in global registers array must match the order defined here. +// When defining the register set layouts, these values can appear in an arbitrary order, and that +// determines the order that register values are displayed in a dump. +enum RegisterIndex +{ + eRegisterIndexRax, + eRegisterIndexRbx, + eRegisterIndexRcx, + eRegisterIndexRdx, + eRegisterIndexRdi, + eRegisterIndexRsi, + eRegisterIndexR8, + eRegisterIndexR9, + eRegisterIndexR10, + eRegisterIndexR11, + eRegisterIndexR12, + eRegisterIndexR13, + eRegisterIndexR14, + eRegisterIndexR15, + eRegisterIndexRbp, + eRegisterIndexRsp, + eRegisterIndexRip, + eRegisterIndexRflags +}; + +// Array of all register information supported by Windows x86 +RegisterInfo g_register_infos[] = { + // Macro auto defines most stuff GCC DWARF GENERIC + // GDB LLDB VALUE REGS INVALIDATE REGS + // ================================ ========================= ====================== ========================= + // =================== ================= ========== =============== + {DEFINE_GPR(rax, nullptr), + {gcc_dwarf_rax_x86_64, gcc_dwarf_rax_x86_64, LLDB_INVALID_REGNUM, gdb_rax_x86_64, lldb_rax_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rbx, nullptr), + {gcc_dwarf_rbx_x86_64, gcc_dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, gdb_rbx_x86_64, lldb_rbx_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rcx, nullptr), + {gcc_dwarf_rcx_x86_64, gcc_dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, gdb_rcx_x86_64, lldb_rcx_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rdx, nullptr), + {gcc_dwarf_rdx_x86_64, gcc_dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, gdb_rdx_x86_64, lldb_rdx_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rdi, nullptr), + {gcc_dwarf_rdi_x86_64, gcc_dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, gdb_rdi_x86_64, lldb_rdi_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rsi, nullptr), + {gcc_dwarf_rsi_x86_64, gcc_dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, gdb_rsi_x86_64, lldb_rsi_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r8, nullptr), + {gcc_dwarf_r8_x86_64, gcc_dwarf_r8_x86_64, LLDB_INVALID_REGNUM, gdb_r8_x86_64, lldb_r8_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r9, nullptr), + {gcc_dwarf_r9_x86_64, gcc_dwarf_r9_x86_64, LLDB_INVALID_REGNUM, gdb_r9_x86_64, lldb_r9_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r10, nullptr), + {gcc_dwarf_r10_x86_64, gcc_dwarf_r10_x86_64, LLDB_INVALID_REGNUM, gdb_r10_x86_64, lldb_r10_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r11, nullptr), + {gcc_dwarf_r11_x86_64, gcc_dwarf_r11_x86_64, LLDB_INVALID_REGNUM, gdb_r11_x86_64, lldb_r11_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r12, nullptr), + {gcc_dwarf_r12_x86_64, gcc_dwarf_r12_x86_64, LLDB_INVALID_REGNUM, gdb_r12_x86_64, lldb_r12_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r13, nullptr), + {gcc_dwarf_r13_x86_64, gcc_dwarf_r13_x86_64, LLDB_INVALID_REGNUM, gdb_r13_x86_64, lldb_r13_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r14, nullptr), + {gcc_dwarf_r14_x86_64, gcc_dwarf_r14_x86_64, LLDB_INVALID_REGNUM, gdb_r14_x86_64, lldb_r14_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r15, nullptr), + {gcc_dwarf_r15_x86_64, gcc_dwarf_r15_x86_64, LLDB_INVALID_REGNUM, gdb_r15_x86_64, lldb_r15_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rbp, "fp"), + {gcc_dwarf_rbp_x86_64, gcc_dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, gdb_rbp_x86_64, lldb_rbp_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rsp, "sp"), + {gcc_dwarf_rsp_x86_64, gcc_dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, gdb_rsp_x86_64, lldb_rsp_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rip, "pc"), + {gcc_dwarf_rip_x86_64, gcc_dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, gdb_rip_x86_64, lldb_rip_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR_BIN(eflags, "flags"), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_rflags_x86_64, lldb_rflags_x86_64}, + nullptr, + nullptr}, +}; + +// Array of lldb register numbers used to define the set of all General Purpose Registers +uint32_t g_gpr_reg_indices[] = {eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx, eRegisterIndexRdx, + eRegisterIndexRdi, eRegisterIndexRsi, eRegisterIndexR8, eRegisterIndexR9, + eRegisterIndexR10, eRegisterIndexR11, eRegisterIndexR12, eRegisterIndexR13, + eRegisterIndexR14, eRegisterIndexR15, eRegisterIndexRbp, eRegisterIndexRsp, + eRegisterIndexRip, eRegisterIndexRflags}; + +RegisterSet g_register_sets[] = { + {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, +}; +} + +//------------------------------------------------------------------ +// Constructors and Destructors +//------------------------------------------------------------------ +RegisterContextWindows_x64::RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx) + : RegisterContextWindows(thread, concrete_frame_idx) +{ +} + +RegisterContextWindows_x64::~RegisterContextWindows_x64() +{ +} + +size_t +RegisterContextWindows_x64::GetRegisterCount() +{ + return llvm::array_lengthof(g_register_infos); +} + +const RegisterInfo * +RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) +{ + return &g_register_infos[reg]; +} + +size_t +RegisterContextWindows_x64::GetRegisterSetCount() +{ + return llvm::array_lengthof(g_register_sets); +} + +const RegisterSet * +RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) +{ + return &g_register_sets[reg_set]; +} + +bool +RegisterContextWindows_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 +RegisterContextWindows_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); +} diff --git a/lldb/source/Plugins/Process/Windows/x64/RegisterContextWindows_x64.h b/lldb/source/Plugins/Process/Windows/x64/RegisterContextWindows_x64.h new file mode 100644 index 00000000000..15e803f6a71 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/x64/RegisterContextWindows_x64.h @@ -0,0 +1,48 @@ +//===-- RegisterContextWindows_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_RegisterContextWindows_x64_H_ +#define liblldb_RegisterContextWindows_x64_H_ + +#include "lldb/lldb-forward.h" +#include "RegisterContextWindows.h" + +namespace lldb_private +{ + +class Thread; + +class RegisterContextWindows_x64 : public RegisterContextWindows +{ + public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx); + + virtual ~RegisterContextWindows_x64(); + + //------------------------------------------------------------------ + // Subclasses must override these functions + //------------------------------------------------------------------ + size_t GetRegisterCount() override; + + const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const RegisterSet *GetRegisterSet(size_t reg_set) override; + + bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; +}; +} + +#endif // #ifndef liblldb_RegisterContextPOSIX_x64_H_ diff --git a/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.cpp b/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.cpp index 9051e9244b7..595046aa738 100644 --- a/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.cpp +++ b/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/lldb-private-types.h" -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Error.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -49,8 +48,6 @@ enum RegisterIndex eRegisterIndexEflags }; -const DWORD kWinContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; - // Array of all register information supported by Windows x86 RegisterInfo g_register_infos[] = { @@ -92,9 +89,7 @@ RegisterSet g_register_sets[] = { // Constructors and Destructors //------------------------------------------------------------------ RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx) - : RegisterContext(thread, concrete_frame_idx) - , m_context() - , m_context_stale(true) + : RegisterContextWindows(thread, concrete_frame_idx) { } @@ -102,12 +97,6 @@ RegisterContextWindows_x86::~RegisterContextWindows_x86() { } -void -RegisterContextWindows_x86::InvalidateAllRegisters() -{ - m_context_stale = true; -} - size_t RegisterContextWindows_x86::GetRegisterCount() { @@ -221,108 +210,3 @@ RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info, const Re TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); } - -bool -RegisterContextWindows_x86::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) -{ - if (!CacheAllRegisterValues()) - return false; - if (data_sp->GetByteSize() < sizeof(m_context)) - { - data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0)); - } - memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context)); - return true; -} - -bool -RegisterContextWindows_x86::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) -{ - assert(data_sp->GetByteSize() >= sizeof(m_context)); - memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context)); - - TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); - if (!::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context)) - return false; - - return true; -} - -uint32_t -RegisterContextWindows_x86::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) -{ - const uint32_t num_regs = GetRegisterCount(); - - assert(kind < kNumRegisterKinds); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) - { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx); - - if (reg_info->kinds[kind] == num) - return reg_idx; - } - - return LLDB_INVALID_REGNUM; -} - -//------------------------------------------------------------------ -// Subclasses can these functions if desired -//------------------------------------------------------------------ -uint32_t -RegisterContextWindows_x86::NumSupportedHardwareBreakpoints() -{ - // Support for hardware breakpoints not yet implemented. - return 0; -} - -uint32_t -RegisterContextWindows_x86::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) -{ - return 0; -} - -bool -RegisterContextWindows_x86::ClearHardwareBreakpoint(uint32_t hw_idx) -{ - return false; -} - -uint32_t -RegisterContextWindows_x86::NumSupportedHardwareWatchpoints() -{ - // Support for hardware watchpoints not yet implemented. - return 0; -} - -uint32_t -RegisterContextWindows_x86::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) -{ - return 0; -} - -bool -RegisterContextWindows_x86::ClearHardwareWatchpoint(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextWindows_x86::HardwareSingleStep(bool enable) -{ - return false; -} - -bool -RegisterContextWindows_x86::CacheAllRegisterValues() -{ - if (!m_context_stale) - return true; - - TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread); - memset(&m_context, 0, sizeof(m_context)); - m_context.ContextFlags = kWinContextFlags; - if (!::GetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context)) - return false; - m_context_stale = false; - return true; -} diff --git a/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.h b/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.h index c4357178764..20a1e88d07b 100644 --- a/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.h +++ b/lldb/source/Plugins/Process/Windows/x86/RegisterContextWindows_x86.h @@ -11,14 +11,14 @@ #define liblldb_RegisterContextWindows_x86_H_ #include "lldb/lldb-forward.h" -#include "lldb/Target/RegisterContext.h" +#include "RegisterContextWindows.h" namespace lldb_private { class Thread; -class RegisterContextWindows_x86 : public lldb_private::RegisterContext +class RegisterContextWindows_x86 : public RegisterContextWindows { public: //------------------------------------------------------------------ @@ -31,8 +31,6 @@ class RegisterContextWindows_x86 : public lldb_private::RegisterContext //------------------------------------------------------------------ // Subclasses must override these functions //------------------------------------------------------------------ - void InvalidateAllRegisters() override; - size_t GetRegisterCount() override; const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; @@ -44,35 +42,6 @@ class RegisterContextWindows_x86 : public lldb_private::RegisterContext bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) override; bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; - - bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; - - bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; - - uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override; - - //------------------------------------------------------------------ - // Subclasses can override these functions if desired - //------------------------------------------------------------------ - uint32_t NumSupportedHardwareBreakpoints() override; - - uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override; - - bool ClearHardwareBreakpoint(uint32_t hw_idx) override; - - uint32_t NumSupportedHardwareWatchpoints() override; - - uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) override; - - bool ClearHardwareWatchpoint(uint32_t hw_index) override; - - bool HardwareSingleStep(bool enable) override; - - private: - bool CacheAllRegisterValues(); - - CONTEXT m_context; - bool m_context_stale; }; } |