diff --git a/lldb/cmake/LLDBDependencies.cmake b/lldb/cmake/LLDBDependencies.cmake index 0d44bdafe64f..b78682f66194 100644 --- a/lldb/cmake/LLDBDependencies.cmake +++ b/lldb/cmake/LLDBDependencies.cmake @@ -81,6 +81,7 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" ) list(APPEND LLDB_USED_LIBS lldbPluginProcessWindows lldbPluginProcessWinMiniDump + lldbPluginProcessWindowsCommon Ws2_32 Rpcrt4 ) diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index ddf86277623b..5b09460fd3fe 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -76,7 +76,7 @@ #if defined(_MSC_VER) #include "lldb/Host/windows/windows.h" -#include "Plugins/Process/Windows/Live/ProcessWindows.h" +#include "Plugins/Process/Windows/Live/ProcessWindowsLive.h" #include "Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h" #endif @@ -307,7 +307,7 @@ SystemInitializerFull::Initialize() ObjCPlusPlusLanguage::Initialize(); #if defined(_MSC_VER) - ProcessWindows::Initialize(); + ProcessWindowsLive::Initialize(); #endif #if defined(__FreeBSD__) ProcessFreeBSD::Initialize(); diff --git a/lldb/source/Initialization/SystemInitializerCommon.cpp b/lldb/source/Initialization/SystemInitializerCommon.cpp index a4d6fd8c12b9..4067ad0d573e 100644 --- a/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -49,7 +49,7 @@ #if defined(_MSC_VER) #include "lldb/Host/windows/windows.h" -#include "Plugins/Process/Windows/Live/ProcessWindowsLog.h" +#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h" #endif #include "llvm/Support/TargetSelect.h" diff --git a/lldb/source/Plugins/Process/CMakeLists.txt b/lldb/source/Plugins/Process/CMakeLists.txt index 30ba5c35f5e4..d15df94414b3 100644 --- a/lldb/source/Plugins/Process/CMakeLists.txt +++ b/lldb/source/Plugins/Process/CMakeLists.txt @@ -9,6 +9,7 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD") elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(Windows/Live) add_subdirectory(Windows/MiniDump) + add_subdirectory(Windows/Common) elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_subdirectory(MacOSX-Kernel) endif() diff --git a/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt b/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt new file mode 100644 index 000000000000..5a53c3c3300c --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Common/CMakeLists.txt @@ -0,0 +1,23 @@ +include_directories(.) +include_directories(../../Utility) + +set(PROC_WINDOWS_COMMON_SOURCES + RegisterContextWindows.cpp + ProcessWindows.cpp + ProcessWindowsLog.cpp + TargetThreadWindows.cpp + ) + +if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set(PROC_WINDOWS_COMMON_SOURCES ${PROC_WINDOWS_COMMON_SOURCES} + x86/RegisterContextWindows_x86.cpp + ) +elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PROC_WINDOWS_COMMON_SOURCES ${PROC_WINDOWS_COMMON_SOURCES} + x64/RegisterContextWindows_x64.cpp + ) +endif() + +add_lldb_library(lldbPluginProcessWindowsCommon + ${PROC_WINDOWS_COMMON_SOURCES} + ) diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp new file mode 100644 index 000000000000..fcb4c8efcaea --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -0,0 +1,77 @@ +//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ProcessWindows.h" + +// Other libraries and framework includes +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/State.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +namespace lldb_private +{ + +//------------------------------------------------------------------------------ +// Constructors and destructors. + +ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, Listener &listener) + : lldb_private::Process(target_sp, listener) +{ +} + +ProcessWindows::~ProcessWindows() +{ +} + +size_t +ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error) +{ + error.SetErrorString("GetSTDOUT unsupported on Windows"); + return 0; +} + +size_t +ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error) +{ + error.SetErrorString("GetSTDERR unsupported on Windows"); + return 0; +} + +size_t +ProcessWindows::PutSTDIN(const char *buf, size_t buf_size, Error &error) +{ + error.SetErrorString("PutSTDIN unsupported on Windows"); + return 0; +} + +//------------------------------------------------------------------------------ +// ProcessInterface protocol. + + +lldb::addr_t +ProcessWindows::GetImageInfoAddress() +{ + Target &target = GetTarget(); + ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile(); + Address addr = obj_file->GetImageInfoAddress(&target); + if (addr.IsValid()) + return addr.GetLoadAddress(&target); + else + return LLDB_INVALID_ADDRESS; +} + +} diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h new file mode 100644 index 000000000000..d367dcdc0446 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -0,0 +1,41 @@ +//===-- ProcessWindows.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_Common_ProcessWindows_H_ +#define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_ + +// Other libraries and framework includes +#include "lldb/lldb-forward.h" +#include "lldb/Core/Error.h" +#include "lldb/Target/Process.h" + +namespace lldb_private +{ + +class ProcessWindows : public lldb_private::Process +{ +public: + //------------------------------------------------------------------ + // Constructors and destructors + //------------------------------------------------------------------ + ProcessWindows(lldb::TargetSP target_sp, + lldb_private::Listener &listener); + + ~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; + + lldb::addr_t GetImageInfoAddress() override; +}; + +} + +#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_ diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLog.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp similarity index 96% rename from lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLog.cpp rename to lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp index 090ab84c90a3..47722c5146b2 100644 --- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLog.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp @@ -1,196 +1,194 @@ -//===-- ProcessWindowsLog.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessWindowsLog.h" - -#include - -#include "lldb/Core/StreamFile.h" -#include "lldb/Interpreter/Args.h" -#include "llvm/Support/ManagedStatic.h" - -#include "ProcessWindows.h" - -using namespace lldb; -using namespace lldb_private; - - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_log_sp the first time this function is -// called. -static bool g_log_enabled = false; -static Log * g_log = nullptr; - -static llvm::ManagedStatic g_once_flag; - -void -ProcessWindowsLog::Initialize() -{ - static ConstString g_name("windows"); - - std::call_once(*g_once_flag, [](){ - Log::Callbacks log_callbacks = { - DisableLog, - EnableLog, - ListLogCategories - }; - - Log::RegisterLogChannel(g_name, log_callbacks); - RegisterPluginName(g_name); - }); -} - -void -ProcessWindowsLog::Terminate() -{ -} - -Log * -ProcessWindowsLog::GetLog() -{ - return (g_log_enabled) ? g_log : nullptr; -} - -bool -ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req) -{ - Log *log = GetLog(); - if (!log) - return false; - - uint32_t log_mask = log->GetMask().Get(); - if (req == LogMaskReq::All) - return ((log_mask & mask) == mask); - else - return (log_mask & mask); -} - -static uint32_t -GetFlagBits(const char *arg) -{ - if (::strcasecmp(arg, "all") == 0 ) return WINDOWS_LOG_ALL; - else if (::strcasecmp(arg, "break") == 0 ) return WINDOWS_LOG_BREAKPOINTS; - else if (::strcasecmp(arg, "event") == 0 ) return WINDOWS_LOG_EVENT; - else if (::strcasecmp(arg, "exception") == 0 ) return WINDOWS_LOG_EXCEPTION; - else if (::strcasecmp(arg, "memory") == 0 ) return WINDOWS_LOG_MEMORY; - else if (::strcasecmp(arg, "process") == 0 ) return WINDOWS_LOG_PROCESS; - else if (::strcasecmp(arg, "registers") == 0 ) return WINDOWS_LOG_REGISTERS; - else if (::strcasecmp(arg, "step") == 0 ) return WINDOWS_LOG_STEP; - else if (::strcasecmp(arg, "thread") == 0 ) return WINDOWS_LOG_THREAD; - else if (::strcasecmp(arg, "verbose") == 0 ) return WINDOWS_LOG_VERBOSE; - return 0; -} - -void -ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm) -{ - Log *log (GetLog()); - if (log) - { - uint32_t flag_bits = 0; - - if (args[0] != nullptr) - { - flag_bits = log->GetMask().Get(); - for (; args[0]; args++) - { - const char *arg = args[0]; - uint32_t bits = GetFlagBits(arg); - - if (bits) - { - flag_bits &= ~bits; - } - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories(feedback_strm); - } - } - } - - log->GetMask().Reset(flag_bits); - if (flag_bits == 0) - { - g_log_enabled = false; - log->SetStream(lldb::StreamSP()); - } - } - - return; -} - -Log * -ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - if (g_log) - flag_bits = g_log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - if (g_log) - g_log->SetStream(log_stream_sp); - else - g_log = new Log(log_stream_sp); - } - - if (g_log) - { - bool got_unknown_category = false; - for (; args[0]; args++) - { - const char *arg = args[0]; - uint32_t bits = GetFlagBits(arg); - - if (bits) - { - flag_bits |= bits; - } - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = WINDOWS_LOG_ALL; - g_log->GetMask().Reset(flag_bits); - g_log->GetOptions().Reset(log_options); - g_log_enabled = true; - } - return g_log; -} - -void -ProcessWindowsLog::ListLogCategories(Stream *strm) -{ - strm->Printf("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " break - log breakpoints\n" - " event - log low level debugger events\n" - " exception - log exception information\n" - " memory - log memory reads and writes\n" - " process - log process events and activities\n" - " registers - log register read/writes\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n", - ProcessWindowsLog::m_pluginname); -} - -const char *ProcessWindowsLog::m_pluginname = ""; +//===-- ProcessWindowsLog.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ProcessWindowsLog.h" + +#include + +#include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/Args.h" +#include "llvm/Support/ManagedStatic.h" + +using namespace lldb; +using namespace lldb_private; + + +// We want to avoid global constructors where code needs to be run so here we +// control access to our static g_log_sp by hiding it in a singleton function +// that will construct the static g_log_sp the first time this function is +// called. +static bool g_log_enabled = false; +static Log * g_log = nullptr; + +static llvm::ManagedStatic g_once_flag; + +void +ProcessWindowsLog::Initialize() +{ + static ConstString g_name("windows"); + + std::call_once(*g_once_flag, [](){ + Log::Callbacks log_callbacks = { + DisableLog, + EnableLog, + ListLogCategories + }; + + Log::RegisterLogChannel(g_name, log_callbacks); + RegisterPluginName(g_name); + }); +} + +void +ProcessWindowsLog::Terminate() +{ +} + +Log * +ProcessWindowsLog::GetLog() +{ + return (g_log_enabled) ? g_log : nullptr; +} + +bool +ProcessWindowsLog::TestLogFlags(uint32_t mask, LogMaskReq req) +{ + Log *log = GetLog(); + if (!log) + return false; + + uint32_t log_mask = log->GetMask().Get(); + if (req == LogMaskReq::All) + return ((log_mask & mask) == mask); + else + return (log_mask & mask); +} + +static uint32_t +GetFlagBits(const char *arg) +{ + if (::strcasecmp(arg, "all") == 0 ) return WINDOWS_LOG_ALL; + else if (::strcasecmp(arg, "break") == 0 ) return WINDOWS_LOG_BREAKPOINTS; + else if (::strcasecmp(arg, "event") == 0 ) return WINDOWS_LOG_EVENT; + else if (::strcasecmp(arg, "exception") == 0 ) return WINDOWS_LOG_EXCEPTION; + else if (::strcasecmp(arg, "memory") == 0 ) return WINDOWS_LOG_MEMORY; + else if (::strcasecmp(arg, "process") == 0 ) return WINDOWS_LOG_PROCESS; + else if (::strcasecmp(arg, "registers") == 0 ) return WINDOWS_LOG_REGISTERS; + else if (::strcasecmp(arg, "step") == 0 ) return WINDOWS_LOG_STEP; + else if (::strcasecmp(arg, "thread") == 0 ) return WINDOWS_LOG_THREAD; + else if (::strcasecmp(arg, "verbose") == 0 ) return WINDOWS_LOG_VERBOSE; + return 0; +} + +void +ProcessWindowsLog::DisableLog(const char **args, Stream *feedback_strm) +{ + Log *log (GetLog()); + if (log) + { + uint32_t flag_bits = 0; + + if (args[0] != nullptr) + { + flag_bits = log->GetMask().Get(); + for (; args[0]; args++) + { + const char *arg = args[0]; + uint32_t bits = GetFlagBits(arg); + + if (bits) + { + flag_bits &= ~bits; + } + else + { + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); + ListLogCategories(feedback_strm); + } + } + } + + log->GetMask().Reset(flag_bits); + if (flag_bits == 0) + { + g_log_enabled = false; + log->SetStream(lldb::StreamSP()); + } + } + + return; +} + +Log * +ProcessWindowsLog::EnableLog(StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm) +{ + // Try see if there already is a log - that way we can reuse its settings. + // We could reuse the log in toto, but we don't know that the stream is the same. + uint32_t flag_bits = 0; + if (g_log) + flag_bits = g_log->GetMask().Get(); + + // Now make a new log with this stream if one was provided + if (log_stream_sp) + { + if (g_log) + g_log->SetStream(log_stream_sp); + else + g_log = new Log(log_stream_sp); + } + + if (g_log) + { + bool got_unknown_category = false; + for (; args[0]; args++) + { + const char *arg = args[0]; + uint32_t bits = GetFlagBits(arg); + + if (bits) + { + flag_bits |= bits; + } + else + { + feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); + if (got_unknown_category == false) + { + got_unknown_category = true; + ListLogCategories (feedback_strm); + } + } + } + if (flag_bits == 0) + flag_bits = WINDOWS_LOG_ALL; + g_log->GetMask().Reset(flag_bits); + g_log->GetOptions().Reset(log_options); + g_log_enabled = true; + } + return g_log; +} + +void +ProcessWindowsLog::ListLogCategories(Stream *strm) +{ + strm->Printf("Logging categories for '%s':\n" + " all - turn on all available logging categories\n" + " break - log breakpoints\n" + " event - log low level debugger events\n" + " exception - log exception information\n" + " memory - log memory reads and writes\n" + " process - log process events and activities\n" + " registers - log register read/writes\n" + " thread - log thread events and activities\n" + " step - log step related activities\n" + " verbose - enable verbose logging\n", + ProcessWindowsLog::m_pluginname); +} + +const char *ProcessWindowsLog::m_pluginname = ""; diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLog.h b/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h similarity index 97% rename from lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLog.h rename to lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h index 4f021539624a..d798d131faeb 100644 --- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLog.h +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h @@ -1,96 +1,96 @@ -//===-- ProcessWindowsLog.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_ProcessWindowsLog_h_ -#define liblldb_ProcessWindowsLog_h_ - -#include "lldb/Core/Log.h" - -#define WINDOWS_LOG_VERBOSE (1u << 0) -#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations -#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions -#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations -#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls -#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations -#define WINDOWS_LOG_STEP (1u << 5) // Log step operations -#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations -#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events -#define WINDOWS_LOG_ALL (UINT32_MAX) - -enum class LogMaskReq -{ - All, - Any -}; - -class ProcessWindowsLog -{ - static const char *m_pluginname; - -public: - // --------------------------------------------------------------------- - // Public Static Methods - // --------------------------------------------------------------------- - static void - Initialize(); - - static void - Terminate(); - - static void - RegisterPluginName(const char *pluginName) - { - m_pluginname = pluginName; - } - - static void - RegisterPluginName(lldb_private::ConstString pluginName) - { - m_pluginname = pluginName.GetCString(); - } - - static bool - TestLogFlags(uint32_t mask, LogMaskReq req); - - static lldb_private::Log * - GetLog(); - - static void - DisableLog(const char **args, lldb_private::Stream *feedback_strm); - - static lldb_private::Log * - EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options, - const char **args, lldb_private::Stream *feedback_strm); - - static void - ListLogCategories(lldb_private::Stream *strm); -}; - -#define WINLOGF_IF(Flags, Req, Method, ...) \ - { \ - if (ProcessWindowsLog::TestLogFlags(Flags, Req)) \ - { \ - Log *log = ProcessWindowsLog::GetLog(); \ - if (log) \ - log->Method(__VA_ARGS__); \ - } \ - } - -#define WINLOG_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Printf, __VA_ARGS__) -#define WINLOG_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Printf, __VA_ARGS__) -#define WINLOGV_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Verbose, __VA_ARGS__) -#define WINLOGV_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Verbose, __VA_ARGS__) -#define WINLOGD_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Debug, __VA_ARGS__) -#define WINLOGD_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Debug, __VA_ARGS__) -#define WINERR_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Error, __VA_ARGS__) -#define WINERR_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Error, __VA_ARGS__) -#define WINWARN_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Warning, __VA_ARGS__) -#define WINWARN_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Warning, __VA_ARGS__) - -#endif // liblldb_ProcessWindowsLog_h_ +//===-- ProcessWindowsLog.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_ProcessWindowsLog_h_ +#define liblldb_ProcessWindowsLog_h_ + +#include "lldb/Core/Log.h" + +#define WINDOWS_LOG_VERBOSE (1u << 0) +#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations +#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions +#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations +#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls +#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations +#define WINDOWS_LOG_STEP (1u << 5) // Log step operations +#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations +#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events +#define WINDOWS_LOG_ALL (UINT32_MAX) + +enum class LogMaskReq +{ + All, + Any +}; + +class ProcessWindowsLog +{ + static const char *m_pluginname; + +public: + // --------------------------------------------------------------------- + // Public Static Methods + // --------------------------------------------------------------------- + static void + Initialize(); + + static void + Terminate(); + + static void + RegisterPluginName(const char *pluginName) + { + m_pluginname = pluginName; + } + + static void + RegisterPluginName(lldb_private::ConstString pluginName) + { + m_pluginname = pluginName.GetCString(); + } + + static bool + TestLogFlags(uint32_t mask, LogMaskReq req); + + static lldb_private::Log * + GetLog(); + + static void + DisableLog(const char **args, lldb_private::Stream *feedback_strm); + + static lldb_private::Log * + EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options, + const char **args, lldb_private::Stream *feedback_strm); + + static void + ListLogCategories(lldb_private::Stream *strm); +}; + +#define WINLOGF_IF(Flags, Req, Method, ...) \ + { \ + if (ProcessWindowsLog::TestLogFlags(Flags, Req)) \ + { \ + Log *log = ProcessWindowsLog::GetLog(); \ + if (log) \ + log->Method(__VA_ARGS__); \ + } \ + } + +#define WINLOG_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Printf, __VA_ARGS__) +#define WINLOG_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Printf, __VA_ARGS__) +#define WINLOGV_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Verbose, __VA_ARGS__) +#define WINLOGV_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Verbose, __VA_ARGS__) +#define WINLOGD_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Debug, __VA_ARGS__) +#define WINLOGD_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Debug, __VA_ARGS__) +#define WINERR_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Error, __VA_ARGS__) +#define WINERR_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Error, __VA_ARGS__) +#define WINWARN_IFANY(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::Any, Warning, __VA_ARGS__) +#define WINWARN_IFALL(Flags, ...) WINLOGF_IF(Flags, LogMaskReq::All, Warning, __VA_ARGS__) + +#endif // liblldb_ProcessWindowsLog_h_ diff --git a/lldb/source/Plugins/Process/Windows/Live/RegisterContextWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp similarity index 96% rename from lldb/source/Plugins/Process/Windows/Live/RegisterContextWindows.cpp rename to lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp index 8552b4635412..d61675f09b1b 100644 --- a/lldb/source/Plugins/Process/Windows/Live/RegisterContextWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp @@ -1,155 +1,155 @@ -//===-- 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 "ProcessWindowsLog.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(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(m_thread); - memset(&m_context, 0, sizeof(m_context)); - m_context.ContextFlags = kWinContextFlags; - if (!::GetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context)) - { - WINERR_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext failed with error %u while caching register values.", - ::GetLastError()); - return false; - } - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext successfully updated the register values.", ::GetLastError()); - m_context_stale = false; - return true; -} +//===-- 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 "ProcessWindowsLog.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(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(m_thread); + memset(&m_context, 0, sizeof(m_context)); + m_context.ContextFlags = kWinContextFlags; + if (!::GetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context)) + { + WINERR_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext failed with error %u while caching register values.", + ::GetLastError()); + return false; + } + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "GetThreadContext successfully updated the register values.", ::GetLastError()); + m_context_stale = false; + return true; +} diff --git a/lldb/source/Plugins/Process/Windows/Live/RegisterContextWindows.h b/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.h similarity index 93% rename from lldb/source/Plugins/Process/Windows/Live/RegisterContextWindows.h rename to lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.h index f742cd1151ef..f895de8b74b6 100644 --- a/lldb/source/Plugins/Process/Windows/Live/RegisterContextWindows.h +++ b/lldb/source/Plugins/Process/Windows/Common/RegisterContextWindows.h @@ -1,69 +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_ +//===-- 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: + virtual bool CacheAllRegisterValues(); + + CONTEXT m_context; + + private: + bool m_context_stale; +}; +} + +#endif // #ifndef liblldb_RegisterContextWindows_H_ diff --git a/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp new file mode 100644 index 000000000000..dcb6f0c72435 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp @@ -0,0 +1,98 @@ +//===-- TargetThreadWindows.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 "TargetThreadWindows.h" +#include "ProcessWindows.h" +#include "ProcessWindowsLog.h" +#include "UnwindLLDB.h" + +using namespace lldb; +using namespace lldb_private; + +TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread) + : Thread(process, thread.GetNativeThread().GetThreadId()) + , m_host_thread(thread) +{ +} + +TargetThreadWindows::~TargetThreadWindows() +{ + DestroyThread(); +} + +void +TargetThreadWindows::RefreshStateAfterStop() +{ + ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle()); + SetState(eStateStopped); + GetRegisterContext()->InvalidateIfNeeded(false); +} + +void +TargetThreadWindows::WillResume(lldb::StateType resume_state) +{ +} + +void +TargetThreadWindows::DidStop() +{ +} + +bool +TargetThreadWindows::CalculateStopInfo() +{ + SetStopInfo(m_stop_info_sp); + return true; +} + +Unwind * +TargetThreadWindows::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 +TargetThreadWindows::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; +} diff --git a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindows.h b/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h similarity index 79% rename from lldb/source/Plugins/Process/Windows/Live/TargetThreadWindows.h rename to lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h index 2d62c81ee25a..701b56b6d26a 100644 --- a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindows.h +++ b/lldb/source/Plugins/Process/Windows/Common/TargetThreadWindows.h @@ -1,55 +1,50 @@ -//===-- TargetThreadWindows.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_TargetThreadWindows_H_ -#define liblldb_Plugins_Process_Windows_TargetThreadWindows_H_ - -#include "ForwardDecl.h" -#include "lldb/lldb-forward.h" -#include "lldb/Host/HostThread.h" -#include "lldb/Target/Thread.h" -class ProcessWindows; - -namespace lldb_private -{ - -class HostThread; -class StackFrame; - -class TargetThreadWindows : public lldb_private::Thread -{ - public: - TargetThreadWindows(ProcessWindows &process, const HostThread &thread); - virtual ~TargetThreadWindows(); - - // 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 \ No newline at end of file +//===-- TargetThreadWindows.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_TargetThreadWindows_H_ +#define liblldb_Plugins_Process_Windows_TargetThreadWindows_H_ + +//#include "ForwardDecl.h" +#include "lldb/lldb-forward.h" +#include "lldb/Host/HostThread.h" +#include "lldb/Target/Thread.h" + +namespace lldb_private +{ +class ProcessWindows; +class HostThread; +class StackFrame; + +class TargetThreadWindows : public lldb_private::Thread +{ + public: + TargetThreadWindows(ProcessWindows &process, const HostThread &thread); + virtual ~TargetThreadWindows(); + + // lldb_private::Thread overrides + void RefreshStateAfterStop() override; + void WillResume(lldb::StateType resume_state) override; + void DidStop() override; + bool CalculateStopInfo() override; + Unwind *GetUnwinder() override; + + bool DoResume(); + + HostThread + GetHostThread() const + { + return m_host_thread; + } + + private: + HostThread m_host_thread; +}; +} + +#endif diff --git a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindows_x64.cpp b/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp similarity index 97% rename from lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindows_x64.cpp rename to lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp index a42eb8db81a8..103cff4a2a56 100644 --- a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindows_x64.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -1,323 +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 eh_frame DWARF GENERIC - // GDB LLDB VALUE REGS INVALIDATE REGS - // ================================ ========================= ====================== ========================= - // =================== ================= ========== =============== - {DEFINE_GPR(rax, nullptr), - {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rax_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rbx, nullptr), - {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rbx_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rdi, nullptr), - {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdi_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rsi, nullptr), - {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rsi_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r12, nullptr), - {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r12_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r13, nullptr), - {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r13_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r14, nullptr), - {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r14_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(r15, nullptr), - {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r15_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rbp, "fp"), - {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_rbp_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rsp, "sp"), - {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_rsp_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR(rip, "pc"), - {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_rip_x86_64}, - nullptr, - nullptr}, - {DEFINE_GPR_BIN(eflags, "flags"), - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 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(m_thread); - return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); -} +//===-- 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 eh_frame DWARF GENERIC + // GDB LLDB VALUE REGS INVALIDATE REGS + // ================================ ========================= ====================== ========================= + // =================== ================= ========== =============== + {DEFINE_GPR(rax, nullptr), + {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rax_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rbx, nullptr), + {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rbx_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rcx, nullptr), + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rdx, nullptr), + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rdi, nullptr), + {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rdi_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rsi, nullptr), + {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_rsi_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r8, nullptr), + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r9, nullptr), + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r10, nullptr), + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r11, nullptr), + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r12, nullptr), + {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r12_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r13, nullptr), + {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r13_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r14, nullptr), + {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r14_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(r15, nullptr), + {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_r15_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rbp, "fp"), + {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_rbp_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rsp, "sp"), + {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_rsp_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR(rip, "pc"), + {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_rip_x86_64}, + nullptr, + nullptr}, + {DEFINE_GPR_BIN(eflags, "flags"), + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 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(m_thread); + return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); +} diff --git a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindows_x64.h b/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h similarity index 97% rename from lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindows_x64.h rename to lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h index b369d1a78618..15e803f6a71e 100644 --- a/lldb/source/Plugins/Process/Windows/Live/x64/RegisterContextWindows_x64.h +++ b/lldb/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h @@ -1,48 +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_ +//===-- 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/Common/x86/RegisterContextWindows_x86.cpp b/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp new file mode 100644 index 000000000000..48ef79287c94 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp @@ -0,0 +1,123 @@ +//===-- RegisterContextWindows_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/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 "ProcessWindowsLog.h" +#include "RegisterContext_x86.h" +#include "RegisterContextWindows_x86.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace lldb; +using namespace lldb_private; + +#define DEFINE_GPR(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatHexUppercase +#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 4, 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 +{ + eRegisterIndexEax, + eRegisterIndexEbx, + eRegisterIndexEcx, + eRegisterIndexEdx, + eRegisterIndexEdi, + eRegisterIndexEsi, + eRegisterIndexEbp, + eRegisterIndexEsp, + eRegisterIndexEip, + eRegisterIndexEflags +}; + +// Array of all register information supported by Windows x86 +RegisterInfo g_register_infos[] = +{ +// Macro auto defines most stuff eh_frame DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS +// ============================== ======================= =================== ========================= =================== ================= ========== =============== + { DEFINE_GPR(eax, nullptr), { ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_eax_i386 }, nullptr, nullptr}, + { DEFINE_GPR(ebx, nullptr), { ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ebx_i386 }, nullptr, nullptr}, + { DEFINE_GPR(ecx, nullptr), { ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ecx_i386 }, nullptr, nullptr}, + { DEFINE_GPR(edx, nullptr), { ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edx_i386 }, nullptr, nullptr}, + { DEFINE_GPR(edi, nullptr), { ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edi_i386 }, nullptr, nullptr}, + { DEFINE_GPR(esi, nullptr), { ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_esi_i386 }, nullptr, nullptr}, + { DEFINE_GPR(ebp, "fp"), { ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_ebp_i386 }, nullptr, nullptr}, + { DEFINE_GPR(esp, "sp"), { ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_esp_i386 }, nullptr, nullptr}, + { DEFINE_GPR(eip, "pc"), { ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_eip_i386 }, nullptr, nullptr}, + { DEFINE_GPR_BIN(eflags, "flags"), { ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_eflags_i386}, nullptr, nullptr}, +}; + +// Array of lldb register numbers used to define the set of all General Purpose Registers +uint32_t g_gpr_reg_indices[] = +{ + eRegisterIndexEax, + eRegisterIndexEbx, + eRegisterIndexEcx, + eRegisterIndexEdx, + eRegisterIndexEdi, + eRegisterIndexEsi, + eRegisterIndexEbp, + eRegisterIndexEsp, + eRegisterIndexEip, + eRegisterIndexEflags +}; + +RegisterSet g_register_sets[] = { + {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, +}; +} + +//------------------------------------------------------------------ +// Constructors and Destructors +//------------------------------------------------------------------ +RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx) + : RegisterContextWindows(thread, concrete_frame_idx) +{ +} + +RegisterContextWindows_x86::~RegisterContextWindows_x86() +{ +} + +size_t +RegisterContextWindows_x86::GetRegisterCount() +{ + return llvm::array_lengthof(g_register_infos); +} + +const RegisterInfo * +RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg) +{ + return &g_register_infos[reg]; +} + +size_t +RegisterContextWindows_x86::GetRegisterSetCount() +{ + return llvm::array_lengthof(g_register_sets); +} + +const RegisterSet * +RegisterContextWindows_x86::GetRegisterSet(size_t reg_set) +{ + return &g_register_sets[reg_set]; +} + diff --git a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindows_x86.h b/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h similarity index 84% rename from lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindows_x86.h rename to lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h index 20a1e88d07b8..9b838c826688 100644 --- a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindows_x86.h +++ b/lldb/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h @@ -38,11 +38,8 @@ class RegisterContextWindows_x86 : public RegisterContextWindows 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_x86_H_ +#endif // #ifndef liblldb_RegisterContextWindows_x86_H_ diff --git a/lldb/source/Plugins/Process/Windows/Live/CMakeLists.txt b/lldb/source/Plugins/Process/Windows/Live/CMakeLists.txt index 200243a4036f..bdb680ad0bee 100644 --- a/lldb/source/Plugins/Process/Windows/Live/CMakeLists.txt +++ b/lldb/source/Plugins/Process/Windows/Live/CMakeLists.txt @@ -5,19 +5,17 @@ include_directories(../Common) set(PROC_WINDOWS_SOURCES DebuggerThread.cpp LocalDebugDelegate.cpp - ProcessWindows.cpp - ProcessWindowsLog.cpp - RegisterContextWindows.cpp - TargetThreadWindows.cpp + ProcessWindowsLive.cpp + TargetThreadWindowsLive.cpp ) if (CMAKE_SIZEOF_VOID_P EQUAL 4) set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES} - x86/RegisterContextWindows_x86.cpp + x86/RegisterContextWindowsLive_x86.cpp ) elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) set(PROC_WINDOWS_SOURCES ${PROC_WINDOWS_SOURCES} - x64/RegisterContextWindows_x64.cpp + x64/RegisterContextWindowsLive_x64.cpp ) endif() diff --git a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp index cc661be63590..d058a412c896 100644 --- a/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp +++ b/lldb/source/Plugins/Process/Windows/Live/DebuggerThread.cpp @@ -24,7 +24,7 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/Process.h" -#include "Plugins/Process/Windows/Live/ProcessWindowsLog.h" +#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/raw_ostream.h" diff --git a/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h b/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h index c2eb168f3278..a782597555e1 100644 --- a/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h +++ b/lldb/source/Plugins/Process/Windows/Live/ForwardDecl.h @@ -1,41 +1,41 @@ -//===-- ForwardDecl.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_ForwardDecl_H_ -#define liblldb_Plugins_Process_Windows_ForwardDecl_H_ - -class ProcessWindows; - -#include - -// ExceptionResult is returned by the debug delegate to specify how it processed -// the exception. -enum class ExceptionResult -{ - BreakInDebugger, // Break in the debugger and give the user a chance to interact with - // the program before continuing. - MaskException, // Eat the exception and don't let the application know it occurred. - SendToApplication // Send the exception to the application to be handled as if there were - // no debugger attached. -}; - -namespace lldb_private -{ - -class IDebugDelegate; -class DebuggerThread; -class ExceptionRecord; - -typedef std::shared_ptr DebugDelegateSP; -typedef std::shared_ptr DebuggerThreadSP; -typedef std::shared_ptr ExceptionRecordSP; -typedef std::unique_ptr ExceptionRecordUP; -} - +//===-- ForwardDecl.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_ForwardDecl_H_ +#define liblldb_Plugins_Process_Windows_ForwardDecl_H_ + +#include + +// ExceptionResult is returned by the debug delegate to specify how it processed +// the exception. +enum class ExceptionResult +{ + BreakInDebugger, // Break in the debugger and give the user a chance to interact with + // the program before continuing. + MaskException, // Eat the exception and don't let the application know it occurred. + SendToApplication // Send the exception to the application to be handled as if there were + // no debugger attached. +}; + +namespace lldb_private +{ + +class ProcessWindows; + +class IDebugDelegate; +class DebuggerThread; +class ExceptionRecord; + +typedef std::shared_ptr DebugDelegateSP; +typedef std::shared_ptr DebuggerThreadSP; +typedef std::shared_ptr ExceptionRecordSP; +typedef std::unique_ptr ExceptionRecordUP; +} + #endif \ No newline at end of file diff --git a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp index e47b26e58f8c..a0ac9725c756 100644 --- a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp +++ b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.cpp @@ -1,91 +1,91 @@ -//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LocalDebugDelegate.h" -#include "ProcessWindows.h" - -using namespace lldb; -using namespace lldb_private; - -LocalDebugDelegate::LocalDebugDelegate(ProcessWP process) - : m_process(process) -{ -} - -void -LocalDebugDelegate::OnExitProcess(uint32_t exit_code) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - process->OnExitProcess(exit_code); -} - -void -LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - process->OnDebuggerConnected(image_base); -} - -ExceptionResult -LocalDebugDelegate::OnDebugException(bool first_chance, const ExceptionRecord &record) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - return process->OnDebugException(first_chance, record); - else - return ExceptionResult::MaskException; -} - -void -LocalDebugDelegate::OnCreateThread(const HostThread &thread) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - process->OnCreateThread(thread); -} - -void -LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) -{ - 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 (ProcessWindowsSP process = GetProcessPointer()) - process->OnLoadDll(module_spec, module_addr); -} - -void -LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - process->OnUnloadDll(module_addr); -} - -void -LocalDebugDelegate::OnDebugString(const std::string &string) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - process->OnDebugString(string); -} - -void -LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type) -{ - if (ProcessWindowsSP process = GetProcessPointer()) - process->OnDebuggerError(error, type); -} - -ProcessWindowsSP -LocalDebugDelegate::GetProcessPointer() -{ - ProcessSP process = m_process.lock(); - return std::static_pointer_cast(process); -} +//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LocalDebugDelegate.h" +#include "ProcessWindowsLive.h" + +using namespace lldb; +using namespace lldb_private; + +LocalDebugDelegate::LocalDebugDelegate(ProcessWP process) + : m_process(process) +{ +} + +void +LocalDebugDelegate::OnExitProcess(uint32_t exit_code) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + process->OnExitProcess(exit_code); +} + +void +LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + process->OnDebuggerConnected(image_base); +} + +ExceptionResult +LocalDebugDelegate::OnDebugException(bool first_chance, const ExceptionRecord &record) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + return process->OnDebugException(first_chance, record); + else + return ExceptionResult::MaskException; +} + +void +LocalDebugDelegate::OnCreateThread(const HostThread &thread) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + process->OnCreateThread(thread); +} + +void +LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) +{ + if (ProcessWindowsLiveSP 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()) + process->OnLoadDll(module_spec, module_addr); +} + +void +LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + process->OnUnloadDll(module_addr); +} + +void +LocalDebugDelegate::OnDebugString(const std::string &string) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + process->OnDebugString(string); +} + +void +LocalDebugDelegate::OnDebuggerError(const Error &error, uint32_t type) +{ + if (ProcessWindowsLiveSP process = GetProcessPointer()) + process->OnDebuggerError(error, type); +} + +ProcessWindowsLiveSP +LocalDebugDelegate::GetProcessPointer() +{ + ProcessSP process = m_process.lock(); + return std::static_pointer_cast(process); +} diff --git a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h index 8fca78fca76a..ec2f9418142f 100644 --- a/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h +++ b/lldb/source/Plugins/Process/Windows/Live/LocalDebugDelegate.h @@ -1,65 +1,68 @@ -//===-- LocalDebugDelegate.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_LocalDebugDelegate_H_ -#define liblldb_Plugins_Process_Windows_LocalDebugDelegate_H_ - -#include "IDebugDelegate.h" -#include "ProcessWindowsForward.h" - -#include "lldb/lldb-forward.h" - -class ProcessWindows; - -namespace lldb_private -{ -//---------------------------------------------------------------------- -// LocalDebugDelegate -// -// 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 -// additional flexibility provided by this sort of adapter pattern. -// 2) LLDB holds a shared_ptr to the ProcessWindows, and our driver thread -// needs access to it as well. To avoid a race condition, we want to make -// sure that we're also holding onto a shared_ptr. -// lldb_private::Process supports enable_shared_from_this, but that gives us -// a ProcessSP (which is exactly what we are trying to decouple from the -// driver), so this adapter serves as a way to transparently hold the -// ProcessSP while still keeping it decoupled from the driver. -//---------------------------------------------------------------------- -class LocalDebugDelegate : public IDebugDelegate -{ - public: - explicit LocalDebugDelegate(lldb::ProcessWP process); - - 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 lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override; - void OnUnloadDll(lldb::addr_t module_addr) override; - void OnDebugString(const std::string &message) override; - void OnDebuggerError(const Error &error, uint32_t type) override; - - private: - ProcessWindowsSP - GetProcessPointer(); - - lldb::ProcessWP m_process; -}; -} - -#endif +//===-- LocalDebugDelegate.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_LocalDebugDelegate_H_ +#define liblldb_Plugins_Process_Windows_LocalDebugDelegate_H_ + +#include + +#include "IDebugDelegate.h" + +#include "lldb/lldb-forward.h" + +namespace lldb_private +{ + +class ProcessWindowsLive; +typedef std::shared_ptr ProcessWindowsLiveSP; + +//---------------------------------------------------------------------- +// 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: +// +// 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 +// additional flexibility provided by this sort of adapter pattern. +// 2) LLDB holds a shared_ptr to the ProcessWindows, and our driver thread +// needs access to it as well. To avoid a race condition, we want to make +// sure that we're also holding onto a shared_ptr. +// lldb_private::Process supports enable_shared_from_this, but that gives us +// a ProcessSP (which is exactly what we are trying to decouple from the +// driver), so this adapter serves as a way to transparently hold the +// ProcessSP while still keeping it decoupled from the driver. +//---------------------------------------------------------------------- +class LocalDebugDelegate : public IDebugDelegate +{ + public: + explicit LocalDebugDelegate(lldb::ProcessWP process); + + 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 lldb_private::ModuleSpec &module_spec, lldb::addr_t module_addr) override; + void OnUnloadDll(lldb::addr_t module_addr) override; + void OnDebugString(const std::string &message) override; + void OnDebuggerError(const Error &error, uint32_t type) override; + + private: + ProcessWindowsLiveSP + GetProcessPointer(); + + lldb::ProcessWP m_process; +}; +} + +#endif diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsForward.h b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsForward.h deleted file mode 100644 index 666012a7a5a8..000000000000 --- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsForward.h +++ /dev/null @@ -1,19 +0,0 @@ -//===-- ProcessWindows.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_ProcessWindowsForward_H_ -#define liblldb_Plugins_Process_Windows_ProcessWindowsForward_H_ - -#include - -class ProcessWindows; - -typedef std::shared_ptr ProcessWindowsSP; - -#endif \ No newline at end of file diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp similarity index 90% rename from lldb/source/Plugins/Process/Windows/Live/ProcessWindows.cpp rename to lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp index b173645056d7..819c4dd43756 100644 --- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp @@ -1,4 +1,4 @@ -//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===// +//===-- ProcessWindowsLive.cpp ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -39,14 +39,13 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" -#include "Plugins/Process/Windows/Live/ProcessWindowsForward.h" -#include "Plugins/Process/Windows/live/ProcessWindowsLog.h" +#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h" #include "DebuggerThread.h" #include "ExceptionRecord.h" #include "LocalDebugDelegate.h" -#include "ProcessWindows.h" -#include "TargetThreadWindows.h" +#include "ProcessWindowsLive.h" +#include "TargetThreadWindowsLive.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -122,13 +121,13 @@ class ProcessWindowsData // Static functions. ProcessSP -ProcessWindows::CreateInstance(lldb::TargetSP target_sp, Listener &listener, const FileSpec *) +ProcessWindowsLive::CreateInstance(lldb::TargetSP target_sp, Listener &listener, const FileSpec *) { - return ProcessSP(new ProcessWindows(target_sp, listener)); + return ProcessSP(new ProcessWindowsLive(target_sp, listener)); } void -ProcessWindows::Initialize() +ProcessWindowsLive::Initialize() { static std::once_flag g_once_flag; @@ -143,56 +142,35 @@ ProcessWindows::Initialize() //------------------------------------------------------------------------------ // Constructors and destructors. -ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, Listener &listener) - : lldb_private::Process(target_sp, listener) +ProcessWindowsLive::ProcessWindowsLive(lldb::TargetSP target_sp, Listener &listener) + : lldb_private::ProcessWindows(target_sp, listener) { } -ProcessWindows::~ProcessWindows() +ProcessWindowsLive::~ProcessWindowsLive() { } void -ProcessWindows::Terminate() +ProcessWindowsLive::Terminate() { } lldb_private::ConstString -ProcessWindows::GetPluginNameStatic() +ProcessWindowsLive::GetPluginNameStatic() { static ConstString g_name("windows"); return g_name; } const char * -ProcessWindows::GetPluginDescriptionStatic() +ProcessWindowsLive::GetPluginDescriptionStatic() { return "Process plugin for Windows"; } -size_t -ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error) -{ - error.SetErrorString("GetSTDOUT unsupported on Windows"); - return 0; -} - -size_t -ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error) -{ - error.SetErrorString("GetSTDERR unsupported on Windows"); - return 0; -} - -size_t -ProcessWindows::PutSTDIN(const char *buf, size_t buf_size, Error &error) -{ - error.SetErrorString("PutSTDIN unsupported on Windows"); - return 0; -} - Error -ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) +ProcessWindowsLive::EnableBreakpointSite(BreakpointSite *bp_site) { WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite called with bp_site 0x%p " "(id=%d, addr=0x%x)", @@ -207,7 +185,7 @@ ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) } Error -ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) +ProcessWindowsLive::DisableBreakpointSite(BreakpointSite *bp_site) { WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite called with bp_site 0x%p " "(id=%d, addr=0x%x)", @@ -223,7 +201,7 @@ ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) } bool -ProcessWindows::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) +ProcessWindowsLive::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { // Add all the threads that were previously running and for which we did not detect a thread // exited event. @@ -255,7 +233,7 @@ ProcessWindows::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_th // Also add all the threads that are new since the last time we broke into the debugger. for (const auto &thread_info : m_session_data->m_new_threads) { - ThreadSP thread(new TargetThreadWindows(*this, thread_info.second)); + ThreadSP thread(new TargetThreadWindowsLive(*this, thread_info.second)); thread->SetID(thread_info.first); new_thread_list.AddThread(thread); ++new_size; @@ -273,8 +251,8 @@ ProcessWindows::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_th } Error -ProcessWindows::DoLaunch(Module *exe_module, - ProcessLaunchInfo &launch_info) +ProcessWindowsLive::DoLaunch(Module *exe_module, + ProcessLaunchInfo &launch_info) { // Even though m_session_data is accessed here, it is before a debugger thread has been // kicked off. So there's no race conditions, and it shouldn't be necessary to acquire @@ -333,7 +311,7 @@ ProcessWindows::DoLaunch(Module *exe_module, } Error -ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) +ProcessWindowsLive::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) { m_session_data.reset(new ProcessWindowsData(!attach_info.GetContinueOnceAttached())); @@ -374,7 +352,7 @@ ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo } Error -ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess &process) +ProcessWindowsLive::WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess &process) { Error result; WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_BREAKPOINTS, "WaitForDebuggerConnection Waiting for loader breakpoint."); @@ -392,7 +370,7 @@ ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess } Error -ProcessWindows::DoResume() +ProcessWindowsLive::DoResume() { llvm::sys::ScopedLock lock(m_mutex); Error error; @@ -419,7 +397,7 @@ ProcessWindows::DoResume() for (int i = 0; i < m_thread_list.GetSize(); ++i) { - auto thread = std::static_pointer_cast( + auto thread = std::static_pointer_cast( m_thread_list.GetThreadAtIndex(i)); thread->DoResume(); } @@ -439,19 +417,19 @@ ProcessWindows::DoResume() // ProcessInterface protocol. lldb_private::ConstString -ProcessWindows::GetPluginName() +ProcessWindowsLive::GetPluginName() { return GetPluginNameStatic(); } uint32_t -ProcessWindows::GetPluginVersion() +ProcessWindowsLive::GetPluginVersion() { return 1; } Error -ProcessWindows::DoDetach(bool keep_stopped) +ProcessWindowsLive::DoDetach(bool keep_stopped) { DebuggerThreadSP debugger_thread; StateType private_state; @@ -500,7 +478,7 @@ ProcessWindows::DoDetach(bool keep_stopped) } Error -ProcessWindows::DoDestroy() +ProcessWindowsLive::DoDestroy() { DebuggerThreadSP debugger_thread; StateType private_state; @@ -544,7 +522,7 @@ ProcessWindows::DoDestroy() } void -ProcessWindows::RefreshStateAfterStop() +ProcessWindowsLive::RefreshStateAfterStop() { llvm::sys::ScopedLock lock(m_mutex); @@ -626,7 +604,7 @@ ProcessWindows::RefreshStateAfterStop() } bool -ProcessWindows::IsAlive() +ProcessWindowsLive::IsAlive() { StateType state = GetPrivateState(); switch (state) @@ -643,7 +621,7 @@ ProcessWindows::IsAlive() } Error -ProcessWindows::DoHalt(bool &caused_stop) +ProcessWindowsLive::DoHalt(bool &caused_stop) { Error error; StateType state = GetPrivateState(); @@ -663,14 +641,15 @@ ProcessWindows::DoHalt(bool &caused_stop) return error; } -void ProcessWindows::DidLaunch() +void +ProcessWindowsLive::DidLaunch() { ArchSpec arch_spec; DidAttach(arch_spec); } void -ProcessWindows::DidAttach(ArchSpec &arch_spec) +ProcessWindowsLive::DidAttach(ArchSpec &arch_spec) { llvm::sys::ScopedLock lock(m_mutex); @@ -680,10 +659,10 @@ ProcessWindows::DidAttach(ArchSpec &arch_spec) } size_t -ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, - void *buf, - size_t size, - Error &error) +ProcessWindowsLive::DoReadMemory(lldb::addr_t vm_addr, + void *buf, + size_t size, + Error &error) { llvm::sys::ScopedLock lock(m_mutex); @@ -704,7 +683,7 @@ ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, } size_t -ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) +ProcessWindowsLive::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) { llvm::sys::ScopedLock lock(m_mutex); WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size, vm_addr); @@ -730,7 +709,7 @@ ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size } Error -ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) +ProcessWindowsLive::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Error error; llvm::sys::ScopedLock lock(m_mutex); @@ -776,20 +755,8 @@ ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info return error; } -lldb::addr_t -ProcessWindows::GetImageInfoAddress() -{ - Target &target = GetTarget(); - ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile(); - Address addr = obj_file->GetImageInfoAddress(&target); - if (addr.IsValid()) - return addr.GetLoadAddress(&target); - else - return LLDB_INVALID_ADDRESS; -} - bool -ProcessWindows::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) +ProcessWindowsLive::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) { if (plugin_specified_by_name) return true; @@ -803,7 +770,7 @@ ProcessWindows::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name } void -ProcessWindows::OnExitProcess(uint32_t exit_code) +ProcessWindowsLive::OnExitProcess(uint32_t exit_code) { // No need to acquire the lock since m_session_data isn't accessed. WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %u exited with code %u", GetID(), exit_code); @@ -822,7 +789,7 @@ ProcessWindows::OnExitProcess(uint32_t exit_code) } void -ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) +ProcessWindowsLive::OnDebuggerConnected(lldb::addr_t image_base) { DebuggerThreadSP debugger = m_session_data->m_debugger; @@ -868,7 +835,7 @@ ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) } ExceptionResult -ProcessWindows::OnDebugException(bool first_chance, const ExceptionRecord &record) +ProcessWindowsLive::OnDebugException(bool first_chance, const ExceptionRecord &record) { llvm::sys::ScopedLock lock(m_mutex); @@ -933,7 +900,7 @@ ProcessWindows::OnDebugException(bool first_chance, const ExceptionRecord &recor } void -ProcessWindows::OnCreateThread(const HostThread &new_thread) +ProcessWindowsLive::OnCreateThread(const HostThread &new_thread) { llvm::sys::ScopedLock lock(m_mutex); const HostThreadWindows &wnew_thread = new_thread.GetNativeThread(); @@ -941,7 +908,7 @@ ProcessWindows::OnCreateThread(const HostThread &new_thread) } void -ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) +ProcessWindowsLive::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) { llvm::sys::ScopedLock lock(m_mutex); @@ -960,7 +927,7 @@ ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) } void -ProcessWindows::OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) +ProcessWindowsLive::OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) { // Confusingly, there is no Target::AddSharedModule. Instead, calling GetSharedModule() with // a new module will add it to the module list and return a corresponding ModuleSP. @@ -975,7 +942,7 @@ ProcessWindows::OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_add } void -ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) +ProcessWindowsLive::OnUnloadDll(lldb::addr_t module_addr) { Address resolved_addr; if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) @@ -991,12 +958,12 @@ ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) } void -ProcessWindows::OnDebugString(const std::string &string) +ProcessWindowsLive::OnDebugString(const std::string &string) { } void -ProcessWindows::OnDebuggerError(const Error &error, uint32_t type) +ProcessWindowsLive::OnDebuggerError(const Error &error, uint32_t type) { llvm::sys::ScopedLock lock(m_mutex); @@ -1018,4 +985,4 @@ ProcessWindows::OnDebuggerError(const Error &error, uint32_t type) error.GetError(), error.AsCString()); return; } -} \ No newline at end of file +} diff --git a/lldb/source/Plugins/Process/Windows/Live/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h similarity index 84% rename from lldb/source/Plugins/Process/Windows/Live/ProcessWindows.h rename to lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h index fa8d7f102bc9..2429f873c823 100644 --- a/lldb/source/Plugins/Process/Windows/Live/ProcessWindows.h +++ b/lldb/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h @@ -1,4 +1,4 @@ -//===-- ProcessWindows.h ----------------------------------------*- C++ -*-===// +//===-- ProcessWindowsLive.h ------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Plugins_Process_Windows_ProcessWindows_H_ -#define liblldb_Plugins_Process_Windows_ProcessWindows_H_ +#ifndef liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_ +#define liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_ // C Includes @@ -26,15 +26,16 @@ #include "llvm/Support/Mutex.h" +#include "plugins/Process/Windows/Common/ProcessWindows.h" + class ProcessMonitor; namespace lldb_private { class HostProcess; class ProcessWindowsData; -} -class ProcessWindows : public lldb_private::Process, public lldb_private::IDebugDelegate +class ProcessWindowsLive : public lldb_private::ProcessWindows, public lldb_private::IDebugDelegate { public: //------------------------------------------------------------------ @@ -60,19 +61,15 @@ public: //------------------------------------------------------------------ // Constructors and destructors //------------------------------------------------------------------ - ProcessWindows(lldb::TargetSP target_sp, - lldb_private::Listener &listener); + ProcessWindowsLive(lldb::TargetSP target_sp, + lldb_private::Listener &listener); - ~ProcessWindows(); + ~ProcessWindowsLive(); // lldb_private::Process overrides lldb_private::ConstString GetPluginName() override; uint32_t GetPluginVersion() override; - 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; - lldb_private::Error EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; lldb_private::Error DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; @@ -88,7 +85,6 @@ public: void DidAttach(lldb_private::ArchSpec &arch_spec) override; void RefreshStateAfterStop() override; - lldb::addr_t GetImageInfoAddress() override; bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override; bool @@ -124,4 +120,6 @@ public: std::unique_ptr m_session_data; }; -#endif // liblldb_Plugins_Process_Windows_ProcessWindows_H_ +} + +#endif // liblldb_Plugins_Process_Windows_Live_ProcessWindowsLive_H_ diff --git a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp similarity index 77% rename from lldb/source/Plugins/Process/Windows/Live/TargetThreadWindows.cpp rename to lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp index e849a920cd0b..52b32716e674 100644 --- a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.cpp @@ -1,4 +1,4 @@ -//===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===// +//===-- TargetThreadWindowsLive.cpp------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,33 +16,33 @@ #include "lldb/Host/windows/windows.h" #include "lldb/Target/RegisterContext.h" -#include "TargetThreadWindows.h" +#include "TargetThreadWindowsLive.h" #include "ProcessWindows.h" #include "ProcessWindowsLog.h" #include "UnwindLLDB.h" #if defined(_WIN64) -#include "x64/RegisterContextWindows_x64.h" +#include "x64/RegisterContextWindowsLive_x64.h" #else -#include "x86/RegisterContextWindows_x86.h" +#include "x86/RegisterContextWindowsLive_x86.h" #endif using namespace lldb; using namespace lldb_private; -TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread) - : Thread(process, thread.GetNativeThread().GetThreadId()) +TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread) + : TargetThreadWindows(process, thread) , m_host_thread(thread) { } -TargetThreadWindows::~TargetThreadWindows() +TargetThreadWindowsLive::~TargetThreadWindowsLive() { DestroyThread(); } void -TargetThreadWindows::RefreshStateAfterStop() +TargetThreadWindowsLive::RefreshStateAfterStop() { ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle()); SetState(eStateStopped); @@ -50,17 +50,17 @@ TargetThreadWindows::RefreshStateAfterStop() } void -TargetThreadWindows::WillResume(lldb::StateType resume_state) +TargetThreadWindowsLive::WillResume(lldb::StateType resume_state) { } void -TargetThreadWindows::DidStop() +TargetThreadWindowsLive::DidStop() { } RegisterContextSP -TargetThreadWindows::GetRegisterContext() +TargetThreadWindowsLive::GetRegisterContext() { if (!m_reg_context_sp) m_reg_context_sp = CreateRegisterContextForFrameIndex(0); @@ -69,13 +69,13 @@ TargetThreadWindows::GetRegisterContext() } RegisterContextSP -TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) +TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame) { return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex()); } RegisterContextSP -TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) +TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx) { if (!m_reg_context_sp) { @@ -86,12 +86,12 @@ TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) #if defined(_WIN64) // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64 #else - m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx)); + 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 RegisterContextWindows_x64(*this, idx)); + 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 @@ -103,14 +103,14 @@ TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) } bool -TargetThreadWindows::CalculateStopInfo() +TargetThreadWindowsLive::CalculateStopInfo() { SetStopInfo(m_stop_info_sp); return true; } Unwind * -TargetThreadWindows::GetUnwinder() +TargetThreadWindowsLive::GetUnwinder() { // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK. if (m_unwinder_ap.get() == NULL) @@ -119,7 +119,7 @@ TargetThreadWindows::GetUnwinder() } bool -TargetThreadWindows::DoResume() +TargetThreadWindowsLive::DoResume() { StateType resume_state = GetTemporaryResumeState(); StateType current_state = GetState(); diff --git a/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h new file mode 100644 index 000000000000..15262b9e9423 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Live/TargetThreadWindowsLive.h @@ -0,0 +1,55 @@ +//===-- 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/lldb-forward.h" +#include "lldb/Host/HostThread.h" +#include "lldb/Target/Thread.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 diff --git a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindows_x86.cpp b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp similarity index 52% rename from lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindows_x86.cpp rename to lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp index 36223a50a3b0..f7eeae529ab1 100644 --- a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindows_x86.cpp +++ b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.cpp @@ -1,241 +1,157 @@ -//===-- RegisterContextWindows_x86.h ----------------------------*- 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 "ProcessWindowsLog.h" -#include "RegisterContext_x86.h" -#include "RegisterContextWindows_x86.h" -#include "TargetThreadWindows.h" - -#include "llvm/ADT/STLExtras.h" - -using namespace lldb; -using namespace lldb_private; - -#define DEFINE_GPR(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatHexUppercase -#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 4, 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 -{ - eRegisterIndexEax, - eRegisterIndexEbx, - eRegisterIndexEcx, - eRegisterIndexEdx, - eRegisterIndexEdi, - eRegisterIndexEsi, - eRegisterIndexEbp, - eRegisterIndexEsp, - eRegisterIndexEip, - eRegisterIndexEflags -}; - -// Array of all register information supported by Windows x86 -RegisterInfo g_register_infos[] = -{ -// Macro auto defines most stuff eh_frame DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS -// ============================== ======================= =================== ========================= =================== ================= ========== =============== - { DEFINE_GPR(eax, nullptr), { ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_eax_i386 }, nullptr, nullptr}, - { DEFINE_GPR(ebx, nullptr), { ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ebx_i386 }, nullptr, nullptr}, - { DEFINE_GPR(ecx, nullptr), { ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_ecx_i386 }, nullptr, nullptr}, - { DEFINE_GPR(edx, nullptr), { ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edx_i386 }, nullptr, nullptr}, - { DEFINE_GPR(edi, nullptr), { ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_edi_i386 }, nullptr, nullptr}, - { DEFINE_GPR(esi, nullptr), { ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_esi_i386 }, nullptr, nullptr}, - { DEFINE_GPR(ebp, "fp"), { ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, lldb_ebp_i386 }, nullptr, nullptr}, - { DEFINE_GPR(esp, "sp"), { ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, lldb_esp_i386 }, nullptr, nullptr}, - { DEFINE_GPR(eip, "pc"), { ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, lldb_eip_i386 }, nullptr, nullptr}, - { DEFINE_GPR_BIN(eflags, "flags"), { ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, lldb_eflags_i386}, nullptr, nullptr}, -}; - -// Array of lldb register numbers used to define the set of all General Purpose Registers -uint32_t g_gpr_reg_indices[] = -{ - eRegisterIndexEax, - eRegisterIndexEbx, - eRegisterIndexEcx, - eRegisterIndexEdx, - eRegisterIndexEdi, - eRegisterIndexEsi, - eRegisterIndexEbp, - eRegisterIndexEsp, - eRegisterIndexEip, - eRegisterIndexEflags -}; - -RegisterSet g_register_sets[] = { - {"General Purpose Registers", "gpr", llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices}, -}; -} - -//------------------------------------------------------------------ -// Constructors and Destructors -//------------------------------------------------------------------ -RegisterContextWindows_x86::RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx) - : RegisterContextWindows(thread, concrete_frame_idx) -{ -} - -RegisterContextWindows_x86::~RegisterContextWindows_x86() -{ -} - -size_t -RegisterContextWindows_x86::GetRegisterCount() -{ - return llvm::array_lengthof(g_register_infos); -} - -const RegisterInfo * -RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg) -{ - return &g_register_infos[reg]; -} - -size_t -RegisterContextWindows_x86::GetRegisterSetCount() -{ - return llvm::array_lengthof(g_register_sets); -} - -const RegisterSet * -RegisterContextWindows_x86::GetRegisterSet(size_t reg_set) -{ - return &g_register_sets[reg_set]; -} - -bool -RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) -{ - if (!CacheAllRegisterValues()) - return false; - - uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - switch (reg) - { - case lldb_eax_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EAX", m_context.Eax); - reg_value.SetUInt32(m_context.Eax); - break; - case lldb_ebx_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBX", m_context.Ebx); - reg_value.SetUInt32(m_context.Ebx); - break; - case lldb_ecx_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ECX", m_context.Ecx); - reg_value.SetUInt32(m_context.Ecx); - break; - case lldb_edx_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDX", m_context.Edx); - reg_value.SetUInt32(m_context.Edx); - break; - case lldb_edi_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDI", m_context.Edi); - reg_value.SetUInt32(m_context.Edi); - break; - case lldb_esi_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESI", m_context.Esi); - reg_value.SetUInt32(m_context.Esi); - break; - case lldb_ebp_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBP", m_context.Ebp); - reg_value.SetUInt32(m_context.Ebp); - break; - case lldb_esp_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESP", m_context.Esp); - reg_value.SetUInt32(m_context.Esp); - break; - case lldb_eip_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EIP", m_context.Eip); - reg_value.SetUInt32(m_context.Eip); - break; - case lldb_eflags_i386: - WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EFLAGS", m_context.EFlags); - reg_value.SetUInt32(m_context.EFlags); - break; - default: - WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg); - break; - } - return true; -} - -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(m_thread); - return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); -} +//===-- 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/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 "ProcessWindowsLog.h" +#include "RegisterContextWindowsLive_x86.h" +#include "TargetThreadWindows.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::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) +{ + if (!CacheAllRegisterValues()) + return false; + + uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + switch (reg) + { + case lldb_eax_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EAX", m_context.Eax); + reg_value.SetUInt32(m_context.Eax); + break; + case lldb_ebx_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBX", m_context.Ebx); + reg_value.SetUInt32(m_context.Ebx); + break; + case lldb_ecx_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ECX", m_context.Ecx); + reg_value.SetUInt32(m_context.Ecx); + break; + case lldb_edx_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDX", m_context.Edx); + reg_value.SetUInt32(m_context.Edx); + break; + case lldb_edi_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EDI", m_context.Edi); + reg_value.SetUInt32(m_context.Edi); + break; + case lldb_esi_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESI", m_context.Esi); + reg_value.SetUInt32(m_context.Esi); + break; + case lldb_ebp_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EBP", m_context.Ebp); + reg_value.SetUInt32(m_context.Ebp); + break; + case lldb_esp_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from ESP", m_context.Esp); + reg_value.SetUInt32(m_context.Esp); + break; + case lldb_eip_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EIP", m_context.Eip); + reg_value.SetUInt32(m_context.Eip); + break; + case lldb_eflags_i386: + WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%x from EFLAGS", m_context.EFlags); + reg_value.SetUInt32(m_context.EFlags); + break; + default: + WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg); + break; + } + return true; +} + + +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(m_thread); + return ::SetThreadContext(wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context); +} + +} // namespace lldb_private diff --git a/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h new file mode 100644 index 000000000000..e44fd958da47 --- /dev/null +++ b/lldb/source/Plugins/Process/Windows/Live/x86/RegisterContextWindowsLive_x86.h @@ -0,0 +1,38 @@ +//===-- 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 "lldb/lldb-forward.h" +#include "../../Common/x86/RegisterContextWindows_x86.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 ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) override; +}; + +} + +#endif // #ifndef liblldb_RegisterContextWindowsLive_x86_H_ diff --git a/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp b/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp index 2ffdd1bcefcf..c27ddb2a7051 100644 --- a/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp +++ b/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp @@ -123,7 +123,7 @@ ProcessWinMiniDump::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_ ProcessWinMiniDump::ProcessWinMiniDump(lldb::TargetSP target_sp, Listener &listener, const FileSpec &core_file) : - Process(target_sp, listener), + ProcessWindows(target_sp, listener), m_data_up(new Data) { m_data_up->m_core_file = core_file; @@ -285,18 +285,6 @@ ProcessWinMiniDump::Initialize() }); } -lldb::addr_t -ProcessWinMiniDump::GetImageInfoAddress() -{ - Target *target = &GetTarget(); - ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); - Address addr = obj_file->GetImageInfoAddress(target); - - if (addr.IsValid()) - return addr.GetLoadAddress(target); - return LLDB_INVALID_ADDRESS; -} - ArchSpec ProcessWinMiniDump::GetArchitecture() { diff --git a/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h b/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h index 7555a03c5418..c76179172e6a 100644 --- a/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h +++ b/lldb/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h @@ -17,9 +17,11 @@ #include "lldb/Core/Error.h" #include "lldb/Target/Process.h" +#include "Plugins/Process/Windows/Common/ProcessWindows.h" + struct ThreadData; -class ProcessWinMiniDump : public lldb_private::Process +class ProcessWinMiniDump : public lldb_private::ProcessWindows { public: static lldb::ProcessSP @@ -79,9 +81,6 @@ public: size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override; - lldb::addr_t - GetImageInfoAddress() override; - lldb_private::ArchSpec GetArchitecture(); diff --git a/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.cpp b/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.cpp index 8b07c1120a9e..2185cccfb9af 100644 --- a/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.cpp +++ b/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.cpp @@ -1,146 +1,146 @@ -//===-- RegisterContextWindowsMiniDump.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 "RegisterContextWindowsMiniDump.h" - -#include "llvm/ADT/STLExtras.h" - -using namespace lldb; -using namespace lldb_private; - -// This is a do-nothing stub implementation for now. - -RegisterContextWindowsMiniDump::RegisterContextWindowsMiniDump(Thread &thread, uint32_t concrete_frame_idx) - : RegisterContext(thread, concrete_frame_idx) -{ -} - -RegisterContextWindowsMiniDump::~RegisterContextWindowsMiniDump() -{ -} - -void -RegisterContextWindowsMiniDump::InvalidateAllRegisters() -{ -} - -size_t -RegisterContextWindowsMiniDump::GetRegisterCount() -{ - return 0; -} - -const RegisterInfo * -RegisterContextWindowsMiniDump::GetRegisterInfoAtIndex(size_t reg) -{ - return nullptr; -} - -size_t -RegisterContextWindowsMiniDump::GetRegisterSetCount() -{ - return 0; -} - -const RegisterSet * -RegisterContextWindowsMiniDump::GetRegisterSet(size_t reg_set) -{ - return nullptr; -} - -bool -RegisterContextWindowsMiniDump::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) -{ - return false; -} - -bool -RegisterContextWindowsMiniDump::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) -{ - return false; -} - -bool -RegisterContextWindowsMiniDump::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) -{ - return false; -} - -bool -RegisterContextWindowsMiniDump::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) -{ - return false; -} - -uint32_t -RegisterContextWindowsMiniDump::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; -} - -uint32_t -RegisterContextWindowsMiniDump::NumSupportedHardwareBreakpoints() -{ - // Support for hardware breakpoints not yet implemented. - return 0; -} - -uint32_t -RegisterContextWindowsMiniDump::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) -{ - return 0; -} - -bool -RegisterContextWindowsMiniDump::ClearHardwareBreakpoint(uint32_t hw_idx) -{ - return false; -} - -uint32_t -RegisterContextWindowsMiniDump::NumSupportedHardwareWatchpoints() -{ - // Support for hardware watchpoints not yet implemented. - return 0; -} - -uint32_t -RegisterContextWindowsMiniDump::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) -{ - return 0; -} - -bool -RegisterContextWindowsMiniDump::ClearHardwareWatchpoint(uint32_t hw_index) -{ - return false; -} - -bool -RegisterContextWindowsMiniDump::HardwareSingleStep(bool enable) -{ - return false; -} +//===-- RegisterContextWindowsMiniDump.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 "RegisterContextWindowsMiniDump.h" + +#include "llvm/ADT/STLExtras.h" + +using namespace lldb; +using namespace lldb_private; + +// This is a do-nothing stub implementation for now. + +RegisterContextWindowsMiniDump::RegisterContextWindowsMiniDump(Thread &thread, uint32_t concrete_frame_idx) + : RegisterContextWindows(thread, concrete_frame_idx) +{ +} + +RegisterContextWindowsMiniDump::~RegisterContextWindowsMiniDump() +{ +} + +void +RegisterContextWindowsMiniDump::InvalidateAllRegisters() +{ +} + +size_t +RegisterContextWindowsMiniDump::GetRegisterCount() +{ + return 0; +} + +const RegisterInfo * +RegisterContextWindowsMiniDump::GetRegisterInfoAtIndex(size_t reg) +{ + return nullptr; +} + +size_t +RegisterContextWindowsMiniDump::GetRegisterSetCount() +{ + return 0; +} + +const RegisterSet * +RegisterContextWindowsMiniDump::GetRegisterSet(size_t reg_set) +{ + return nullptr; +} + +bool +RegisterContextWindowsMiniDump::ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value) +{ + return false; +} + +bool +RegisterContextWindowsMiniDump::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) +{ + return false; +} + +bool +RegisterContextWindowsMiniDump::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) +{ + return false; +} + +bool +RegisterContextWindowsMiniDump::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) +{ + return false; +} + +uint32_t +RegisterContextWindowsMiniDump::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; +} + +uint32_t +RegisterContextWindowsMiniDump::NumSupportedHardwareBreakpoints() +{ + // Support for hardware breakpoints not yet implemented. + return 0; +} + +uint32_t +RegisterContextWindowsMiniDump::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) +{ + return 0; +} + +bool +RegisterContextWindowsMiniDump::ClearHardwareBreakpoint(uint32_t hw_idx) +{ + return false; +} + +uint32_t +RegisterContextWindowsMiniDump::NumSupportedHardwareWatchpoints() +{ + // Support for hardware watchpoints not yet implemented. + return 0; +} + +uint32_t +RegisterContextWindowsMiniDump::SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write) +{ + return 0; +} + +bool +RegisterContextWindowsMiniDump::ClearHardwareWatchpoint(uint32_t hw_index) +{ + return false; +} + +bool +RegisterContextWindowsMiniDump::HardwareSingleStep(bool enable) +{ + return false; +} diff --git a/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.h b/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.h index 5c6e2408bf11..5c7830c4553f 100644 --- a/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.h +++ b/lldb/source/Plugins/Process/Windows/MiniDump/RegisterContextWindowsMiniDump.h @@ -1,73 +1,75 @@ -//===-- RegisterContextWindowsMiniDump.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_RegisterContextWindowsMiniDump_H_ -#define liblldb_RegisterContextWindowsMiniDump_H_ - -#include "lldb/lldb-forward.h" -#include "lldb/Target/RegisterContext.h" - - -namespace lldb_private -{ - -class Thread; - -class RegisterContextWindowsMiniDump : public lldb_private::RegisterContext -{ - public: - RegisterContextWindowsMiniDump(Thread &thread, uint32_t concrete_frame_idx); - - virtual ~RegisterContextWindowsMiniDump(); - - void - InvalidateAllRegisters() override; - - 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; - - 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; - - 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; -}; - -} - -#endif // #ifndef liblldb_RegisterContextWindowsMiniDump_H_ +//===-- RegisterContextWindowsMiniDump.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_RegisterContextWindowsMiniDump_H_ +#define liblldb_RegisterContextWindowsMiniDump_H_ + +#include "lldb/lldb-forward.h" +#include "lldb/Target/RegisterContext.h" + +#include "Plugins/Process/Windows/Common/RegisterContextWindows.h" + + +namespace lldb_private +{ + +class Thread; + +class RegisterContextWindowsMiniDump : public lldb_private::RegisterContextWindows +{ + public: + RegisterContextWindowsMiniDump(Thread &thread, uint32_t concrete_frame_idx); + + virtual ~RegisterContextWindowsMiniDump(); + + void + InvalidateAllRegisters() override; + + 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; + + 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; + + 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; +}; + +} + +#endif // #ifndef liblldb_RegisterContextWindowsMiniDump_H_