summaryrefslogtreecommitdiff
path: root/source/Plugins/Process
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process')
-rw-r--r--source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp2
-rw-r--r--source/Plugins/Process/Darwin/MachException.cpp35
-rw-r--r--source/Plugins/Process/Darwin/NativeProcessDarwin.h30
-rw-r--r--source/Plugins/Process/FreeBSD/FreeBSDThread.cpp29
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp16
-rw-r--r--source/Plugins/Process/FreeBSD/POSIXStopInfo.h13
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp26
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp6
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h2
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp46
-rw-r--r--source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h2
-rw-r--r--source/Plugins/Process/Linux/CMakeLists.txt3
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp282
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h9
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp16
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.h19
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp22
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h3
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp34
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h3
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp26
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h6
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp801
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h149
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp14
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h3
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp120
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h8
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp42
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h11
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h2
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp2
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp117
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h10
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp4
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h4
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp11
-rw-r--r--source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h3
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp36
-rw-r--r--source/Plugins/Process/NetBSD/NativeThreadNetBSD.h4
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/Utility/DynamicRegisterInfo.cpp6
-rw-r--r--source/Plugins/Process/Utility/InferiorCallPOSIX.cpp12
-rw-r--r--source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp4
-rw-r--r--source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp4
-rw-r--r--source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h2
-rw-r--r--source/Plugins/Process/Utility/RegisterContextLLDB.cpp8
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_arm.cpp16
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_i386.cpp12
-rw-r--r--source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp12
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp216
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h82
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp22
-rw-r--r--source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h6
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_mips.h5
-rw-r--r--source/Plugins/Process/Utility/RegisterContext_x86.h39
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoInterface.h5
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp66
-rw-r--r--source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h32
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_i386.h18
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_ppc64le.h476
-rw-r--r--source/Plugins/Process/Utility/RegisterInfos_x86_64.h27
-rw-r--r--source/Plugins/Process/Utility/StopInfoMachException.cpp1
-rw-r--r--source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp10
-rw-r--r--source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h210
-rw-r--r--source/Plugins/Process/elf-core/CMakeLists.txt2
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.cpp496
-rw-r--r--source/Plugins/Process/elf-core/ProcessElfCore.h24
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp2
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp4
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp5
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp8
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h8
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp132
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h49
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp4
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp4
-rw-r--r--source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h7
-rw-r--r--source/Plugins/Process/elf-core/RegisterUtilities.cpp39
-rw-r--r--source/Plugins/Process/elf-core/RegisterUtilities.h110
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.cpp44
-rw-r--r--source/Plugins/Process/elf-core/ThreadElfCore.h29
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp46
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h10
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp49
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h4
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp7
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp329
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h29
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp5
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp2
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp24
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h9
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp1
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp2
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp2
-rw-r--r--source/Plugins/Process/minidump/MinidumpParser.h3
-rw-r--r--source/Plugins/Process/minidump/ProcessMinidump.h8
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.cpp14
-rw-r--r--source/Plugins/Process/minidump/ThreadMinidump.h2
106 files changed, 3436 insertions, 1376 deletions
diff --git a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
index c6daf6ccea6e..6b3d5f6c117f 100644
--- a/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
+++ b/source/Plugins/Process/Darwin/DarwinProcessLauncher.cpp
@@ -144,7 +144,7 @@ static Status ForkChildForPTraceDebugging(const char *path, char const *argv[],
// Use a fork that ties the child process's stdin/out/err to a pseudo
// terminal so we can read it in our MachProcess::STDIOThread
// as unbuffered io.
- lldb_utility::PseudoTerminal pty;
+ PseudoTerminal pty;
char fork_error[256];
memset(fork_error, 0, sizeof(fork_error));
*pid = static_cast<::pid_t>(pty.Fork(fork_error, sizeof(fork_error)));
diff --git a/source/Plugins/Process/Darwin/MachException.cpp b/source/Plugins/Process/Darwin/MachException.cpp
index 7d956dfc6506..9f5920753d68 100644
--- a/source/Plugins/Process/Darwin/MachException.cpp
+++ b/source/Plugins/Process/Darwin/MachException.cpp
@@ -57,11 +57,6 @@ extern "C" kern_return_t catch_mach_exception_raise_state_identity(
extern "C" boolean_t mach_exc_server(mach_msg_header_t *InHeadP,
mach_msg_header_t *OutHeadP);
-// Any access to the g_message variable should be done by locking the
-// g_message_mutex first, using the g_message variable, then unlocking
-// the g_message_mutex. See MachException::Message::CatchExceptionRaise()
-// for sample code.
-
static MachException::Data *g_message = NULL;
extern "C" kern_return_t catch_mach_exception_raise_state(
@@ -131,33 +126,6 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port,
return KERN_FAILURE;
}
-#if 0
-void
-MachException::Message::Dump(Stream &stream) const
-{
- stream.Printf("exc_msg { bits = 0x%8.8x size = 0x%8.8x remote-port = "
- "0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
- "id = 0x%8.8x }\n",
- exc_msg.hdr.msgh_bits,
- exc_msg.hdr.msgh_size,
- exc_msg.hdr.msgh_remote_port,
- exc_msg.hdr.msgh_local_port,
- exc_msg.hdr.msgh_reserved,
- exc_msg.hdr.msgh_id);
-
- stream.Printf("reply_msg { bits = 0x%8.8x size = 0x%8.8x remote-port "
- "= 0x%8.8x local-port = 0x%8.8x reserved = 0x%8.8x "
- "id = 0x%8.8x }",
- reply_msg.hdr.msgh_bits,
- reply_msg.hdr.msgh_size,
- reply_msg.hdr.msgh_remote_port,
- reply_msg.hdr.msgh_local_port,
- reply_msg.hdr.msgh_reserved,
- reply_msg.hdr.msgh_id);
- stream.Flush();
-}
-#endif
-
bool MachException::Data::GetStopInfo(struct ThreadStopInfo *stop_info,
const UnixSignals &signals,
Stream &stream) const {
@@ -279,9 +247,6 @@ void MachException::Message::Dump(Stream &stream) const {
bool MachException::Message::CatchExceptionRaise(task_t task) {
bool success = false;
- // locker will keep a mutex locked until it goes out of scope
- // PThreadMutex::Locker locker(&g_message_mutex);
- // DNBLogThreaded("calling mach_exc_server");
state.task_port = task;
g_message = &state;
// The exc_server function is the MIG generated server handling function
diff --git a/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
index 2214bbc52ca4..649280c17a8f 100644
--- a/source/Plugins/Process/Darwin/NativeProcessDarwin.h
+++ b/source/Plugins/Process/Darwin/NativeProcessDarwin.h
@@ -22,12 +22,12 @@
#include <unordered_set>
// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-types.h"
@@ -197,20 +197,6 @@ private:
// waitpid reader callback handle.
MainLoop::ReadHandleUP m_waitpid_reader_handle;
-#if 0
- ArchSpec m_arch;
-
- LazyBool m_supports_mem_region;
- std::vector<MemoryRegionInfo> m_mem_region_cache;
-
- lldb::tid_t m_pending_notification_tid;
-
- // List of thread ids stepping with a breakpoint with the address of
- // the relevan breakpoint
- std::map<lldb::tid_t, lldb::addr_t>
- m_threads_stepping_with_breakpoint;
-#endif
-
// -----------------------------------------------------------------
// Private Instance Methods
// -----------------------------------------------------------------
@@ -322,20 +308,6 @@ private:
Status SetupSoftwareSingleStepping(NativeThreadDarwin &thread);
-#if 0
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGSEGV(const siginfo_t *info);
-
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGILL(const siginfo_t *info);
-
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGFPE(const siginfo_t *info);
-
- static ::ProcessMessage::CrashReason
- GetCrashReasonForSIGBUS(const siginfo_t *info);
-#endif
-
bool HasThreadNoLock(lldb::tid_t thread_id);
bool StopTrackingThread(lldb::tid_t thread_id);
diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
index bd8e5abe2255..e6557c2d58e0 100644
--- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
+++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
@@ -375,6 +375,7 @@ void FreeBSDThread::Notify(const ProcessMessage &message) {
LimboNotify(message);
break;
+ case ProcessMessage::eCrashMessage:
case ProcessMessage::eSignalMessage:
SignalNotify(message);
break;
@@ -395,10 +396,6 @@ void FreeBSDThread::Notify(const ProcessMessage &message) {
WatchNotify(message);
break;
- case ProcessMessage::eCrashMessage:
- CrashNotify(message);
- break;
-
case ProcessMessage::eExecMessage:
ExecNotify(message);
break;
@@ -577,7 +574,14 @@ void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
int signo = message.GetSignal();
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
+ if (message.GetKind() == ProcessMessage::eCrashMessage) {
+ std::string stop_description = GetCrashReasonString(
+ message.GetCrashReason(), message.GetFaultAddress());
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+ *this, signo, stop_description.c_str()));
+ } else {
+ SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
+ }
}
void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
@@ -585,21 +589,6 @@ void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
}
-void FreeBSDThread::CrashNotify(const ProcessMessage &message) {
- // FIXME: Update stop reason as per bugzilla 14598
- int signo = message.GetSignal();
-
- assert(message.GetKind() == ProcessMessage::eCrashMessage);
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
- if (log)
- log->Printf("FreeBSDThread::%s () signo = %i, reason = '%s'", __FUNCTION__,
- signo, message.PrintCrashReason());
-
- SetStopInfo(lldb::StopInfoSP(new POSIXCrashStopInfo(
- *this, signo, message.GetCrashReason(), message.GetFaultAddress())));
-}
-
unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
unsigned reg = LLDB_INVALID_REGNUM;
ArchSpec arch = HostInfo::GetArchitecture();
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
index dfbd695899ff..9c75c26e379b 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.cpp
@@ -28,22 +28,6 @@ bool POSIXLimboStopInfo::ShouldStop(Event *event_ptr) { return false; }
bool POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) { return false; }
//===----------------------------------------------------------------------===//
-// POSIXCrashStopInfo
-
-POSIXCrashStopInfo::POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status,
- CrashReason reason,
- lldb::addr_t fault_addr)
- : POSIXStopInfo(thread, status) {
- m_description = ::GetCrashReasonString(reason, fault_addr);
-}
-
-POSIXCrashStopInfo::~POSIXCrashStopInfo() {}
-
-lldb::StopReason POSIXCrashStopInfo::GetStopReason() const {
- return lldb::eStopReasonException;
-}
-
-//===----------------------------------------------------------------------===//
// POSIXNewThreadStopInfo
POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() {}
diff --git a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
index e51fc08d74cc..96861852b38e 100644
--- a/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
+++ b/source/Plugins/Process/FreeBSD/POSIXStopInfo.h
@@ -45,19 +45,6 @@ public:
};
//===----------------------------------------------------------------------===//
-/// @class POSIXCrashStopInfo
-/// @brief Represents the stop state of process that is ready to crash.
-///
-class POSIXCrashStopInfo : public POSIXStopInfo {
-public:
- POSIXCrashStopInfo(FreeBSDThread &thread, uint32_t status, CrashReason reason,
- lldb::addr_t fault_addr);
- ~POSIXCrashStopInfo();
-
- lldb::StopReason GetStopReason() const;
-};
-
-//===----------------------------------------------------------------------===//
/// @class POSIXNewThreadStopInfo
/// @brief Represents the stop state of process when a new thread is spawned.
///
diff --git a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
index 3046150e3246..7a937db49be0 100644
--- a/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
@@ -825,32 +825,6 @@ uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
return m_thread_list.GetSize(false);
}
-#if 0
-bool
-ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
-
- bool has_updated = false;
- // Update the process thread list with this new thread.
- // FIXME: We should be using tid, not pid.
- assert(m_monitor);
- ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
- if (!thread_sp) {
- thread_sp.reset(CreateNewFreeBSDThread(*this, GetID()));
- has_updated = true;
- }
-
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessFreeBSD::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
- new_thread_list.AddThread(thread_sp);
-
- return has_updated; // the list has been updated
-}
-#endif
-
ByteOrder ProcessFreeBSD::GetByteOrder() const {
// FIXME: We should be able to extract this value directly. See comment in
// ProcessFreeBSD().
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index a4f5f02dde62..bd06fa25f0a0 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -843,7 +843,7 @@ bool ProcessMonitor::Launch(LaunchArgs *args) {
const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
const FileSpec &working_dir = args->m_working_dir;
- lldb_utility::PseudoTerminal terminal;
+ PseudoTerminal terminal;
const size_t err_len = 1024;
char err_str[err_len];
::pid_t pid;
@@ -1192,7 +1192,9 @@ ProcessMessage ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
case SIGBUS:
lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
const auto reason = GetCrashReason(*info);
- return ProcessMessage::Crash(tid, reason, signo, fault_addr);
+ if (reason != CrashReason::eInvalidCrashReason) {
+ return ProcessMessage::Crash(tid, reason, signo, fault_addr);
+ } // else; Use atleast si_signo info for other si_code
}
// Everything else is "normal" and does not require any special action on
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
index c0b9b2f4a2d3..4ff5121bac13 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h
@@ -14,8 +14,8 @@
// C++ Includes
// Other libraries and framework includes
#include "RegisterInfoInterface.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/ArchSpec.h"
//------------------------------------------------------------------------------
/// @class POSIXBreakpointProtocol
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
index 1cd8f1aafa6e..4608520dba40 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -58,6 +58,9 @@ RegisterContextPOSIXProcessMonitor_x86_64::
// Store byte offset of fctrl (i.e. first register of FPR) wrt 'UserArea'
const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
+
+ m_iovec.iov_base = &m_fpr.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xsave);
}
ProcessMonitor &RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor() {
@@ -74,12 +77,12 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR() {
bool RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR() {
ProcessMonitor &monitor = GetMonitor();
if (GetFPRType() == eFXSAVE)
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
- sizeof(m_fpr.xstate.fxsave));
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr.fxsave,
+ sizeof(m_fpr.fxsave));
if (GetFPRType() == eXSAVE)
return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec,
- sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ sizeof(m_fpr.xsave), NT_X86_XSTATE);
return false;
}
@@ -91,12 +94,12 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR() {
bool RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR() {
ProcessMonitor &monitor = GetMonitor();
if (GetFPRType() == eFXSAVE)
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave,
- sizeof(m_fpr.xstate.fxsave));
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr.fxsave,
+ sizeof(m_fpr.fxsave));
if (GetFPRType() == eXSAVE)
return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec,
- sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ sizeof(m_fpr.xsave), NT_X86_XSTATE);
return false;
}
@@ -209,17 +212,14 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
if (byte_order != ByteOrder::eByteOrderInvalid) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- reg_info->byte_size, byte_order);
+ value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- reg_info->byte_size, byte_order);
+ value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- value.SetBytes(
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- reg_info->byte_size, byte_order);
+ value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
// Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
@@ -233,7 +233,7 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(
return false;
}
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ // Get pointer to m_fpr.fxsave variable and set the data from it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, ReadFPR() reads fpu registers {using ptrace(PT_GETFPREGS,..)}
// and stores them in 'm_fpr' (of type FPR structure). To extract values of
@@ -276,15 +276,15 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
if (IsFPR(reg, GetFPRType())) {
if (reg_info->encoding == eEncodingVector) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
value.GetBytes(), value.GetByteSize());
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- ::memcpy(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ ::memcpy(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
value.GetBytes(), value.GetByteSize());
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
value.GetBytes(), value.GetByteSize());
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
@@ -299,7 +299,7 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(
return false;
}
} else {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ // Get pointer to m_fpr.fxsave variable and set the data to it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
// fpu
@@ -353,7 +353,7 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(
::memcpy(dst, &m_gpr_x86_64, GetGPRSize());
dst += GetGPRSize();
if (GetFPRType() == eFXSAVE)
- ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
}
if (GetFPRType() == eXSAVE) {
@@ -385,9 +385,9 @@ bool RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(
if (WriteGPR()) {
src += GetGPRSize();
if (GetFPRType() == eFXSAVE)
- ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
if (GetFPRType() == eXSAVE)
- ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+ ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
success = WriteFPR();
if (success) {
diff --git a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
index 57e2d00e668f..8c654f97dcd9 100644
--- a/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
+++ b/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.h
@@ -12,6 +12,7 @@
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
#include "RegisterContextPOSIX.h"
+#include <sys/uio.h>
class RegisterContextPOSIXProcessMonitor_x86_64
: public RegisterContextPOSIX_x86,
@@ -75,6 +76,7 @@ private:
ProcessMonitor &GetMonitor();
uint32_t
m_fctrl_offset_in_userarea; // Offset of 'fctrl' in 'UserArea' Structure
+ struct iovec m_iovec;
};
#endif
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt
index 8330cac160e6..390dbd9ff8bf 100644
--- a/source/Plugins/Process/Linux/CMakeLists.txt
+++ b/source/Plugins/Process/Linux/CMakeLists.txt
@@ -7,9 +7,10 @@ add_lldb_library(lldbPluginProcessLinux PLUGIN
NativeRegisterContextLinux.cpp
NativeRegisterContextLinux_arm.cpp
NativeRegisterContextLinux_arm64.cpp
- NativeRegisterContextLinux_x86_64.cpp
NativeRegisterContextLinux_mips64.cpp
+ NativeRegisterContextLinux_ppc64le.cpp
NativeRegisterContextLinux_s390x.cpp
+ NativeRegisterContextLinux_x86_64.cpp
NativeThreadLinux.cpp
ProcessorTrace.cpp
SingleStepCheck.cpp
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 170d3b100064..136af361af29 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -177,7 +177,7 @@ void PtraceDisplayBytes(int &req, void *data, size_t data_size) {
break;
}
case PTRACE_SETREGSET: {
- // Extract iov_base from data, which is a pointer to the struct IOVEC
+ // Extract iov_base from data, which is a pointer to the struct iovec
DisplayBytes(buf, *(void **)data, data_size);
LLDB_LOGV(log, "PTRACE_SETREGSET {0}", buf.GetData());
break;
@@ -305,10 +305,9 @@ NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
assert(m_sigchld_handle && status.Success());
for (const auto &tid : tids) {
- NativeThreadLinuxSP thread_sp = AddThread(tid);
- assert(thread_sp && "AddThread() returned a nullptr thread");
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
+ NativeThreadLinux &thread = AddThread(tid);
+ thread.SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(thread);
}
// Let our process instance know the thread has stopped.
@@ -413,46 +412,20 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
// Handle when the thread exits.
if (exited) {
- LLDB_LOG(log, "got exit signal({0}) , tid = {1} ({2} main thread)", signal,
- pid, is_main_thread ? "is" : "is not");
+ LLDB_LOG(log,
+ "got exit signal({0}) , tid = {1} ({2} main thread), process "
+ "state = {3}",
+ signal, pid, is_main_thread ? "is" : "is not", GetState());
// This is a thread that exited. Ensure we're not tracking it anymore.
- const bool thread_found = StopTrackingThread(pid);
+ StopTrackingThread(pid);
if (is_main_thread) {
- // We only set the exit status and notify the delegate if we haven't
- // already set the process
- // state to an exited state. We normally should have received a SIGTRAP |
- // (PTRACE_EVENT_EXIT << 8)
- // for the main thread.
- const bool already_notified = (GetState() == StateType::eStateExited) ||
- (GetState() == StateType::eStateCrashed);
- if (!already_notified) {
- LLDB_LOG(
- log,
- "tid = {0} handling main thread exit ({1}), expected exit state "
- "already set but state was {2} instead, setting exit state now",
- pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found",
- GetState());
- // The main thread exited. We're done monitoring. Report to delegate.
- SetExitStatus(status, true);
+ // The main thread exited. We're done monitoring. Report to delegate.
+ SetExitStatus(status, true);
- // Notify delegate that our process has exited.
- SetState(StateType::eStateExited, true);
- } else
- LLDB_LOG(log, "tid = {0} main thread now exited (%s)", pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found");
- } else {
- // Do we want to report to the delegate in this case? I think not. If
- // this was an orderly thread exit, we would already have received the
- // SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal, and we would have done an
- // all-stop then.
- LLDB_LOG(log, "tid = {0} handling non-main thread exit (%s)", pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found");
+ // Notify delegate that our process has exited.
+ SetState(StateType::eStateExited, true);
}
return;
}
@@ -478,11 +451,11 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
info.si_pid);
- auto thread_sp = AddThread(pid);
+ NativeThreadLinux &thread = AddThread(pid);
// Resume the newly created thread.
- ResumeThread(*thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*thread_sp);
+ ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(thread);
return;
}
@@ -549,12 +522,9 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- NativeThreadLinuxSP new_thread_sp = GetThreadByID(tid);
-
- if (new_thread_sp) {
+ if (GetThreadByID(tid)) {
// We are already tracking the thread - we got the event on the new thread
- // (see
- // MonitorSignal) before this one. We are done.
+ // (see MonitorSignal) before this one. We are done.
return;
}
@@ -587,10 +557,10 @@ void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
}
LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
- new_thread_sp = AddThread(tid);
+ NativeThreadLinux &new_thread = AddThread(tid);
- ResumeThread(*new_thread_sp, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(*new_thread_sp);
+ ResumeThread(new_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
+ ThreadWasCreated(new_thread);
}
void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
@@ -630,7 +600,6 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
}
case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
- NativeThreadLinuxSP main_thread_sp;
LLDB_LOG(log, "received exec event, code = {0}", info.si_code ^ SIGTRAP);
// Exec clears any pending notifications.
@@ -640,44 +609,26 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
// which only copies the main thread.
LLDB_LOG(log, "exec received, stop tracking all but main thread");
- for (auto thread_sp : m_threads) {
- const bool is_main_thread = thread_sp && thread_sp->GetID() == GetID();
- if (is_main_thread) {
- main_thread_sp = std::static_pointer_cast<NativeThreadLinux>(thread_sp);
- LLDB_LOG(log, "found main thread with tid {0}, keeping",
- main_thread_sp->GetID());
- } else {
- LLDB_LOG(log, "discarding non-main-thread tid {0} due to exec",
- thread_sp->GetID());
- }
+ for (auto i = m_threads.begin(); i != m_threads.end();) {
+ if ((*i)->GetID() == GetID())
+ i = m_threads.erase(i);
+ else
+ ++i;
}
+ assert(m_threads.size() == 1);
+ auto *main_thread = static_cast<NativeThreadLinux *>(m_threads[0].get());
- m_threads.clear();
-
- if (main_thread_sp) {
- m_threads.push_back(main_thread_sp);
- SetCurrentThreadID(main_thread_sp->GetID());
- main_thread_sp->SetStoppedByExec();
- } else {
- SetCurrentThreadID(LLDB_INVALID_THREAD_ID);
- LLDB_LOG(log,
- "pid {0} no main thread found, discarded all threads, "
- "we're in a no-thread state!",
- GetID());
- }
+ SetCurrentThreadID(main_thread->GetID());
+ main_thread->SetStoppedByExec();
// Tell coordinator about about the "new" (since exec) stopped main thread.
- ThreadWasCreated(*main_thread_sp);
+ ThreadWasCreated(*main_thread);
// Let our delegate know we have just exec'd.
NotifyDidExec();
- // If we have a main thread, indicate we are stopped.
- assert(main_thread_sp && "exec called during ptraced process but no main "
- "thread metadata tracked");
-
// Let the process know we're stopped.
- StopRunningThreads(main_thread_sp->GetID());
+ StopRunningThreads(main_thread->GetID());
break;
}
@@ -685,10 +636,8 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
// The inferior process or one of its threads is about to exit.
// We don't want to do anything with the thread so we just resume it. In
- // case we
- // want to implement "break on thread exit" functionality, we would need to
- // stop
- // here.
+ // case we want to implement "break on thread exit" functionality, we would
+ // need to stop here.
unsigned long data = 0;
if (GetEventMessage(thread.GetID(), &data).Fail())
@@ -700,18 +649,14 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
data, WIFEXITED(data), WIFSIGNALED(data), thread.GetID(),
is_main_thread);
- if (is_main_thread)
- SetExitStatus(WaitStatus::Decode(data), true);
StateType state = thread.GetState();
if (!StateIsRunningState(state)) {
// Due to a kernel bug, we may sometimes get this stop after the inferior
- // gets a
- // SIGKILL. This confuses our state tracking logic in ResumeThread(),
- // since normally,
- // we should not be receiving any ptrace events while the inferior is
- // stopped. This
- // makes sure that the inferior is resumed and exits normally.
+ // gets a SIGKILL. This confuses our state tracking logic in
+ // ResumeThread(), since normally, we should not be receiving any ptrace
+ // events while the inferior is stopped. This makes sure that the inferior
+ // is resumed and exits normally.
state = eStateRunning;
}
ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
@@ -725,7 +670,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
{
// If a watchpoint was hit, report it
uint32_t wp_index;
- Status error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
wp_index, (uintptr_t)info.si_addr);
if (error.Fail())
LLDB_LOG(log,
@@ -739,7 +684,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
// If a breakpoint was hit, report it
uint32_t bp_index;
- error = thread.GetRegisterContext()->GetHardwareBreakHitIndex(
+ error = thread.GetRegisterContext().GetHardwareBreakHitIndex(
bp_index, (uintptr_t)info.si_addr);
if (error.Fail())
LLDB_LOG(log, "received error while checking for hardware "
@@ -762,7 +707,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
{
// If a watchpoint was hit, report it
uint32_t wp_index;
- Status error = thread.GetRegisterContext()->GetWatchpointHitIndex(
+ Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
wp_index, LLDB_INVALID_ADDRESS);
if (error.Fail())
LLDB_LOG(log,
@@ -933,13 +878,13 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
namespace {
struct EmulatorBaton {
- NativeProcessLinux *m_process;
- NativeRegisterContext *m_reg_context;
+ NativeProcessLinux &m_process;
+ NativeRegisterContext &m_reg_context;
// eRegisterKindDWARF -> RegsiterValue
std::unordered_map<uint32_t, RegisterValue> m_register_values;
- EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
+ EmulatorBaton(NativeProcessLinux &process, NativeRegisterContext &reg_context)
: m_process(process), m_reg_context(reg_context) {}
};
@@ -951,7 +896,7 @@ static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
size_t bytes_read;
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
+ emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
return bytes_read;
}
@@ -971,11 +916,11 @@ static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
// the generic register numbers). Get the full register info from the
// register context based on the dwarf register numbers.
const RegisterInfo *full_reg_info =
- emulator_baton->m_reg_context->GetRegisterInfo(
+ emulator_baton->m_reg_context.GetRegisterInfo(
eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
Status error =
- emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
+ emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
if (error.Success())
return true;
@@ -999,17 +944,17 @@ static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
return length;
}
-static lldb::addr_t ReadFlags(NativeRegisterContext *regsiter_context) {
- const RegisterInfo *flags_info = regsiter_context->GetRegisterInfo(
+static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
+ const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- return regsiter_context->ReadRegisterAsUnsigned(flags_info,
- LLDB_INVALID_ADDRESS);
+ return regsiter_context.ReadRegisterAsUnsigned(flags_info,
+ LLDB_INVALID_ADDRESS);
}
Status
NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
Status error;
- NativeRegisterContextSP register_context_sp = thread.GetRegisterContext();
+ NativeRegisterContext& register_context = thread.GetRegisterContext();
std::unique_ptr<EmulateInstruction> emulator_ap(
EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
@@ -1018,7 +963,7 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
if (emulator_ap == nullptr)
return Status("Instruction emulator not found!");
- EmulatorBaton baton(this, register_context_sp.get());
+ EmulatorBaton baton(*this, register_context);
emulator_ap->SetBaton(&baton);
emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
@@ -1031,9 +976,9 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
bool emulation_result =
emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
- const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
+ const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *reg_info_flags = register_context_sp->GetRegisterInfo(
+ const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
auto pc_it =
@@ -1051,15 +996,14 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
if (flags_it != baton.m_register_values.end())
next_flags = flags_it->second.GetAsUInt64();
else
- next_flags = ReadFlags(register_context_sp.get());
+ next_flags = ReadFlags(register_context);
} else if (pc_it == baton.m_register_values.end()) {
// Emulate instruction failed and it haven't changed PC. Advance PC
// with the size of the current opcode because the emulation of all
// PC modifying instruction should be successful. The failure most
// likely caused by a not supported instruction which don't modify PC.
- next_pc =
- register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
- next_flags = ReadFlags(register_context_sp.get());
+ next_pc = register_context.GetPC() + emulator_ap->GetOpcode().GetByteSize();
+ next_flags = ReadFlags(register_context);
} else {
// The instruction emulation failed after it modified the PC. It is an
// unknown error where we can't continue because the next instruction is
@@ -1078,7 +1022,8 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
} else if (m_arch.GetMachine() == llvm::Triple::mips64 ||
m_arch.GetMachine() == llvm::Triple::mips64el ||
m_arch.GetMachine() == llvm::Triple::mips ||
- m_arch.GetMachine() == llvm::Triple::mipsel)
+ m_arch.GetMachine() == llvm::Triple::mipsel ||
+ m_arch.GetMachine() == llvm::Triple::ppc64le)
error = SetSoftwareBreakpoint(next_pc, 4);
else {
// No size hint is given for the next breakpoint
@@ -1114,44 +1059,44 @@ Status NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
bool software_single_step = !SupportHardwareSingleStepping();
if (software_single_step) {
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
const ResumeAction *const action =
- resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ resume_actions.GetActionForThread(thread->GetID(), true);
if (action == nullptr)
continue;
if (action->state == eStateStepping) {
Status error = SetupSoftwareSingleStepping(
- static_cast<NativeThreadLinux &>(*thread_sp));
+ static_cast<NativeThreadLinux &>(*thread));
if (error.Fail())
return error;
}
}
}
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
const ResumeAction *const action =
- resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ resume_actions.GetActionForThread(thread->GetID(), true);
if (action == nullptr) {
LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread_sp->GetID());
+ thread->GetID());
continue;
}
LLDB_LOG(log, "processing resume action state {0} for pid {1} tid {2}",
- action->state, GetID(), thread_sp->GetID());
+ action->state, GetID(), thread->GetID());
switch (action->state) {
case eStateRunning:
case eStateStepping: {
// Run the thread, possibly feeding it the signal.
const int signo = action->signal;
- ResumeThread(static_cast<NativeThreadLinux &>(*thread_sp), action->state,
+ ResumeThread(static_cast<NativeThreadLinux &>(*thread), action->state,
signo);
break;
}
@@ -1164,7 +1109,7 @@ Status NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
return Status("NativeProcessLinux::%s (): unexpected state %s specified "
"for pid %" PRIu64 ", tid %" PRIu64,
__FUNCTION__, StateAsCString(action->state), GetID(),
- thread_sp->GetID());
+ thread->GetID());
}
}
@@ -1190,8 +1135,8 @@ Status NativeProcessLinux::Detach() {
if (GetID() == LLDB_INVALID_PROCESS_ID)
return error;
- for (auto thread_sp : m_threads) {
- Status e = Detach(thread_sp->GetID());
+ for (const auto &thread : m_threads) {
+ Status e = Detach(thread->GetID());
if (e.Fail())
error =
e; // Save the error, but still attempt to detach from other threads.
@@ -1221,29 +1166,25 @@ Status NativeProcessLinux::Interrupt() {
// the chosen thread that will be the stop-reason thread.
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- NativeThreadProtocolSP running_thread_sp;
- NativeThreadProtocolSP stopped_thread_sp;
+ NativeThreadProtocol *running_thread = nullptr;
+ NativeThreadProtocol *stopped_thread = nullptr;
LLDB_LOG(log, "selecting running thread for interrupt target");
- for (auto thread_sp : m_threads) {
- // The thread shouldn't be null but lets just cover that here.
- if (!thread_sp)
- continue;
-
+ for (const auto &thread : m_threads) {
// If we have a running or stepping thread, we'll call that the
// target of the interrupt.
- const auto thread_state = thread_sp->GetState();
+ const auto thread_state = thread->GetState();
if (thread_state == eStateRunning || thread_state == eStateStepping) {
- running_thread_sp = thread_sp;
+ running_thread = thread.get();
break;
- } else if (!stopped_thread_sp && StateIsStoppedState(thread_state, true)) {
+ } else if (!stopped_thread && StateIsStoppedState(thread_state, true)) {
// Remember the first non-dead stopped thread. We'll use that as a backup
// if there are no running threads.
- stopped_thread_sp = thread_sp;
+ stopped_thread = thread.get();
}
}
- if (!running_thread_sp && !stopped_thread_sp) {
+ if (!running_thread && !stopped_thread) {
Status error("found no running/stepping or live stopped threads as target "
"for interrupt");
LLDB_LOG(log, "skipping due to error: {0}", error);
@@ -1251,14 +1192,14 @@ Status NativeProcessLinux::Interrupt() {
return error;
}
- NativeThreadProtocolSP deferred_signal_thread_sp =
- running_thread_sp ? running_thread_sp : stopped_thread_sp;
+ NativeThreadProtocol *deferred_signal_thread =
+ running_thread ? running_thread : stopped_thread;
LLDB_LOG(log, "pid {0} {1} tid {2} chosen for interrupt target", GetID(),
- running_thread_sp ? "running" : "stopped",
- deferred_signal_thread_sp->GetID());
+ running_thread ? "running" : "stopped",
+ deferred_signal_thread->GetID());
- StopRunningThreads(deferred_signal_thread_sp->GetID());
+ StopRunningThreads(deferred_signal_thread->GetID());
return Status();
}
@@ -1568,17 +1509,13 @@ size_t NativeProcessLinux::UpdateThreads() {
return m_threads.size();
}
-bool NativeProcessLinux::GetArchitecture(ArchSpec &arch) const {
- arch = m_arch;
- return true;
-}
-
Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
uint32_t &actual_opcode_size) {
// FIXME put this behind a breakpoint protocol class that can be
// set per architecture. Need ARM, MIPS support here.
static const uint8_t g_i386_opcode[] = {0xCC};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::x86:
@@ -1590,6 +1527,10 @@ Status NativeProcessLinux::GetSoftwareBreakpointPCOffset(
actual_opcode_size = static_cast<uint32_t>(sizeof(g_s390x_opcode));
return Status();
+ case llvm::Triple::ppc64le:
+ actual_opcode_size = static_cast<uint32_t>(sizeof(g_ppc64le_opcode));
+ return Status();
+
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::mips64:
@@ -1635,6 +1576,7 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (m_arch.GetMachine()) {
case llvm::Triple::aarch64:
@@ -1680,6 +1622,11 @@ Status NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(
actual_opcode_size = sizeof(g_s390x_opcode);
return Status();
+ case llvm::Triple::ppc64le:
+ trap_opcode_bytes = g_ppc64le_opcode;
+ actual_opcode_size = sizeof(g_ppc64le_opcode);
+ return Status();
+
default:
assert(false && "CPU type not supported!");
return Status("CPU type not supported");
@@ -1963,9 +1910,9 @@ Status NativeProcessLinux::Detach(lldb::tid_t tid) {
}
bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
- if (thread_sp->GetID() == thread_id) {
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
+ if (thread->GetID() == thread_id) {
// We have this thread.
return true;
}
@@ -1994,7 +1941,7 @@ bool NativeProcessLinux::StopTrackingThread(lldb::tid_t thread_id) {
return found;
}
-NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
+NativeThreadLinux &NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
@@ -2005,8 +1952,7 @@ NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
if (m_threads.empty())
SetCurrentThreadID(thread_id);
- auto thread_sp = std::make_shared<NativeThreadLinux>(*this, thread_id);
- m_threads.push_back(thread_sp);
+ m_threads.push_back(llvm::make_unique<NativeThreadLinux>(*this, thread_id));
if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
auto traceMonitor = ProcessorTraceMonitor::Create(
@@ -2022,7 +1968,7 @@ NativeThreadLinuxSP NativeProcessLinux::AddThread(lldb::tid_t thread_id) {
}
}
- return thread_sp;
+ return static_cast<NativeThreadLinux &>(*m_threads.back());
}
Status
@@ -2033,12 +1979,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
// Find out the size of a breakpoint (might depend on where we are in the
// code).
- NativeRegisterContextSP context_sp = thread.GetRegisterContext();
- if (!context_sp) {
- error.SetErrorString("cannot get a NativeRegisterContext for the thread");
- LLDB_LOG(log, "failed: {0}", error);
- return error;
- }
+ NativeRegisterContext &context = thread.GetRegisterContext();
uint32_t breakpoint_size = 0;
error = GetSoftwareBreakpointPCOffset(breakpoint_size);
@@ -2050,8 +1991,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
// First try probing for a breakpoint at a software breakpoint location: PC -
// breakpoint size.
- const lldb::addr_t initial_pc_addr =
- context_sp->GetPCfromBreakpointLocation();
+ const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();
lldb::addr_t breakpoint_addr = initial_pc_addr;
if (breakpoint_size > 0) {
// Do not allow breakpoint probe to wrap around.
@@ -2098,7 +2038,7 @@ NativeProcessLinux::FixupBreakpointPCAsNeeded(NativeThreadLinux &thread) {
LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
thread.GetID(), initial_pc_addr, breakpoint_addr);
- error = context_sp->SetPC(breakpoint_addr);
+ error = context.SetPC(breakpoint_addr);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
thread.GetID(), error);
@@ -2144,8 +2084,8 @@ Status NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
return Status("No load address found for specified file.");
}
-NativeThreadLinuxSP NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
- return std::static_pointer_cast<NativeThreadLinux>(
+NativeThreadLinux *NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
+ return static_cast<NativeThreadLinux *>(
NativeProcessProtocol::GetThreadByID(tid));
}
@@ -2200,9 +2140,9 @@ void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
// Request a stop for all the thread stops that need to be stopped
// and are not already known to be stopped.
- for (const auto &thread_sp : m_threads) {
- if (StateIsRunningState(thread_sp->GetState()))
- static_pointer_cast<NativeThreadLinux>(thread_sp)->RequestStop();
+ for (const auto &thread : m_threads) {
+ if (StateIsRunningState(thread->GetState()))
+ static_cast<NativeThreadLinux *>(thread.get())->RequestStop();
}
SignalIfAllThreadsStopped();
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index c9ec002760f8..f078c1ac30e2 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -13,12 +13,11 @@
#include <csignal>
#include <unordered_set>
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Host/Debug.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-types.h"
@@ -87,7 +86,7 @@ public:
size_t UpdateThreads() override;
- bool GetArchitecture(ArchSpec &arch) const override;
+ const ArchSpec &GetArchitecture() const override { return m_arch; }
Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) override;
@@ -102,7 +101,7 @@ public:
Status GetFileLoadAddress(const llvm::StringRef &file_name,
lldb::addr_t &load_addr) override;
- NativeThreadLinuxSP GetThreadByID(lldb::tid_t id);
+ NativeThreadLinux *GetThreadByID(lldb::tid_t id);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
GetAuxvData() const override {
@@ -203,7 +202,7 @@ private:
bool StopTrackingThread(lldb::tid_t thread_id);
- NativeThreadLinuxSP AddThread(lldb::tid_t thread_id);
+ NativeThreadLinux &AddThread(lldb::tid_t thread_id);
Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
index 30f09f0c3a3f..c8a8355f9cb9 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
@@ -14,27 +14,19 @@
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/Host/linux/Ptrace.h"
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
using namespace lldb_private;
using namespace lldb_private::process_linux;
NativeRegisterContextLinux::NativeRegisterContextLinux(
- NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &native_thread,
RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx,
- reg_info_interface_p) {}
+ : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {}
lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
- // Get the target process whose privileged thread was used for the register
- // read.
- lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
-
- if (!m_thread.GetProcess().GetByteOrder(byte_order)) {
- // FIXME log here
- }
-
- return byte_order;
+ return m_thread.GetProcess().GetByteOrder();
}
Status NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
index 26074a6ce0e3..2cea497b53bc 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
@@ -10,10 +10,8 @@
#ifndef lldb_NativeRegisterContextLinux_h
#define lldb_NativeRegisterContextLinux_h
-#include "lldb/Host/common/NativeThreadProtocol.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
+#include "lldb/Host/common/NativeThreadProtocol.h"
namespace lldb_private {
namespace process_linux {
@@ -21,20 +19,15 @@ namespace process_linux {
class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
public:
NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
RegisterInfoInterface *reg_info_interface_p);
// This function is implemented in the NativeRegisterContextLinux_* subclasses
- // to create a new
- // instance of the host specific NativeRegisterContextLinux. The
- // implementations can't collide
- // as only one NativeRegisterContextLinux_* variant should be compiled into
- // the final
- // executable.
- static NativeRegisterContextLinux *
+ // to create a new instance of the host specific NativeRegisterContextLinux.
+ // The implementations can't collide as only one NativeRegisterContextLinux_*
+ // variant should be compiled into the final executable.
+ static std::unique_ptr<NativeRegisterContextLinux>
CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
protected:
lldb::ByteOrder GetByteOrder() const;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
index 22b7d10869fe..cb05416cb6c3 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -11,15 +11,15 @@
#include "NativeRegisterContextLinux_arm.h"
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
-
#include <elf.h>
#include <sys/socket.h>
@@ -95,20 +95,18 @@ static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
#if defined(__arm__)
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_arm(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
+ native_thread);
}
#endif // defined(__arm__)
NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
new RegisterInfoPOSIX_arm(target_arch)) {
switch (target_arch.GetMachine()) {
case llvm::Triple::arm:
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
index ec99c05e1644..40e3b80eda74 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
@@ -23,8 +23,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_arm(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index 7aad062e3f93..c483260a5b2c 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -112,26 +112,24 @@ static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
{"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
g_fpu_regnums_arm64}};
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
switch (target_arch.GetMachine()) {
case llvm::Triple::arm:
- return new NativeRegisterContextLinux_arm(target_arch, native_thread,
- concrete_frame_idx);
+ return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
+ native_thread);
case llvm::Triple::aarch64:
- return new NativeRegisterContextLinux_arm64(target_arch, native_thread,
- concrete_frame_idx);
+ return llvm::make_unique<NativeRegisterContextLinux_arm64>(target_arch,
+ native_thread);
default:
llvm_unreachable("have no register context for architecture");
}
}
NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
new RegisterInfoPOSIX_arm64(target_arch)) {
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64:
@@ -872,12 +870,8 @@ Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
if (error.Success()) {
- ArchSpec arch;
- if (m_thread.GetProcess().GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
- arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
+ value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
+ m_thread.GetProcess().GetByteOrder());
}
} else {
elf_gregset_t regs;
@@ -889,12 +883,8 @@ Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
if (error.Success()) {
- ArchSpec arch;
- if (m_thread.GetProcess().GetArchitecture(arch))
- value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
- arch.GetByteOrder());
- else
- error.SetErrorString("failed to get architecture");
+ value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
+ m_thread.GetProcess().GetByteOrder());
}
}
return error;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
index 9877dec37c48..ab3c881ead59 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -23,8 +23,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
index f35ff2be0d94..32c04a4374e6 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
@@ -80,12 +80,11 @@ struct pt_watch_regs default_watch_regs;
using namespace lldb_private;
using namespace lldb_private::process_linux;
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_mips64(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return llvm::make_unique<NativeRegisterContextLinux_mips64>(target_arch,
+ native_thread);
}
#define REG_CONTEXT_SIZE \
@@ -110,9 +109,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
CreateRegisterInfoInterface(target_arch)) {
switch (target_arch.GetMachine()) {
case llvm::Triple::mips:
@@ -1033,13 +1031,11 @@ Status NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
Status error = NativeProcessLinux::PtraceWrapper(
PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
if (error.Success()) {
- lldb_private::ArchSpec arch;
- if (m_thread.GetProcess().GetArchitecture(arch)) {
- void *target_address = ((uint8_t *)&regs) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- value.SetUInt(*(uint32_t *)target_address, size);
- } else
- error.SetErrorString("failed to get architecture");
+ const lldb_private::ArchSpec &arch =
+ m_thread.GetProcess().GetArchitecture();
+ void *target_address = ((uint8_t *)&regs) + offset +
+ 4 * (arch.GetMachine() == llvm::Triple::mips);
+ value.SetUInt(*(uint32_t *)target_address, size);
}
return error;
}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
index 3e14da5a2725..c4e984a545bc 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
@@ -15,6 +15,7 @@
#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/RegisterContext_mips.h"
#include "Plugins/Process/Utility/lldb-mips-linux-register-enums.h"
+#include <sys/uio.h>
#define MAX_NUM_WP 8
@@ -26,8 +27,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
@@ -129,7 +129,7 @@ private:
lldb::addr_t hw_addr_map[MAX_NUM_WP];
- IOVEC_mips m_iovec;
+ struct iovec m_iovec;
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
new file mode 100644
index 000000000000..ea854dfa1dc6
--- /dev/null
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
@@ -0,0 +1,801 @@
+//===-- NativeRegisterContextLinux_ppc64le.cpp ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This implementation is related to the OpenPOWER ABI for Power Architecture
+// 64-bit ELF V2 ABI
+
+#if defined(__powerpc64__)
+
+#include "NativeRegisterContextLinux_ppc64le.h"
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/Linux/NativeProcessLinux.h"
+#include "Plugins/Process/Linux/Procfs.h"
+#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
+
+// System includes - They have to be included after framework includes because
+// they define some
+// macros which collide with variable names in other modules
+#include <sys/socket.h>
+#include <elf.h>
+#include <asm/ptrace.h>
+
+#define REG_CONTEXT_SIZE \
+ (GetGPRSize() + GetFPRSize() + sizeof(m_vmx_ppc64le) + sizeof(m_vsx_ppc64le))
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_linux;
+
+static const uint32_t g_gpr_regnums_ppc64le[] = {
+ gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
+ gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
+ gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
+ gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
+ gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
+ gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
+ gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
+ gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le,
+ gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le,
+ gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le,
+ gpr_trap_ppc64le,
+};
+
+static const uint32_t g_fpr_regnums_ppc64le[] = {
+ fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le,
+ fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le,
+ fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le,
+ fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le,
+ fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le,
+ fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_ppc64le,
+ fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le,
+ fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le,
+ fpr_fpscr_ppc64le,
+};
+
+static const uint32_t g_vmx_regnums_ppc64le[] = {
+ vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le,
+ vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le,
+ vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le,
+ vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le,
+ vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le,
+ vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_ppc64le,
+ vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le,
+ vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le,
+ vmx_vscr_ppc64le, vmx_vrsave_ppc64le,
+};
+
+static const uint32_t g_vsx_regnums_ppc64le[] = {
+ vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le,
+ vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le,
+ vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le,
+ vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le,
+ vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le,
+ vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le,
+ vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le,
+ vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le,
+ vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le,
+ vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le,
+ vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le,
+ vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le,
+ vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_ppc64le,
+ vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le,
+ vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le,
+ vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le,
+};
+
+namespace {
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 4 };
+}
+
+static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
+ g_gpr_regnums_ppc64le},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le,
+ g_fpr_regnums_ppc64le},
+ {"AltiVec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le,
+ g_vmx_regnums_ppc64le},
+ {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le,
+ g_vsx_regnums_ppc64le},
+};
+
+std::unique_ptr<NativeRegisterContextLinux>
+NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return llvm::make_unique<NativeRegisterContextLinux_ppc64le>(target_arch,
+ native_thread);
+ default:
+ llvm_unreachable("have no register context for architecture");
+ }
+}
+
+NativeRegisterContextLinux_ppc64le::NativeRegisterContextLinux_ppc64le(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
+ new RegisterInfoPOSIX_ppc64le(target_arch)) {
+ if (target_arch.GetMachine() != llvm::Triple::ppc64le) {
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ ::memset(&m_gpr_ppc64le, 0, sizeof(m_gpr_ppc64le));
+ ::memset(&m_fpr_ppc64le, 0, sizeof(m_fpr_ppc64le));
+ ::memset(&m_vmx_ppc64le, 0, sizeof(m_vmx_ppc64le));
+ ::memset(&m_vsx_ppc64le, 0, sizeof(m_vsx_ppc64le));
+ ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextLinux_ppc64le::GetRegisterSet(uint32_t set_index) const {
+ if (set_index < k_num_register_sets)
+ return &g_reg_sets_ppc64le[set_index];
+
+ return nullptr;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
+ count += g_reg_sets_ppc64le[set_index].num_registers;
+ return count;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &reg_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (IsFPR(reg)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_fpr_ppc64le variable and set the data from it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < sizeof m_fpr_ppc64le);
+ uint8_t *src = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else if (IsVSX(reg)) {
+ uint32_t vsx_offset = CalculateVsxOffset(reg_info);
+ assert(vsx_offset < sizeof(m_vsx_ppc64le));
+
+ if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
+ error = ReadVSX();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ uint64_t value[2];
+ uint8_t *dst, *src;
+ dst = (uint8_t *)&value;
+ src = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+ dst += 8;
+ src = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+ reg_value.SetFromMemoryData(reg_info, &value, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data from it.
+ uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
+ uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ }
+ } else if (IsVMX(reg)) {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data from it.
+ uint32_t vmx_offset = CalculateVmxOffset(reg_info);
+ assert(vmx_offset < sizeof m_vmx_ppc64le);
+ uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else if (IsGPR(reg)) {
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *src = (uint8_t *) &m_gpr_ppc64le + reg_info->byte_offset;
+ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
+ eByteOrderLittle, error);
+ } else {
+ return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
+ "or VMX, read strategy unknown");
+ }
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &reg_value) {
+ Status error;
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
+ if (reg_index == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ if (IsGPR(reg_index)) {
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = (uint8_t *)&m_gpr_ppc64le + reg_info->byte_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteGPR();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ if (IsFPR(reg_index)) {
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_fpr_ppc64le variable and set the data to it.
+ uint32_t fpr_offset = CalculateFprOffset(reg_info);
+ assert(fpr_offset < GetFPRSize());
+ uint8_t *dst = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ if (IsVMX(reg_index)) {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data to it.
+ uint32_t vmx_offset = CalculateVmxOffset(reg_info);
+ assert(vmx_offset < sizeof(m_vmx_ppc64le));
+ uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+
+ error = WriteVMX();
+ if (error.Fail())
+ return error;
+
+ return Status();
+ }
+
+ if (IsVSX(reg_index)) {
+ uint32_t vsx_offset = CalculateVsxOffset(reg_info);
+ assert(vsx_offset < sizeof(m_vsx_ppc64le));
+
+ if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
+ error = ReadVSX();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ uint64_t value[2];
+ ::memcpy(value, reg_value.GetBytes(), 16);
+ uint8_t *dst, *src;
+ src = (uint8_t *)value;
+ dst = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+ src += 8;
+ dst = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
+ ::memcpy(dst, src, 8);
+
+ WriteVSX();
+ WriteFPR();
+ } else {
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ // Get pointer to m_vmx_ppc64le variable and set the data from it.
+ uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
+ uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
+ ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
+ WriteVMX();
+ }
+
+ return Status();
+ }
+
+ return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
+ "or VMX, write strategy unknown");
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
+ if (!data_sp)
+ return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
+ REG_CONTEXT_SIZE);
+
+ error = ReadGPR();
+ if (error.Fail())
+ return error;
+
+ error = ReadFPR();
+ if (error.Fail())
+ return error;
+
+ error = ReadVMX();
+ if (error.Fail())
+ return error;
+
+ error = ReadVSX();
+ if (error.Fail())
+ return error;
+
+ uint8_t *dst = data_sp->GetBytes();
+ if (dst == nullptr) {
+ error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
+ " returned a null pointer",
+ REG_CONTEXT_SIZE);
+ return error;
+ }
+
+ ::memcpy(dst, &m_gpr_ppc64le, GetGPRSize());
+ dst += GetGPRSize();
+ ::memcpy(dst, &m_fpr_ppc64le, GetFPRSize());
+ dst += GetFPRSize();
+ ::memcpy(dst, &m_vmx_ppc64le, sizeof(m_vmx_ppc64le));
+ dst += sizeof(m_vmx_ppc64le);
+ ::memcpy(dst, &m_vsx_ppc64le, sizeof(m_vsx_ppc64le));
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_ppc64le::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextLinux_ppc64le::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextLinux_ppc64le::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+
+ ::memcpy(&m_gpr_ppc64le, src, GetGPRSize());
+ error = WriteGPR();
+
+ if (error.Fail())
+ return error;
+
+ src += GetGPRSize();
+ ::memcpy(&m_fpr_ppc64le, src, GetFPRSize());
+
+ error = WriteFPR();
+ if (error.Fail())
+ return error;
+
+ src += GetFPRSize();
+ ::memcpy(&m_vmx_ppc64le, src, sizeof(m_vmx_ppc64le));
+
+ error = WriteVMX();
+ if (error.Fail())
+ return error;
+
+ src += sizeof(m_vmx_ppc64le);
+ ::memcpy(&m_vsx_ppc64le, src, sizeof(m_vsx_ppc64le));
+ error = WriteVSX();
+
+ return error;
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsGPR(unsigned reg) const {
+ return reg <= k_last_gpr_ppc64le; // GPR's come first.
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsFPR(unsigned reg) const {
+ return (k_first_fpr_ppc64le <= reg && reg <= k_last_fpr_ppc64le);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoReadGPR(
+ void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoWriteGPR(
+ void *buf, size_t buf_size) {
+ int regset = NT_PRSTATUS;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoReadFPR(void *buf,
+ size_t buf_size) {
+ int regset = NT_FPREGSET;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+Status NativeRegisterContextLinux_ppc64le::DoWriteFPR(void *buf,
+ size_t buf_size) {
+ int regset = NT_FPREGSET;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
+ &regset, buf, buf_size);
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::CalculateFprOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(k_first_fpr_ppc64le)->byte_offset;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::CalculateVmxOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(k_first_vmx_ppc64le)->byte_offset;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::CalculateVsxOffset(
+ const RegisterInfo *reg_info) const {
+ return reg_info->byte_offset -
+ GetRegisterInfoAtIndex(k_first_vsx_ppc64le)->byte_offset;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadVMX() {
+ int regset = NT_PPC_VMX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETVRREGS, m_thread.GetID(),
+ &regset, &m_vmx_ppc64le,
+ sizeof(m_vmx_ppc64le));
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteVMX() {
+ int regset = NT_PPC_VMX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETVRREGS, m_thread.GetID(),
+ &regset, &m_vmx_ppc64le,
+ sizeof(m_vmx_ppc64le));
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadVSX() {
+ int regset = NT_PPC_VSX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_GETVSRREGS, m_thread.GetID(),
+ &regset, &m_vsx_ppc64le,
+ sizeof(m_vsx_ppc64le));
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteVSX() {
+ int regset = NT_PPC_VSX;
+ return NativeProcessLinux::PtraceWrapper(PTRACE_SETVSRREGS, m_thread.GetID(),
+ &regset, &m_vsx_ppc64le,
+ sizeof(m_vsx_ppc64le));
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsVMX(unsigned reg) {
+ return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le);
+}
+
+bool NativeRegisterContextLinux_ppc64le::IsVSX(unsigned reg) {
+ return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le);
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::NumSupportedHardwareWatchpoints() {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+
+ // Read hardware breakpoint and watchpoint information.
+ Status error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return 0;
+
+ LLDB_LOG(log, "{0}", m_max_hwp_supported);
+ return m_max_hwp_supported;
+}
+
+uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint(
+ lldb::addr_t addr, size_t size, uint32_t watch_flags) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
+ watch_flags);
+
+ // Read hardware breakpoint and watchpoint information.
+ Status error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return LLDB_INVALID_INDEX32;
+
+ uint32_t control_value = 0, wp_index = 0;
+ lldb::addr_t real_addr = addr;
+ uint32_t rw_mode = 0;
+
+ // Check if we are setting watchpoint other than read/write/access
+ // Update watchpoint flag to match ppc64le write-read bit configuration.
+ switch (watch_flags) {
+ case eWatchpointKindWrite:
+ rw_mode = PPC_BREAKPOINT_TRIGGER_WRITE;
+ watch_flags = 2;
+ break;
+ case eWatchpointKindRead:
+ rw_mode = PPC_BREAKPOINT_TRIGGER_READ;
+ watch_flags = 1;
+ break;
+ case (eWatchpointKindRead | eWatchpointKindWrite):
+ rw_mode = PPC_BREAKPOINT_TRIGGER_RW;
+ break;
+ default:
+ return LLDB_INVALID_INDEX32;
+ }
+
+ // Check if size has a valid hardware watchpoint length.
+ if (size != 1 && size != 2 && size != 4 && size != 8)
+ return LLDB_INVALID_INDEX32;
+
+ // Check 8-byte alignment for hardware watchpoint target address.
+ // Below is a hack to recalculate address and size in order to
+ // make sure we can watch non 8-byte alligned addresses as well.
+ if (addr & 0x07) {
+
+ addr_t begin = llvm::alignDown(addr, 8);
+ addr_t end = llvm::alignTo(addr + size, 8);
+ size = llvm::PowerOf2Ceil(end - begin);
+
+ addr = addr & (~0x07);
+ }
+
+ // Setup control value
+ control_value = watch_flags << 3;
+ control_value |= ((1 << size) - 1) << 5;
+ control_value |= (2 << 1) | 1;
+
+ // Iterate over stored watchpoints and find a free wp_index
+ wp_index = LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ if ((m_hwp_regs[i].control & 1) == 0) {
+ wp_index = i; // Mark last free slot
+ } else if (m_hwp_regs[i].address == addr) {
+ return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
+ }
+ }
+
+ if (wp_index == LLDB_INVALID_INDEX32)
+ return LLDB_INVALID_INDEX32;
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].real_addr = real_addr;
+ m_hwp_regs[wp_index].address = addr;
+ m_hwp_regs[wp_index].control = control_value;
+ m_hwp_regs[wp_index].mode = rw_mode;
+
+ // PTRACE call to set corresponding watchpoint register.
+ error = WriteHardwareDebugRegs();
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
+
+ return LLDB_INVALID_INDEX32;
+ }
+
+ return wp_index;
+}
+
+bool NativeRegisterContextLinux_ppc64le::ClearHardwareWatchpoint(
+ uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ // Read hardware breakpoint and watchpoint information.
+ Status error = ReadHardwareDebugInfo();
+
+ if (error.Fail())
+ return false;
+
+ if (wp_index >= m_max_hwp_supported)
+ return false;
+
+ // Create a backup we can revert to in case of failure.
+ lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+ uint32_t tempControl = m_hwp_regs[wp_index].control;
+ long *tempSlot = reinterpret_cast<long *>(m_hwp_regs[wp_index].slot);
+
+ // Update watchpoint in local cache
+ m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
+ m_hwp_regs[wp_index].address = 0;
+ m_hwp_regs[wp_index].slot = 0;
+ m_hwp_regs[wp_index].mode = 0;
+
+ // Ptrace call to update hardware debug registers
+ error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_DELHWDEBUG,
+ m_thread.GetID(), 0, tempSlot);
+
+ if (error.Fail()) {
+ m_hwp_regs[wp_index].control = tempControl;
+ m_hwp_regs[wp_index].address = tempAddr;
+ m_hwp_regs[wp_index].slot = reinterpret_cast<long>(tempSlot);
+
+ return false;
+ }
+
+ return true;
+}
+
+uint32_t
+NativeRegisterContextLinux_ppc64le::GetWatchpointSize(uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ unsigned control = (m_hwp_regs[wp_index].control >> 5) & 0xff;
+ if (llvm::isPowerOf2_32(control + 1)) {
+ return llvm::countPopulation(control);
+ }
+
+ return 0;
+}
+
+bool NativeRegisterContextLinux_ppc64le::WatchpointIsEnabled(
+ uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ return !!((m_hwp_regs[wp_index].control & 0x1) == 0x1);
+}
+
+Status NativeRegisterContextLinux_ppc64le::GetWatchpointHitIndex(
+ uint32_t &wp_index, lldb::addr_t trap_addr) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
+
+ uint32_t watch_size;
+ lldb::addr_t watch_addr;
+
+ for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
+ watch_size = GetWatchpointSize(wp_index);
+ watch_addr = m_hwp_regs[wp_index].address;
+
+ if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
+ trap_addr <= watch_addr + watch_size) {
+ m_hwp_regs[wp_index].hit_addr = trap_addr;
+ return Status();
+ }
+ }
+
+ wp_index = LLDB_INVALID_INDEX32;
+ return Status();
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_ppc64le::GetWatchpointAddress(uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].real_addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+NativeRegisterContextLinux_ppc64le::GetWatchpointHitAddress(uint32_t wp_index) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
+ LLDB_LOG(log, "wp_index: {0}", wp_index);
+
+ if (wp_index >= m_max_hwp_supported)
+ return LLDB_INVALID_ADDRESS;
+
+ if (WatchpointIsEnabled(wp_index))
+ return m_hwp_regs[wp_index].hit_addr;
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+Status NativeRegisterContextLinux_ppc64le::ReadHardwareDebugInfo() {
+ if (!m_refresh_hwdebug_info) {
+ return Status();
+ }
+
+ ::pid_t tid = m_thread.GetID();
+
+ struct ppc_debug_info hwdebug_info;
+ Status error;
+
+ error = NativeProcessLinux::PtraceWrapper(
+ PPC_PTRACE_GETHWDBGINFO, tid, 0, &hwdebug_info, sizeof(hwdebug_info));
+
+ if (error.Fail())
+ return error;
+
+ m_max_hwp_supported = hwdebug_info.num_data_bps;
+ m_max_hbp_supported = hwdebug_info.num_instruction_bps;
+ m_refresh_hwdebug_info = false;
+
+ return error;
+}
+
+Status NativeRegisterContextLinux_ppc64le::WriteHardwareDebugRegs() {
+ struct ppc_hw_breakpoint reg_state;
+ Status error;
+ long ret;
+
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ reg_state.addr = m_hwp_regs[i].address;
+ reg_state.trigger_type = m_hwp_regs[i].mode;
+ reg_state.version = 1;
+ reg_state.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
+ reg_state.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
+ reg_state.addr2 = 0;
+ reg_state.condition_value = 0;
+
+ error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_SETHWDEBUG,
+ m_thread.GetID(), 0, &reg_state,
+ sizeof(reg_state), &ret);
+
+ if (error.Fail())
+ return error;
+
+ m_hwp_regs[i].slot = ret;
+ }
+
+ return error;
+}
+
+#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
new file mode 100644
index 000000000000..bb25af80d02c
--- /dev/null
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
@@ -0,0 +1,149 @@
+//===-- NativeRegisterContextLinux_ppc64le.h --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This implementation is related to the OpenPOWER ABI for Power Architecture
+// 64-bit ELF V2 ABI
+
+#if defined(__powerpc64__)
+
+#ifndef lldb_NativeRegisterContextLinux_ppc64le_h
+#define lldb_NativeRegisterContextLinux_ppc64le_h
+
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+namespace lldb_private {
+namespace process_linux {
+
+class NativeProcessLinux;
+
+class NativeRegisterContextLinux_ppc64le : public NativeRegisterContextLinux {
+public:
+ NativeRegisterContextLinux_ppc64le(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ //------------------------------------------------------------------
+ // Hardware watchpoint mangement functions
+ //------------------------------------------------------------------
+
+ uint32_t NumSupportedHardwareWatchpoints() override;
+
+ uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags) override;
+
+ bool ClearHardwareWatchpoint(uint32_t hw_index) override;
+
+ Status GetWatchpointHitIndex(uint32_t &wp_index,
+ lldb::addr_t trap_addr) override;
+
+ lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
+
+ lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
+
+ uint32_t GetWatchpointSize(uint32_t wp_index);
+
+ bool WatchpointIsEnabled(uint32_t wp_index);
+
+protected:
+ Status DoReadGPR(void *buf, size_t buf_size) override;
+
+ Status DoWriteGPR(void *buf, size_t buf_size) override;
+
+ Status DoReadFPR(void *buf, size_t buf_size) override;
+
+ Status DoWriteFPR(void *buf, size_t buf_size) override;
+
+ bool IsVMX(unsigned reg);
+
+ bool IsVSX(unsigned reg);
+
+ Status ReadVMX();
+
+ Status WriteVMX();
+
+ Status ReadVSX();
+
+ Status WriteVSX();
+
+ void *GetGPRBuffer() override { return &m_gpr_ppc64le; }
+
+ void *GetFPRBuffer() override { return &m_fpr_ppc64le; }
+
+ size_t GetFPRSize() override { return sizeof(m_fpr_ppc64le); }
+
+private:
+ GPR m_gpr_ppc64le; // 64-bit general purpose registers.
+ FPR m_fpr_ppc64le; // floating-point registers including extended register.
+ VMX m_vmx_ppc64le; // VMX registers.
+ VSX m_vsx_ppc64le; // Last lower bytes from first VSX registers.
+
+ bool IsGPR(unsigned reg) const;
+
+ bool IsFPR(unsigned reg) const;
+
+ bool IsVMX(unsigned reg) const;
+
+ bool IsVSX(unsigned reg) const;
+
+ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
+
+ uint32_t CalculateVmxOffset(const RegisterInfo *reg_info) const;
+
+ uint32_t CalculateVsxOffset(const RegisterInfo *reg_info) const;
+
+ Status ReadHardwareDebugInfo();
+
+ Status WriteHardwareDebugRegs();
+
+ // Debug register info for hardware watchpoints management.
+ struct DREG {
+ lldb::addr_t address; // Breakpoint/watchpoint address value.
+ lldb::addr_t hit_addr; // Address at which last watchpoint trigger
+ // exception occurred.
+ lldb::addr_t real_addr; // Address value that should cause target to stop.
+ uint32_t control; // Breakpoint/watchpoint control value.
+ uint32_t refcount; // Serves as enable/disable and reference counter.
+ long slot; // Saves the value returned from PTRACE_SETHWDEBUG.
+ int mode; // Defines if watchpoint is read/write/access.
+ };
+
+ std::array<DREG, 4> m_hwp_regs;
+
+ // 16 is just a maximum value, query hardware for actual watchpoint count
+ uint32_t m_max_hwp_supported = 16;
+ uint32_t m_max_hbp_supported = 16;
+ bool m_refresh_hwdebug_info = true;
+};
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextLinux_ppc64le_h
+
+#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
index c2a696e08bf9..021394ab154b 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
@@ -97,12 +97,11 @@ static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_s390x(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return llvm::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
+ native_thread);
}
// ----------------------------------------------------------------------------
@@ -117,9 +116,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
CreateRegisterInfoInterface(target_arch)) {
// Set up data about ranges of valid registers.
switch (target_arch.GetMachine()) {
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
index 3ffbaeeb0bba..57b1a0481512 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
@@ -24,8 +24,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index e44e03b46b5c..84ffe9b6e420 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -243,12 +243,11 @@ static inline unsigned int fxsr_regset(const ArchSpec &arch) {
#define mask_XSTATE_BNDCFG (1ULL << 4)
#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
-NativeRegisterContextLinux *
+std::unique_ptr<NativeRegisterContextLinux>
NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextLinux_x86_64(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return std::unique_ptr<NativeRegisterContextLinux>(
+ new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
}
// ----------------------------------------------------------------------------
@@ -270,9 +269,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextLinux(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextLinux(native_thread,
CreateRegisterInfoInterface(target_arch)),
m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(),
m_mpx_set(), m_reg_info(), m_gpr_x86_64() {
@@ -334,11 +332,11 @@ NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
// Initialize m_iovec to point to the buffer and buffer size
// using the conventions of Berkeley style UIO structures, as required
// by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+ m_iovec.iov_base = &m_fpr;
+ m_iovec.iov_len = sizeof(m_fpr);
// Clear out the FPR state.
- ::memset(&m_fpr, 0, sizeof(FPR));
+ ::memset(&m_fpr, 0, sizeof(m_fpr));
// Store byte offset of fctrl (i.e. first register of FPR)
const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
@@ -441,17 +439,14 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
if (byte_order != lldb::eByteOrderInvalid) {
if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- reg_value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- reg_info->byte_size, byte_order);
+ reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- reg_value.SetBytes(
- m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- reg_info->byte_size, byte_order);
+ reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- reg_value.SetBytes(
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- reg_info->byte_size, byte_order);
+ reg_value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
+ reg_info->byte_size, byte_order);
if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
// Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
if (CopyXSTATEtoYMM(reg, byte_order))
@@ -492,7 +487,7 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
- // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ // Get pointer to m_fpr.fxsave variable and set the data from it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
@@ -530,6 +525,22 @@ NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
return error;
}
+void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
+ uint32_t reg_index) {
+ XSAVE_HDR::XFeature &xstate_bv = m_fpr.xsave.header.xstate_bv;
+ if (IsFPR(reg_index)) {
+ // IsFPR considers both %st and %xmm registers as floating point, but these
+ // map to two features. Set both flags, just in case.
+ xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
+ } else if (IsAVX(reg_index)) {
+ // Lower bytes of some %ymm registers are shared with %xmm registers.
+ xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
+ } else if (IsMPX(reg_index)) {
+ // MPX registers map to two XSAVE features.
+ xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
+ }
+}
+
Status NativeRegisterContextLinux_x86_64::WriteRegister(
const RegisterInfo *reg_info, const RegisterValue &reg_value) {
assert(reg_info && "reg_info is null");
@@ -540,25 +551,24 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
? reg_info->name
: "<unknown register>");
+ UpdateXSTATEforWrite(reg_index);
+
if (IsGPR(reg_index))
return WriteRegisterRaw(reg_index, reg_value);
if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
if (reg_info->encoding == lldb::eEncodingVector) {
if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
- ::memcpy(
- m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
+ ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
- ::memcpy(
- m_fpr.xstate.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
+ ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
- ::memcpy(
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
+ ::memcpy(m_fpr.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
+ reg_value.GetBytes(), reg_value.GetByteSize());
if (reg_index >= m_reg_info.first_ymm &&
reg_index <= m_reg_info.last_ymm) {
@@ -586,7 +596,7 @@ Status NativeRegisterContextLinux_x86_64::WriteRegister(
return Status("CopyMPXtoXSTATE() failed");
}
} else {
- // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ // Get pointer to m_fpr.fxsave variable and set the data to it.
// Byte offsets of all registers are calculated wrt 'UserArea' structure.
// However, WriteFPR() takes m_fpr (of type FPR structure) and writes only
@@ -658,7 +668,7 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
dst += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
else if (m_xstate_type == XStateType::XSAVE) {
lldb::ByteOrder byte_order = GetByteOrder();
@@ -749,9 +759,9 @@ Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
src += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
else if (m_xstate_type == XStateType::XSAVE)
- ::memcpy(&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+ ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
error = WriteFPR();
if (error.Fail())
@@ -805,12 +815,12 @@ bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
return true;
case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
// reading in the XCR0 area of XSAVE.
- if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
+ if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
return true;
break;
case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
// reading in the XCR0 area of XSAVE.
- if ((m_fpr.xstate.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
+ if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
return true;
break;
}
@@ -847,11 +857,10 @@ Status NativeRegisterContextLinux_x86_64::WriteFPR() {
switch (m_xstate_type) {
case XStateType::FXSAVE:
return WriteRegisterSet(
- &m_iovec, sizeof(m_fpr.xstate.xsave),
+ &m_iovec, sizeof(m_fpr.fxsave),
fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
case XStateType::XSAVE:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave),
- NT_X86_XSTATE);
+ return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
default:
return Status("Unrecognized FPR type.");
}
@@ -871,11 +880,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
if (byte_order == lldb::eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg),
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
@@ -883,10 +892,10 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
if (byte_order == lldb::eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
sizeof(XMMReg),
- m_fpr.xstate.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
@@ -899,19 +908,19 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
return false;
if (byte_order == lldb::eByteOrderLittle) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(YMMHReg));
return true;
}
if (byte_order == lldb::eByteOrderBig) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true;
}
@@ -921,7 +930,7 @@ bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
switch (m_xstate_type) {
case XStateType::FXSAVE:
- return &m_fpr.xstate.fxsave;
+ return &m_fpr.fxsave;
case XStateType::XSAVE:
return &m_iovec;
default:
@@ -932,7 +941,7 @@ void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
switch (m_xstate_type) {
case XStateType::FXSAVE:
- return sizeof(m_fpr.xstate.fxsave);
+ return sizeof(m_fpr.fxsave);
case XStateType::XSAVE:
return sizeof(m_iovec);
default:
@@ -945,15 +954,14 @@ Status NativeRegisterContextLinux_x86_64::ReadFPR() {
// Probe XSAVE and if it is not supported fall back to FXSAVE.
if (m_xstate_type != XStateType::FXSAVE) {
- error =
- ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ error = ReadRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
if (!error.Fail()) {
m_xstate_type = XStateType::XSAVE;
return error;
}
}
error = ReadRegisterSet(
- &m_iovec, sizeof(m_fpr.xstate.xsave),
+ &m_iovec, sizeof(m_fpr.xsave),
fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
if (!error.Fail()) {
m_xstate_type = XStateType::FXSAVE;
@@ -975,11 +983,11 @@ bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
- m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
sizeof(MPXReg));
} else {
::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
- m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
sizeof(MPXCsr));
}
return true;
@@ -990,10 +998,10 @@ bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
return false;
if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
- ::memcpy(m_fpr.xstate.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
+ ::memcpy(m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
} else {
- ::memcpy(m_fpr.xstate.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
+ ::memcpy(m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
}
return true;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
index abb0dba4d91c..9dcf82f50a45 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
@@ -15,6 +15,7 @@
#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
#include "Plugins/Process/Utility/RegisterContext_x86.h"
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
+#include <sys/uio.h>
namespace lldb_private {
namespace process_linux {
@@ -24,8 +25,7 @@ class NativeProcessLinux;
class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
public:
NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
@@ -110,7 +110,7 @@ private:
// Private member variables.
mutable XStateType m_xstate_type;
FPR m_fpr; // Extended States Area, named FPR for historical reasons.
- IOVEC m_iovec;
+ struct iovec m_iovec;
YMM m_ymm_set;
MPX m_mpx_set;
RegInfo m_reg_info;
@@ -137,6 +137,8 @@ private:
bool CopyMPXtoXSTATE(uint32_t reg);
bool IsMPX(uint32_t reg_index) const;
+
+ void UpdateXSTATEforWrite(uint32_t reg_index);
};
} // namespace process_linux
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index 5cd40941dcf8..0db3bd56b8e4 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -88,7 +88,11 @@ void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
lldb::tid_t tid)
: NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
- m_stop_info(), m_reg_context_sp(), m_stop_description() {}
+ m_stop_info(),
+ m_reg_context_up(
+ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
+ process.GetArchitecture(), *this)),
+ m_stop_description() {}
std::string NativeThreadLinux::GetName() {
NativeProcessLinux &process = GetProcess();
@@ -139,23 +143,6 @@ bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContextSP NativeThreadLinux::GetRegisterContext() {
- // Return the register context if we already created it.
- if (m_reg_context_sp)
- return m_reg_context_sp;
-
- ArchSpec target_arch;
- if (!m_process.GetArchitecture(target_arch))
- return NativeRegisterContextSP();
-
- const uint32_t concrete_frame_idx = 0;
- m_reg_context_sp.reset(
- NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- target_arch, *this, concrete_frame_idx));
-
- return m_reg_context_sp;
-}
-
Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
uint32_t watch_flags, bool hardware) {
if (!hardware)
@@ -165,8 +152,8 @@ Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
Status error = RemoveWatchpoint(addr);
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ uint32_t wp_index =
+ m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
if (wp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware watchpoint failed.");
m_watchpoint_index_map.insert({addr, wp_index});
@@ -179,7 +166,7 @@ Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
return Status();
uint32_t wp_index = wp->second;
m_watchpoint_index_map.erase(wp);
- if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
return Status();
return Status("Clearing hardware watchpoint failed.");
}
@@ -193,8 +180,7 @@ Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
+ uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
if (bp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware breakpoint failed.");
@@ -209,7 +195,7 @@ Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
return Status();
uint32_t bp_index = bp->second;
- if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
+ if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
m_hw_break_index_map.erase(bp);
return Status();
}
@@ -231,7 +217,7 @@ Status NativeThreadLinux::Resume(uint32_t signo) {
NativeProcessLinux &process = GetProcess();
const auto &watchpoint_map = process.GetWatchpointMap();
- GetRegisterContext()->ClearAllHardwareWatchpoints();
+ m_reg_context_up->ClearAllHardwareWatchpoints();
for (const auto &pair : watchpoint_map) {
const auto &wp = pair.second;
SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
@@ -243,7 +229,7 @@ Status NativeThreadLinux::Resume(uint32_t signo) {
NativeProcessLinux &process = GetProcess();
const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
- GetRegisterContext()->ClearAllHardwareBreakpoints();
+ m_reg_context_up->ClearAllHardwareBreakpoints();
for (const auto &pair : hw_breakpoint_map) {
const auto &bp = pair.second;
SetHardwareBreakpoint(bp.m_addr, bp.m_size);
@@ -365,7 +351,7 @@ void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
std::ostringstream ostr;
- ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
ostr << wp_index;
/*
@@ -379,7 +365,7 @@ void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
* stop-info
* packet.
*/
- ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+ ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
m_stop_description = ostr.str();
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
index 6ae87feffcda..a7c4e982012d 100644
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ b/source/Plugins/Process/Linux/NativeThreadLinux.h
@@ -10,7 +10,8 @@
#ifndef liblldb_NativeThreadLinux_H_
#define liblldb_NativeThreadLinux_H_
-#include "SingleStepCheck.h"
+#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
+#include "Plugins/Process/Linux/SingleStepCheck.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
#include "lldb/lldb-private-forward.h"
@@ -40,7 +41,9 @@ public:
bool GetStopReason(ThreadStopInfo &stop_info,
std::string &description) override;
- NativeRegisterContextSP GetRegisterContext() override;
+ NativeRegisterContextLinux &GetRegisterContext() override {
+ return *m_reg_context_up;
+ }
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
bool hardware) override;
@@ -103,15 +106,13 @@ private:
// ---------------------------------------------------------------------
lldb::StateType m_state;
ThreadStopInfo m_stop_info;
- NativeRegisterContextSP m_reg_context_sp;
+ std::unique_ptr<NativeRegisterContextLinux> m_reg_context_up;
std::string m_stop_description;
using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
WatchpointIndexMap m_watchpoint_index_map;
WatchpointIndexMap m_hw_break_index_map;
std::unique_ptr<SingleStepWorkaround> m_step_workaround;
};
-
-typedef std::shared_ptr<NativeThreadLinux> NativeThreadLinuxSP;
} // namespace process_linux
} // namespace lldb_private
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 52b9441e0e79..b4eae58af83c 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -17,12 +17,12 @@
#include <vector>
// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ThreadSafeValue.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
index ae2f11f38006..1902cc492ff4 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
@@ -12,13 +12,13 @@
#include "lldb/Utility/SafeMachO.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 388989a21f76..387f04afa5b4 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -109,10 +109,8 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
if (status.Fail())
return status.ToError();
- for (const auto &thread_sp : process_up->m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
- SIGSTOP);
- }
+ for (const auto &thread : process_up->m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
process_up->SetState(StateType::eStateStopped);
return std::move(process_up);
@@ -198,9 +196,9 @@ void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
// Handle SIGSTOP from LLGS (LLDB GDB Server)
if (info.psi_siginfo.si_code == SI_USER &&
info.psi_siginfo.si_pid == ::getpid()) {
- /* Stop Tracking All Threads attached to Process */
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ /* Stop Tracking all Threads attached to Process */
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(
SIGSTOP, &info.psi_siginfo);
}
}
@@ -221,18 +219,15 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
switch (info.psi_siginfo.si_code) {
case TRAP_BRKPT:
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByBreakpoint();
- FixupBreakpointPCAsNeeded(
- *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByBreakpoint();
+ FixupBreakpointPCAsNeeded(static_cast<NativeThreadNetBSD &>(*thread));
}
SetState(StateType::eStateStopped, true);
break;
case TRAP_TRACE:
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByTrace();
SetState(StateType::eStateStopped, true);
break;
case TRAP_EXEC: {
@@ -245,38 +240,35 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
// Let our delegate know we have just exec'd.
NotifyDidExec();
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByExec();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByExec();
SetState(StateType::eStateStopped, true);
} break;
case TRAP_DBREG: {
// If a watchpoint was hit, report it
uint32_t wp_index;
- Status error =
- static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
- ->GetRegisterContext()
- ->GetWatchpointHitIndex(wp_index,
- (uintptr_t)info.psi_siginfo.si_addr);
+ Status error = static_cast<NativeThreadNetBSD &>(*m_threads[info.psi_lwpid])
+ .GetRegisterContext()
+ .GetWatchpointHitIndex(
+ wp_index, (uintptr_t)info.psi_siginfo.si_addr);
if (error.Fail())
LLDB_LOG(log,
"received error while checking for watchpoint hits, pid = "
"{0}, LWP = {1}, error = {2}",
GetID(), info.psi_lwpid, error);
if (wp_index != LLDB_INVALID_INDEX32) {
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByWatchpoint(wp_index);
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByWatchpoint(
+ wp_index);
SetState(StateType::eStateStopped, true);
break;
}
// If a breakpoint was hit, report it
uint32_t bp_index;
- error = static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
- ->GetRegisterContext()
- ->GetHardwareBreakHitIndex(bp_index,
+ error = static_cast<NativeThreadNetBSD &>(*m_threads[info.psi_lwpid])
+ .GetRegisterContext()
+ .GetHardwareBreakHitIndex(bp_index,
(uintptr_t)info.psi_siginfo.si_addr);
if (error.Fail())
LLDB_LOG(log,
@@ -284,10 +276,8 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
"breakpoint hits, pid = {0}, LWP = {1}, error = {2}",
GetID(), info.psi_lwpid, error);
if (bp_index != LLDB_INVALID_INDEX32) {
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)
- ->SetStoppedByBreakpoint();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByBreakpoint();
SetState(StateType::eStateStopped, true);
break;
}
@@ -300,8 +290,8 @@ void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
const auto siginfo_err =
PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ for (const auto &thread : m_threads) {
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(
info.psi_siginfo.si_signo, &info.psi_siginfo);
}
SetState(StateType::eStateStopped, true);
@@ -351,12 +341,7 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
Status error;
// Find out the size of a breakpoint (might depend on where we are in the
// code).
- NativeRegisterContextSP context_sp = thread.GetRegisterContext();
- if (!context_sp) {
- error.SetErrorString("cannot get a NativeRegisterContext for the thread");
- LLDB_LOG(log, "failed: {0}", error);
- return error;
- }
+ NativeRegisterContext& context = thread.GetRegisterContext();
uint32_t breakpoint_size = 0;
error = GetSoftwareBreakpointPCOffset(breakpoint_size);
if (error.Fail()) {
@@ -367,7 +352,7 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
// First try probing for a breakpoint at a software breakpoint location: PC
// - breakpoint size.
const lldb::addr_t initial_pc_addr =
- context_sp->GetPCfromBreakpointLocation();
+ context.GetPCfromBreakpointLocation();
lldb::addr_t breakpoint_addr = initial_pc_addr;
if (breakpoint_size > 0) {
// Do not allow breakpoint probe to wrap around.
@@ -420,7 +405,7 @@ NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
// Change the program counter.
LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
thread.GetID(), initial_pc_addr, breakpoint_addr);
- error = context_sp->SetPC(breakpoint_addr);
+ error = context.SetPC(breakpoint_addr);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
thread.GetID(), error);
@@ -433,13 +418,13 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid {0}", GetID());
- const auto &thread_sp = m_threads[0];
+ const auto &thread = m_threads[0];
const ResumeAction *const action =
- resume_actions.GetActionForThread(thread_sp->GetID(), true);
+ resume_actions.GetActionForThread(thread->GetID(), true);
if (action == nullptr) {
LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread_sp->GetID());
+ thread->GetID());
return Status();
}
@@ -452,9 +437,8 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
action->signal);
if (!error.Success())
return error;
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetRunning();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetRunning();
SetState(eStateRunning, true);
break;
}
@@ -464,9 +448,8 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
action->signal);
if (!error.Success())
return error;
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStepping();
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStepping();
SetState(eStateStepping, true);
break;
@@ -478,7 +461,7 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
return Status("NativeProcessNetBSD::%s (): unexpected state %s specified "
"for pid %" PRIu64 ", tid %" PRIu64,
__FUNCTION__, StateAsCString(action->state), GetID(),
- thread_sp->GetID());
+ thread->GetID());
}
return Status();
@@ -690,11 +673,6 @@ lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); }
-bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const {
- arch = m_arch;
- return true;
-}
-
Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) {
if (hardware)
@@ -764,9 +742,9 @@ void NativeProcessNetBSD::SigchldHandler() {
}
bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
- for (auto thread_sp : m_threads) {
- assert(thread_sp && "thread list should not contain NULL threads");
- if (thread_sp->GetID() == thread_id) {
+ for (const auto &thread : m_threads) {
+ assert(thread && "thread list should not contain NULL threads");
+ if (thread->GetID() == thread_id) {
// We have this thread.
return true;
}
@@ -776,7 +754,7 @@ bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
return false;
}
-NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
+NativeThreadNetBSD &NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
@@ -788,9 +766,8 @@ NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
if (m_threads.empty())
SetCurrentThreadID(thread_id);
- auto thread_sp = std::make_shared<NativeThreadNetBSD>(*this, thread_id);
- m_threads.push_back(thread_sp);
- return thread_sp;
+ m_threads.push_back(llvm::make_unique<NativeThreadNetBSD>(*this, thread_id));
+ return static_cast<NativeThreadNetBSD &>(*m_threads.back());
}
Status NativeProcessNetBSD::Attach() {
@@ -811,10 +788,8 @@ Status NativeProcessNetBSD::Attach() {
if (status.Fail())
return status;
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
- SIGSTOP);
- }
+ for (const auto &thread : m_threads)
+ static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
// Let our process instance know the thread has stopped.
SetState(StateType::eStateStopped);
@@ -928,7 +903,7 @@ Status NativeProcessNetBSD::ReinitializeThreads() {
}
// Reinitialize from scratch threads and register them in process
while (info.pl_lwpid != 0) {
- NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
+ AddThread(info.pl_lwpid);
error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
if (error.Fail()) {
return error;
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 2cbd5e30ab23..7090fce34fc9 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -10,12 +10,8 @@
#ifndef liblldb_NativeProcessNetBSD_H_
#define liblldb_NativeProcessNetBSD_H_
-// C++ Includes
-
-// Other libraries and framework includes
-
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "NativeThreadNetBSD.h"
@@ -77,7 +73,7 @@ public:
size_t UpdateThreads() override;
- bool GetArchitecture(ArchSpec &arch) const override;
+ const ArchSpec &GetArchitecture() const override { return m_arch; }
Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
bool hardware) override;
@@ -121,7 +117,7 @@ private:
bool HasThreadNoLock(lldb::tid_t thread_id);
- NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id);
+ NativeThreadNetBSD &AddThread(lldb::tid_t thread_id);
void MonitorCallback(lldb::pid_t pid, int signal);
void MonitorExited(lldb::pid_t pid, WaitStatus status);
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
index dde86880c41a..d4fef6342439 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -20,9 +20,9 @@ using namespace lldb_private::process_netbsd;
// clang-format on
NativeRegisterContextNetBSD::NativeRegisterContextNetBSD(
- NativeThreadProtocol &native_thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &native_thread,
RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread, concrete_frame_idx,
+ : NativeRegisterContextRegisterInfo(native_thread,
reg_info_interface_p) {}
Status NativeRegisterContextNetBSD::ReadGPR() {
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
index d96b7aea0048..b81430e7f5ac 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
@@ -21,7 +21,6 @@ namespace process_netbsd {
class NativeRegisterContextNetBSD : public NativeRegisterContextRegisterInfo {
public:
NativeRegisterContextNetBSD(NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx,
RegisterInfoInterface *reg_info_interface_p);
// This function is implemented in the NativeRegisterContextNetBSD_*
@@ -31,8 +30,7 @@ public:
// executable.
static NativeRegisterContextNetBSD *
CreateHostNativeRegisterContextNetBSD(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
protected:
virtual Status ReadGPR();
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 9690da0e1374..347c15ae5b23 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -149,10 +149,8 @@ const int fpu_save = []() -> int {
NativeRegisterContextNetBSD *
NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx) {
- return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread,
- concrete_frame_idx);
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextNetBSD_x86_64(target_arch, native_thread);
}
// ----------------------------------------------------------------------------
@@ -169,9 +167,8 @@ CreateRegisterInfoInterface(const ArchSpec &target_arch) {
}
NativeRegisterContextNetBSD_x86_64::NativeRegisterContextNetBSD_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx)
- : NativeRegisterContextNetBSD(native_thread, concrete_frame_idx,
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextNetBSD(native_thread,
CreateRegisterInfoInterface(target_arch)),
m_gpr_x86_64(), m_fpr_x86_64(), m_dbr_x86_64() {}
diff --git a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index 5f5a6a0792e4..c55ddfec6615 100644
--- a/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -30,8 +30,7 @@ class NativeProcessNetBSD;
class NativeRegisterContextNetBSD_x86_64 : public NativeRegisterContextNetBSD {
public:
NativeRegisterContextNetBSD_x86_64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread,
- uint32_t concrete_frame_idx);
+ NativeThreadProtocol &native_thread);
uint32_t GetRegisterSetCount() const override;
const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index 1fd7400bf800..83f1da78d01d 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -27,7 +27,9 @@ using namespace lldb_private::process_netbsd;
NativeThreadNetBSD::NativeThreadNetBSD(NativeProcessNetBSD &process,
lldb::tid_t tid)
: NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
- m_stop_info(), m_reg_context_sp(), m_stop_description() {}
+ m_stop_info(), m_reg_context_up(
+NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(process.GetArchitecture(), *this)
+), m_stop_description() {}
void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo,
const siginfo_t *info) {
@@ -77,10 +79,10 @@ void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
std::ostringstream ostr;
- ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
+ ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
ostr << wp_index;
- ostr << " " << GetRegisterContext()->GetWatchpointHitAddress(wp_index);
+ ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
m_stop_description = ostr.str();
@@ -139,21 +141,9 @@ bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContextSP NativeThreadNetBSD::GetRegisterContext() {
- // Return the register context if we already created it.
- if (m_reg_context_sp)
- return m_reg_context_sp;
-
- ArchSpec target_arch;
- if (!m_process.GetArchitecture(target_arch))
- return NativeRegisterContextSP();
-
- const uint32_t concrete_frame_idx = 0;
- m_reg_context_sp.reset(
- NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
- target_arch, *this, concrete_frame_idx));
-
- return m_reg_context_sp;
+NativeRegisterContext& NativeThreadNetBSD::GetRegisterContext() {
+ assert(m_reg_context_up);
+return *m_reg_context_up;
}
Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
@@ -165,8 +155,7 @@ Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
Status error = RemoveWatchpoint(addr);
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t wp_index = reg_ctx->SetHardwareWatchpoint(addr, size, watch_flags);
+ uint32_t wp_index = GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
if (wp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware watchpoint failed.");
m_watchpoint_index_map.insert({addr, wp_index});
@@ -179,7 +168,7 @@ Status NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
return Status();
uint32_t wp_index = wp->second;
m_watchpoint_index_map.erase(wp);
- if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
+ if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
return Status();
return Status("Clearing hardware watchpoint failed.");
}
@@ -193,8 +182,7 @@ Status NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
if (error.Fail())
return error;
- NativeRegisterContextSP reg_ctx = GetRegisterContext();
- uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
+ uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);
if (bp_index == LLDB_INVALID_INDEX32)
return Status("Setting hardware breakpoint failed.");
@@ -209,7 +197,7 @@ Status NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
return Status();
uint32_t bp_index = bp->second;
- if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
+ if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
m_hw_break_index_map.erase(bp);
return Status();
}
diff --git a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index 1e3f587be5f5..72426244c112 100644
--- a/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -37,7 +37,7 @@ public:
bool GetStopReason(ThreadStopInfo &stop_info,
std::string &description) override;
- NativeRegisterContextSP GetRegisterContext() override;
+ NativeRegisterContext& GetRegisterContext() override;
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
bool hardware) override;
@@ -67,7 +67,7 @@ private:
// ---------------------------------------------------------------------
lldb::StateType m_state;
ThreadStopInfo m_stop_info;
- NativeRegisterContextSP m_reg_context_sp;
+ std::unique_ptr<NativeRegisterContext> m_reg_context_up;
std::string m_stop_description;
using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
WatchpointIndexMap m_watchpoint_index_map;
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
index bda0ad626f6f..3780fb5e4c18 100644
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/source/Plugins/Process/Utility/CMakeLists.txt
@@ -39,11 +39,13 @@ add_lldb_library(lldbPluginProcessUtility PLUGIN
RegisterContextPOSIX_arm64.cpp
RegisterContextPOSIX_mips64.cpp
RegisterContextPOSIX_powerpc.cpp
+ RegisterContextPOSIX_ppc64le.cpp
RegisterContextPOSIX_s390x.cpp
RegisterContextPOSIX_x86.cpp
RegisterContextThreadMemory.cpp
RegisterInfoPOSIX_arm.cpp
RegisterInfoPOSIX_arm64.cpp
+ RegisterInfoPOSIX_ppc64le.cpp
StopInfoMachException.cpp
ThreadMemory.cpp
UnwindLLDB.cpp
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
index 1a4511a82230..61e5bf4481d6 100644
--- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -9,14 +9,10 @@
#include "DynamicRegisterInfo.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 4e1f10c6ae18..5c51a035ec66 100644
--- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -64,7 +64,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
options.SetTimeout(std::chrono::milliseconds(500));
options.SetTrapExceptions(false);
- addr_t prot_arg, flags_arg = 0;
+ addr_t prot_arg;
if (prot == eMmapProtNone)
prot_arg = PROT_NONE;
else {
@@ -77,11 +77,6 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
prot_arg |= PROT_WRITE;
}
- const ArchSpec arch = process->GetTarget().GetArchitecture();
- flags_arg =
- process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,
- flags);
-
AddressRange mmap_range;
if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
mmap_range)) {
@@ -89,7 +84,10 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
process->GetTarget().GetScratchClangASTContext();
CompilerType clang_void_ptr_type =
clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
- lldb::addr_t args[] = {addr, length, prot_arg, flags_arg, fd, offset};
+ const ArchSpec arch = process->GetTarget().GetArchitecture();
+ MmapArgList args =
+ process->GetTarget().GetPlatform()->GetMmapArgumentList(
+ arch, addr, length, prot_arg, flags, fd, offset);
lldb::ThreadPlanSP call_plan_sp(
new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
clang_void_ptr_type, args, options));
diff --git a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
index 0b1814362425..3a9d497711c0 100644
--- a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
+++ b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.cpp
@@ -14,9 +14,9 @@
using namespace lldb_private;
NativeRegisterContextRegisterInfo::NativeRegisterContextRegisterInfo(
- NativeThreadProtocol &thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &thread,
RegisterInfoInterface *register_info_interface)
- : NativeRegisterContext(thread, concrete_frame_idx),
+ : NativeRegisterContext(thread),
m_register_info_interface_up(register_info_interface) {
assert(register_info_interface && "null register_info_interface");
}
diff --git a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
index c1b597462b60..8f2e4409105f 100644
--- a/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
+++ b/source/Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h
@@ -23,7 +23,7 @@ public:
/// of the register_info_interface pointer.
///
NativeRegisterContextRegisterInfo(
- NativeThreadProtocol &thread, uint32_t concrete_frame_idx,
+ NativeThreadProtocol &thread,
RegisterInfoInterface *register_info_interface);
uint32_t GetRegisterCount() const override;
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
index 0c36f1a8346c..344c08965fad 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -426,7 +426,7 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size,
+ value.SetBytes(fpu.v[reg].bytes.buffer, reg_info->byte_size,
endian::InlHostByteOrder());
break;
@@ -618,7 +618,7 @@ bool RegisterContextDarwin_arm64::WriteRegister(const RegisterInfo *reg_info,
case fpu_v29:
case fpu_v30:
case fpu_v31:
- ::memcpy(fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize());
+ ::memcpy(fpu.v[reg].bytes.buffer, value.GetBytes(), value.GetByteSize());
break;
case fpu_fpsr:
diff --git a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
index 2d1fe0555b58..4a0e50947ee7 100644
--- a/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ b/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -78,7 +78,7 @@ public:
};
struct VReg {
- uint8_t bytes[16];
+ llvm::AlignedCharArray<16, 16> bytes;
};
// mirrors <mach/arm/thread_status.h> arm_neon_state64_t
diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index bd73a29e0871..5435a02433ab 100644
--- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -1517,8 +1517,8 @@ RegisterContextLLDB::SavedLocationForRegister(
dwarfexpr.SetRegisterKind(unwindplan_registerkind);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
- nullptr, result, &error)) {
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
+ &error)) {
addr_t val;
val = result.GetScalar().ULongLong();
if (unwindplan_regloc.IsDWARFExpression()) {
@@ -1827,8 +1827,8 @@ bool RegisterContextLLDB::ReadCFAValueForRow(
dwarfexpr.SetRegisterKind(row_register_kind);
Value result;
Status error;
- if (dwarfexpr.Evaluate(&exe_ctx, nullptr, nullptr, this, 0, nullptr,
- nullptr, result, &error)) {
+ if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result,
+ &error)) {
cfa_value = result.GetScalar().ULongLong();
UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64,
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
index a4cf07710194..71d35bbd3938 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp
@@ -50,22 +50,30 @@ int RegisterContextMach_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
int RegisterContextMach_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)),
+ GPRWordCount);
}
int RegisterContextMach_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)),
+ FPUWordCount);
}
int RegisterContextMach_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)),
+ EXCWordCount);
}
int RegisterContextMach_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
const DBG &dbg) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<DBG *>(&dbg)),
+ DBGWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
index 959149edbc3e..5a260d5de1d5 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp
@@ -43,17 +43,23 @@ int RegisterContextMach_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
int RegisterContextMach_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)),
+ GPRWordCount);
}
int RegisterContextMach_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)),
+ FPUWordCount);
}
int RegisterContextMach_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)),
+ EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
index 522b73a2888e..0180879d51ee 100644
--- a/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp
@@ -46,17 +46,23 @@ int RegisterContextMach_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
int RegisterContextMach_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
const GPR &gpr) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<GPR *>(&gpr)),
+ GPRWordCount);
}
int RegisterContextMach_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
const FPU &fpu) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<FPU *>(&fpu)),
+ FPUWordCount);
}
int RegisterContextMach_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
const EXC &exc) {
- return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
+ return ::thread_set_state(
+ tid, flavor, reinterpret_cast<thread_state_t>(const_cast<EXC *>(&exc)),
+ EXCWordCount);
}
#endif
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
new file mode 100644
index 000000000000..de410f063b53
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp
@@ -0,0 +1,216 @@
+//===-- RegisterContextPOSIX_ppc64le.cpp -------------------------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstring>
+#include <errno.h>
+#include <stdint.h>
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "llvm/Support/Compiler.h"
+
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
+#include "RegisterContextPOSIX_ppc64le.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+static const uint32_t g_gpr_regnums[] = {
+ gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
+ gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
+ gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
+ gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
+ gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
+ gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
+ gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
+ gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le,
+ gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le,
+ gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le,
+ gpr_trap_ppc64le,
+};
+
+static const uint32_t g_fpr_regnums[] = {
+ fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le,
+ fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le,
+ fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le,
+ fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le,
+ fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le,
+ fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_ppc64le,
+ fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le,
+ fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le,
+ fpr_fpscr_ppc64le,
+};
+
+static const uint32_t g_vmx_regnums[] = {
+ vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le,
+ vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le,
+ vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le,
+ vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le,
+ vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le,
+ vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_ppc64le,
+ vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le,
+ vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le,
+ vmx_vscr_ppc64le, vmx_vrsave_ppc64le,
+};
+
+static const uint32_t g_vsx_regnums[] = {
+ vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le,
+ vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le,
+ vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le,
+ vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le,
+ vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le,
+ vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le,
+ vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le,
+ vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le,
+ vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le,
+ vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le,
+ vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le,
+ vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le,
+ vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_ppc64le,
+ vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le,
+ vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le,
+ vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le,
+};
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 4 };
+
+static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
+ g_gpr_regnums},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le,
+ g_fpr_regnums},
+ {"Altivec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le,
+ g_vmx_regnums},
+ {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le, g_vsx_regnums},
+};
+
+bool RegisterContextPOSIX_ppc64le::IsGPR(unsigned reg) {
+ return (reg <= k_last_gpr_ppc64le); // GPR's come first.
+}
+
+bool RegisterContextPOSIX_ppc64le::IsFPR(unsigned reg) {
+ return (reg >= k_first_fpr_ppc64le) && (reg <= k_last_fpr_ppc64le);
+}
+
+bool RegisterContextPOSIX_ppc64le::IsVMX(unsigned reg) {
+ return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le);
+}
+
+bool RegisterContextPOSIX_ppc64le::IsVSX(unsigned reg) {
+ return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le);
+}
+
+RegisterContextPOSIX_ppc64le::RegisterContextPOSIX_ppc64le(
+ Thread &thread, uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx) {
+ m_register_info_ap.reset(register_info);
+
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
+}
+
+void RegisterContextPOSIX_ppc64le::InvalidateAllRegisters() {}
+
+unsigned RegisterContextPOSIX_ppc64le::GetRegisterOffset(unsigned reg) {
+ assert(reg < k_num_registers_ppc64le && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned RegisterContextPOSIX_ppc64le::GetRegisterSize(unsigned reg) {
+ assert(reg < k_num_registers_ppc64le && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
+}
+
+size_t RegisterContextPOSIX_ppc64le::GetRegisterCount() {
+ size_t num_registers = k_num_registers_ppc64le;
+ return num_registers;
+}
+
+size_t RegisterContextPOSIX_ppc64le::GetGPRSize() {
+ return m_register_info_ap->GetGPRSize();
+}
+
+const RegisterInfo *RegisterContextPOSIX_ppc64le::GetRegisterInfo() {
+ // Commonly, this method is overridden and g_register_infos is copied and
+ // specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_ppc64le::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < k_num_registers_ppc64le)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
+}
+
+size_t RegisterContextPOSIX_ppc64le::GetRegisterSetCount() {
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set) {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
+}
+
+const RegisterSet *RegisterContextPOSIX_ppc64le::GetRegisterSet(size_t set) {
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_ppc64le[set];
+ else
+ return NULL;
+}
+
+const char *RegisterContextPOSIX_ppc64le::GetRegisterName(unsigned reg) {
+ assert(reg < k_num_registers_ppc64le && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
+}
+
+lldb::ByteOrder RegisterContextPOSIX_ppc64le::GetByteOrder() {
+ // Get the target process whose privileged thread was used for the register
+ // read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
+
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
+}
+
+bool RegisterContextPOSIX_ppc64le::IsRegisterSetAvailable(size_t set_index) {
+ size_t num_sets = k_num_register_sets;
+
+ return (set_index < num_sets);
+}
+
+// Used when parsing DWARF and EH frame information and any other
+// object file sections that contain register numbers in them.
+uint32_t RegisterContextPOSIX_ppc64le::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;
+}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
new file mode 100644
index 000000000000..1070b4dea405
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h
@@ -0,0 +1,82 @@
+//===-- RegisterContextPOSIX_ppc64le.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_RegisterContextPOSIX_ppc64le_h_
+#define liblldb_RegisterContextPOSIX_ppc64le_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+#include "RegisterInfoInterface.h"
+#include "Utility/PPC64LE_DWARF_Registers.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Log.h"
+
+class RegisterContextPOSIX_ppc64le : public lldb_private::RegisterContext {
+public:
+ RegisterContextPOSIX_ppc64le(
+ lldb_private::Thread &thread, uint32_t concrete_frame_idx,
+ lldb_private::RegisterInfoInterface *register_info);
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ virtual size_t GetGPRSize();
+
+ virtual unsigned GetRegisterSize(unsigned reg);
+
+ virtual unsigned GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+ const char *GetRegisterName(unsigned reg);
+
+ uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+ uint32_t num) override;
+
+protected:
+ // 64-bit general purpose registers.
+ uint64_t m_gpr_ppc64le[k_num_gpr_registers_ppc64le];
+
+ // floating-point registers including extended register.
+ uint64_t m_fpr_ppc64le[k_num_fpr_registers_ppc64le];
+
+ // VMX registers.
+ uint64_t m_vmx_ppc64le[k_num_vmx_registers_ppc64le * 2];
+
+ // VSX registers.
+ uint64_t m_vsx_ppc64le[k_num_vsx_registers_ppc64le * 2];
+
+ std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap;
+
+ // Determines if an extended register set is supported on the processor
+ // running the inferior process.
+ virtual bool IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ bool IsVMX(unsigned reg);
+
+ bool IsVSX(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+};
+
+#endif // liblldb_RegisterContextPOSIX_ppc64le_h_
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
index 5e1bf35356b8..41cec8add987 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp
@@ -365,12 +365,6 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(
break;
}
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
-
::memset(&m_fpr, 0, sizeof(FPR));
m_fpr_type = eNotValid;
@@ -481,19 +475,19 @@ bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg,
return false;
if (byte_order == eByteOrderLittle) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(YMMHReg));
return true;
}
if (byte_order == eByteOrderBig) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
sizeof(XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
return true;
}
@@ -508,20 +502,20 @@ bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg,
if (byte_order == eByteOrderLittle) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
if (byte_order == eByteOrderBig) {
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
sizeof(XMMReg));
::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
sizeof(YMMHReg));
return true;
}
diff --git a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
index aa689273f218..ca71a6f272f8 100644
--- a/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h
@@ -149,9 +149,9 @@ protected:
RegInfo m_reg_info;
FPRType
m_fpr_type; // determines the type of data stored by union FPR, if any.
- FPR m_fpr; // floating-point registers including extended register sets.
- IOVEC m_iovec; // wrapper for xsave.
- YMM m_ymm_set; // copy of ymmh and xmm register halves.
+ lldb_private::FPR m_fpr; // floating-point registers including extended
+ // register sets.
+ lldb_private::YMM m_ymm_set; // copy of ymmh and xmm register halves.
std::unique_ptr<lldb_private::RegisterInfoInterface>
m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
diff --git a/source/Plugins/Process/Utility/RegisterContext_mips.h b/source/Plugins/Process/Utility/RegisterContext_mips.h
index 565747cb4bd7..da470bd82732 100644
--- a/source/Plugins/Process/Utility/RegisterContext_mips.h
+++ b/source/Plugins/Process/Utility/RegisterContext_mips.h
@@ -241,11 +241,6 @@ enum {
dwarf_config5_mips64,
};
-struct IOVEC_mips {
- void *iov_base;
- size_t iov_len;
-};
-
// GP registers
struct GPR_linux_mips {
uint64_t zero;
diff --git a/source/Plugins/Process/Utility/RegisterContext_x86.h b/source/Plugins/Process/Utility/RegisterContext_x86.h
index 5f6fc295a15c..6146dcaf7e5a 100644
--- a/source/Plugins/Process/Utility/RegisterContext_x86.h
+++ b/source/Plugins/Process/Utility/RegisterContext_x86.h
@@ -13,8 +13,10 @@
#include <cstddef>
#include <cstdint>
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/Support/Compiler.h"
+namespace lldb_private {
//---------------------------------------------------------------------------
// i386 ehframe, dwarf regnums
//---------------------------------------------------------------------------
@@ -313,13 +315,28 @@ struct MPX {
LLVM_PACKED_START
struct XSAVE_HDR {
- uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states
+ enum class XFeature : uint64_t {
+ FP = 1,
+ SSE = FP << 1,
+ YMM = SSE << 1,
+ BNDREGS = YMM << 1,
+ BNDCSR = BNDREGS << 1,
+ OPMASK = BNDCSR << 1,
+ ZMM_Hi256 = OPMASK << 1,
+ Hi16_ZMM = ZMM_Hi256 << 1,
+ PT = Hi16_ZMM << 1,
+ PKRU = PT << 1,
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ PKRU)
+ };
+
+ XFeature xstate_bv; // OS enabled xstate mask to determine the extended states
// supported by the processor
- uint64_t xcomp_bv; // Mask to indicate the format of the XSAVE area and of
+ XFeature xcomp_bv; // Mask to indicate the format of the XSAVE area and of
// the XRSTOR instruction
uint64_t reserved1[1];
uint64_t reserved2[5];
};
+static_assert(sizeof(XSAVE_HDR) == 64, "XSAVE_HDR layout incorrect");
LLVM_PACKED_END
// x86 extensions to FXSAVE (i.e. for AVX and MPX processors)
@@ -338,21 +355,13 @@ struct LLVM_ALIGNAS(64) XSAVE {
LLVM_PACKED_END
// Floating-point registers
-struct FPR {
- // Thread state for the floating-point unit of the processor read by ptrace.
- union XSTATE {
- FXSAVE fxsave; // Generic floating-point registers.
- XSAVE xsave; // x86 extended processor state.
- } xstate;
+union FPR {
+ FXSAVE fxsave; // Generic floating-point registers.
+ XSAVE xsave; // x86 extended processor state.
};
-//---------------------------------------------------------------------------
-// ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure
-//---------------------------------------------------------------------------
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
-struct IOVEC {
- void *iov_base; // pointer to XSAVE
- size_t iov_len; // sizeof(XSAVE)
-};
+} // namespace lldb_private
#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfoInterface.h b/source/Plugins/Process/Utility/RegisterInfoInterface.h
index 74d5d6e50208..1894b5368122 100644
--- a/source/Plugins/Process/Utility/RegisterInfoInterface.h
+++ b/source/Plugins/Process/Utility/RegisterInfoInterface.h
@@ -10,10 +10,9 @@
#ifndef lldb_RegisterInfoInterface_h
#define lldb_RegisterInfoInterface_h
-#include <vector>
-
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/lldb-private-types.h"
+#include <vector>
namespace lldb_private {
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
new file mode 100644
index 000000000000..e5e7350fe68a
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.cpp
@@ -0,0 +1,66 @@
+//===-- RegisterInfoPOSIX_ppc64le.cpp --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <cassert>
+#include <stddef.h>
+#include <vector>
+
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
+
+#include "RegisterInfoPOSIX_ppc64le.h"
+
+//-----------------------------------------------------------------------------
+// Include RegisterInfoPOSIX_ppc64le to declare our g_register_infos_ppc64le
+//-----------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+#include "RegisterInfos_ppc64le.h"
+#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+static const lldb_private::RegisterInfo *
+GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return g_register_infos_ppc64le;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
+
+static uint32_t
+GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::ppc64le:
+ return static_cast<uint32_t>(sizeof(g_register_infos_ppc64le) /
+ sizeof(g_register_infos_ppc64le[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+RegisterInfoPOSIX_ppc64le::RegisterInfoPOSIX_ppc64le(
+ const lldb_private::ArchSpec &target_arch)
+ : lldb_private::RegisterInfoInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)) {}
+
+size_t RegisterInfoPOSIX_ppc64le::GetGPRSize() const {
+ return sizeof(GPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterInfoPOSIX_ppc64le::GetRegisterInfo() const {
+ return m_register_info_p;
+}
+
+uint32_t RegisterInfoPOSIX_ppc64le::GetRegisterCount() const {
+ return m_register_info_count;
+}
diff --git a/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
new file mode 100644
index 000000000000..411ab05c2b13
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h
@@ -0,0 +1,32 @@
+//===-- RegisterInfoPOSIX_ppc64le.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_RegisterContextLinux_ppc64le_H_
+#define liblldb_RegisterContextLinux_ppc64le_H_
+
+#include "RegisterInfoInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/lldb-private.h"
+
+class RegisterInfoPOSIX_ppc64le : public lldb_private::RegisterInfoInterface {
+public:
+ RegisterInfoPOSIX_ppc64le(const lldb_private::ArchSpec &target_arch);
+
+ size_t GetGPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+};
+
+#endif
diff --git a/source/Plugins/Process/Utility/RegisterInfos_i386.h b/source/Plugins/Process/Utility/RegisterInfos_i386.h
index 8597d0c39dc4..ffdc4d0d116b 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_i386.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_i386.h
@@ -27,19 +27,19 @@
// Based on DNBArchImplI386.cpp from debugserver
#define YMM_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FPR, fxsave) + \
LLVM_EXTENSION offsetof(FXSAVE, xmm[7]) + sizeof(XMMReg) + \
(32 * reg_index))
-#define BNDR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
-#define BNDC_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, i387) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
+#define BNDC_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, i387) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
// Number of bytes needed to represent a FPR.
#if !defined(FPR_SIZE)
diff --git a/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
new file mode 100644
index 000000000000..bffa7a1d8b63
--- /dev/null
+++ b/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h
@@ -0,0 +1,476 @@
+//===-- RegisterInfos_ppc64le.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
+
+// C Includes
+#include <stddef.h>
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) (offsetof(GPR, regname))
+#define FPR_OFFSET(regname) (offsetof(FPR, regname) + sizeof(GPR))
+#define VMX_OFFSET(regname) (offsetof(VMX, regname) + sizeof(GPR) + sizeof(FPR))
+#define VSX_OFFSET(regname) \
+ (offsetof(VSX, regname) + sizeof(GPR) + sizeof(FPR) + sizeof(VMX))
+#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
+
+#include "Utility/PPC64LE_DWARF_Registers.h"
+#include "lldb-ppc64le-register-enums.h"
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, lldb_kind) \
+ { \
+ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le,\
+ ppc64le_dwarf::dwarf_##reg##_ppc64le,\
+ lldb_kind, \
+ LLDB_INVALID_REGNUM, \
+ gpr_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_FPR(reg, alt, lldb_kind) \
+ { \
+#reg, alt, 8, FPR_OFFSET(reg), lldb::eEncodingIEEE754, lldb::eFormatFloat, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \
+ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \
+ fpr_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VMX(reg, lldb_kind) \
+ { \
+#reg, NULL, 16, VMX_OFFSET(reg), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt32, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \
+ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \
+ vmx_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+#define DEFINE_VSX(reg, lldb_kind) \
+ { \
+#reg, NULL, 16, VSX_OFFSET(reg), lldb::eEncodingVector, \
+ lldb::eFormatVectorOfUInt32, \
+ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \
+ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \
+ vsx_##reg##_ppc64le }, \
+ NULL, NULL, NULL, 0 \
+ }
+
+// General purpose registers.
+// EH_Frame, Generic, Process Plugin
+#define POWERPC_REGS \
+ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \
+ , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \
+ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \
+ DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \
+ DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \
+ DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \
+ DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \
+ DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \
+ DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \
+ DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \
+ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \
+ DEFINE_GPR(msr, "msr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(origr3, "orig_r3", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \
+ DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \
+ DEFINE_GPR(softe, "softe", LLDB_INVALID_REGNUM), \
+ DEFINE_GPR(trap, "trap", LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f0, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f1, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f2, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f3, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f4, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f5, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f6, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f7, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f8, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f9, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f10, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f11, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f12, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f13, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f14, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f15, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f16, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f17, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f18, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f19, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f20, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f21, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f22, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f23, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f24, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f25, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f26, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f27, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f28, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f29, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f30, NULL, LLDB_INVALID_REGNUM), \
+ DEFINE_FPR(f31, NULL, LLDB_INVALID_REGNUM), \
+ {"fpscr", \
+ NULL, \
+ 8, \
+ FPR_OFFSET(fpscr), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_fpscr_ppc64le, \
+ ppc64le_dwarf::dwarf_fpscr_ppc64le, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64le}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VMX(vr0, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr1, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr2, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr3, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr4, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr5, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr6, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr7, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr8, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr9, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr10, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr11, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr12, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr13, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr14, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr15, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr16, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr17, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr18, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr19, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr20, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr21, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr22, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr23, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr24, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr25, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr26, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr27, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr28, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr29, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr30, LLDB_INVALID_REGNUM), \
+ DEFINE_VMX(vr31, LLDB_INVALID_REGNUM), \
+ {"vscr", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vscr), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_vscr_ppc64le, ppc64le_dwarf::dwarf_vscr_ppc64le, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64le}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ {"vrsave", \
+ NULL, \
+ 4, \
+ VMX_OFFSET(vrsave), \
+ lldb::eEncodingUint, \
+ lldb::eFormatHex, \
+ {ppc64le_dwarf::dwarf_vrsave_ppc64le, \
+ ppc64le_dwarf::dwarf_vrsave_ppc64le, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64le}, \
+ NULL, \
+ NULL, \
+ NULL, \
+ 0}, \
+ DEFINE_VSX(vs0, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs1, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs2, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs3, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs4, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs5, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs6, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs7, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs8, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs9, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs10, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs11, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs12, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs13, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs14, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs15, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs16, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs17, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs18, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs19, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs20, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs21, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs22, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs23, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs24, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs25, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs26, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs27, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs28, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs29, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs30, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs31, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs32, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs33, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs34, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs35, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs36, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs37, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs38, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs39, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs40, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs41, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs42, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs43, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs44, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs45, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs46, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs47, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs48, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs49, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs50, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs51, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs52, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs53, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs54, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs55, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs56, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs57, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs58, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs59, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs50, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs61, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs62, LLDB_INVALID_REGNUM), \
+ DEFINE_VSX(vs63, LLDB_INVALID_REGNUM), /* */
+
+typedef struct _GPR {
+ uint64_t r0;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t r28;
+ uint64_t r29;
+ uint64_t r30;
+ uint64_t r31;
+ uint64_t pc;
+ uint64_t msr;
+ uint64_t origr3;
+ uint64_t ctr;
+ uint64_t lr;
+ uint64_t xer;
+ uint64_t cr;
+ uint64_t softe;
+ uint64_t trap;
+ uint64_t pad[3];
+} GPR;
+
+typedef struct _FPR {
+ uint64_t f0;
+ uint64_t f1;
+ uint64_t f2;
+ uint64_t f3;
+ uint64_t f4;
+ uint64_t f5;
+ uint64_t f6;
+ uint64_t f7;
+ uint64_t f8;
+ uint64_t f9;
+ uint64_t f10;
+ uint64_t f11;
+ uint64_t f12;
+ uint64_t f13;
+ uint64_t f14;
+ uint64_t f15;
+ uint64_t f16;
+ uint64_t f17;
+ uint64_t f18;
+ uint64_t f19;
+ uint64_t f20;
+ uint64_t f21;
+ uint64_t f22;
+ uint64_t f23;
+ uint64_t f24;
+ uint64_t f25;
+ uint64_t f26;
+ uint64_t f27;
+ uint64_t f28;
+ uint64_t f29;
+ uint64_t f30;
+ uint64_t f31;
+ uint64_t fpscr;
+} FPR;
+
+typedef struct _VMX {
+ uint32_t vr0[4];
+ uint32_t vr1[4];
+ uint32_t vr2[4];
+ uint32_t vr3[4];
+ uint32_t vr4[4];
+ uint32_t vr5[4];
+ uint32_t vr6[4];
+ uint32_t vr7[4];
+ uint32_t vr8[4];
+ uint32_t vr9[4];
+ uint32_t vr10[4];
+ uint32_t vr11[4];
+ uint32_t vr12[4];
+ uint32_t vr13[4];
+ uint32_t vr14[4];
+ uint32_t vr15[4];
+ uint32_t vr16[4];
+ uint32_t vr17[4];
+ uint32_t vr18[4];
+ uint32_t vr19[4];
+ uint32_t vr20[4];
+ uint32_t vr21[4];
+ uint32_t vr22[4];
+ uint32_t vr23[4];
+ uint32_t vr24[4];
+ uint32_t vr25[4];
+ uint32_t vr26[4];
+ uint32_t vr27[4];
+ uint32_t vr28[4];
+ uint32_t vr29[4];
+ uint32_t vr30[4];
+ uint32_t vr31[4];
+ uint32_t pad[2];
+ uint32_t vscr[2];
+ uint32_t vrsave;
+} VMX;
+
+typedef struct _VSX {
+ uint32_t vs0[4];
+ uint32_t vs1[4];
+ uint32_t vs2[4];
+ uint32_t vs3[4];
+ uint32_t vs4[4];
+ uint32_t vs5[4];
+ uint32_t vs6[4];
+ uint32_t vs7[4];
+ uint32_t vs8[4];
+ uint32_t vs9[4];
+ uint32_t vs10[4];
+ uint32_t vs11[4];
+ uint32_t vs12[4];
+ uint32_t vs13[4];
+ uint32_t vs14[4];
+ uint32_t vs15[4];
+ uint32_t vs16[4];
+ uint32_t vs17[4];
+ uint32_t vs18[4];
+ uint32_t vs19[4];
+ uint32_t vs20[4];
+ uint32_t vs21[4];
+ uint32_t vs22[4];
+ uint32_t vs23[4];
+ uint32_t vs24[4];
+ uint32_t vs25[4];
+ uint32_t vs26[4];
+ uint32_t vs27[4];
+ uint32_t vs28[4];
+ uint32_t vs29[4];
+ uint32_t vs30[4];
+ uint32_t vs31[4];
+ uint32_t vs32[4];
+ uint32_t vs33[4];
+ uint32_t vs34[4];
+ uint32_t vs35[4];
+ uint32_t vs36[4];
+ uint32_t vs37[4];
+ uint32_t vs38[4];
+ uint32_t vs39[4];
+ uint32_t vs40[4];
+ uint32_t vs41[4];
+ uint32_t vs42[4];
+ uint32_t vs43[4];
+ uint32_t vs44[4];
+ uint32_t vs45[4];
+ uint32_t vs46[4];
+ uint32_t vs47[4];
+ uint32_t vs48[4];
+ uint32_t vs49[4];
+ uint32_t vs50[4];
+ uint32_t vs51[4];
+ uint32_t vs52[4];
+ uint32_t vs53[4];
+ uint32_t vs54[4];
+ uint32_t vs55[4];
+ uint32_t vs56[4];
+ uint32_t vs57[4];
+ uint32_t vs58[4];
+ uint32_t vs59[4];
+ uint32_t vs60[4];
+ uint32_t vs61[4];
+ uint32_t vs62[4];
+ uint32_t vs63[4];
+} VSX;
+
+static lldb_private::RegisterInfo g_register_infos_ppc64le[] = {
+ POWERPC_REGS
+};
+
+static_assert((sizeof(g_register_infos_ppc64le) /
+ sizeof(g_register_infos_ppc64le[0])) ==
+ k_num_registers_ppc64le,
+ "g_register_infos_powerpc64 has wrong number of register infos");
+
+#undef DEFINE_FPR
+#undef DEFINE_GPR
+#undef DEFINE_VMX
+#undef DEFINE_VSX
+
+#endif // DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
diff --git a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
index 8861ecd66806..651536cb6045 100644
--- a/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
+++ b/source/Plugins/Process/Utility/RegisterInfos_x86_64.h
@@ -7,11 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Compiler.h"
-#include <cstddef>
-#include <cstdint>
-
-// Project includes
+// This file is meant to be textually included. Do not #include modular
+// headers here.
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname))
@@ -19,25 +16,25 @@
// Computes the offset of the given FPR in the extended data area.
#define FPR_OFFSET(regname) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FPR, fxsave) + \
LLVM_EXTENSION offsetof(FXSAVE, regname))
// Computes the offset of the YMM register assembled from register halves.
// Based on DNBArchImplX86_64.cpp from debugserver
#define YMM_OFFSET(reg_index) \
(LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index))
-#define BNDR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
+#define BNDR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]))
-#define BNDC_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, fpr) + \
- LLVM_EXTENSION offsetof(FPR, xstate) + \
- LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
+#define BNDC_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, fpr) + \
+ LLVM_EXTENSION offsetof(FPR, xsave) + \
+ LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]))
#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
diff --git a/source/Plugins/Process/Utility/StopInfoMachException.cpp b/source/Plugins/Process/Utility/StopInfoMachException.cpp
index 435f3d18c062..3e860874183c 100644
--- a/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ b/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -14,7 +14,6 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
diff --git a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
index f907735d8f58..d831011cb661 100644
--- a/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
+++ b/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
@@ -7,11 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -19,6 +14,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "RegisterContextMacOSXFrameBackchain.h"
@@ -85,8 +81,6 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386(
if (process == NULL)
return 0;
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
struct Frame_i386 {
uint32_t fp;
uint32_t pc;
@@ -179,8 +173,6 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64(
StackFrame *first_frame = exe_ctx.GetFramePtr();
- std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;
-
struct Frame_x86_64 {
uint64_t fp;
uint64_t pc;
diff --git a/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h b/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
new file mode 100644
index 000000000000..675804d13268
--- /dev/null
+++ b/source/Plugins/Process/Utility/lldb-ppc64le-register-enums.h
@@ -0,0 +1,210 @@
+//===-- lldb-ppc64le-register-enums.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_ppc64le_register_enums_h
+#define lldb_ppc64le_register_enums_h
+
+// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB)
+
+// ---------------------------------------------------------------------------
+// Internal codes for all ppc64le registers.
+// ---------------------------------------------------------------------------
+enum {
+ k_first_gpr_ppc64le,
+ gpr_r0_ppc64le = k_first_gpr_ppc64le,
+ gpr_r1_ppc64le,
+ gpr_r2_ppc64le,
+ gpr_r3_ppc64le,
+ gpr_r4_ppc64le,
+ gpr_r5_ppc64le,
+ gpr_r6_ppc64le,
+ gpr_r7_ppc64le,
+ gpr_r8_ppc64le,
+ gpr_r9_ppc64le,
+ gpr_r10_ppc64le,
+ gpr_r11_ppc64le,
+ gpr_r12_ppc64le,
+ gpr_r13_ppc64le,
+ gpr_r14_ppc64le,
+ gpr_r15_ppc64le,
+ gpr_r16_ppc64le,
+ gpr_r17_ppc64le,
+ gpr_r18_ppc64le,
+ gpr_r19_ppc64le,
+ gpr_r20_ppc64le,
+ gpr_r21_ppc64le,
+ gpr_r22_ppc64le,
+ gpr_r23_ppc64le,
+ gpr_r24_ppc64le,
+ gpr_r25_ppc64le,
+ gpr_r26_ppc64le,
+ gpr_r27_ppc64le,
+ gpr_r28_ppc64le,
+ gpr_r29_ppc64le,
+ gpr_r30_ppc64le,
+ gpr_r31_ppc64le,
+ gpr_pc_ppc64le,
+ gpr_msr_ppc64le,
+ gpr_origr3_ppc64le,
+ gpr_ctr_ppc64le,
+ gpr_lr_ppc64le,
+ gpr_xer_ppc64le,
+ gpr_cr_ppc64le,
+ gpr_softe_ppc64le,
+ gpr_trap_ppc64le,
+ k_last_gpr_ppc64le = gpr_trap_ppc64le,
+
+ k_first_fpr_ppc64le,
+ fpr_f0_ppc64le = k_first_fpr_ppc64le,
+ fpr_f1_ppc64le,
+ fpr_f2_ppc64le,
+ fpr_f3_ppc64le,
+ fpr_f4_ppc64le,
+ fpr_f5_ppc64le,
+ fpr_f6_ppc64le,
+ fpr_f7_ppc64le,
+ fpr_f8_ppc64le,
+ fpr_f9_ppc64le,
+ fpr_f10_ppc64le,
+ fpr_f11_ppc64le,
+ fpr_f12_ppc64le,
+ fpr_f13_ppc64le,
+ fpr_f14_ppc64le,
+ fpr_f15_ppc64le,
+ fpr_f16_ppc64le,
+ fpr_f17_ppc64le,
+ fpr_f18_ppc64le,
+ fpr_f19_ppc64le,
+ fpr_f20_ppc64le,
+ fpr_f21_ppc64le,
+ fpr_f22_ppc64le,
+ fpr_f23_ppc64le,
+ fpr_f24_ppc64le,
+ fpr_f25_ppc64le,
+ fpr_f26_ppc64le,
+ fpr_f27_ppc64le,
+ fpr_f28_ppc64le,
+ fpr_f29_ppc64le,
+ fpr_f30_ppc64le,
+ fpr_f31_ppc64le,
+ fpr_fpscr_ppc64le,
+ k_last_fpr_ppc64le = fpr_fpscr_ppc64le,
+
+ k_first_vmx_ppc64le,
+ vmx_vr0_ppc64le = k_first_vmx_ppc64le,
+ vmx_vr1_ppc64le,
+ vmx_vr2_ppc64le,
+ vmx_vr3_ppc64le,
+ vmx_vr4_ppc64le,
+ vmx_vr5_ppc64le,
+ vmx_vr6_ppc64le,
+ vmx_vr7_ppc64le,
+ vmx_vr8_ppc64le,
+ vmx_vr9_ppc64le,
+ vmx_vr10_ppc64le,
+ vmx_vr11_ppc64le,
+ vmx_vr12_ppc64le,
+ vmx_vr13_ppc64le,
+ vmx_vr14_ppc64le,
+ vmx_vr15_ppc64le,
+ vmx_vr16_ppc64le,
+ vmx_vr17_ppc64le,
+ vmx_vr18_ppc64le,
+ vmx_vr19_ppc64le,
+ vmx_vr20_ppc64le,
+ vmx_vr21_ppc64le,
+ vmx_vr22_ppc64le,
+ vmx_vr23_ppc64le,
+ vmx_vr24_ppc64le,
+ vmx_vr25_ppc64le,
+ vmx_vr26_ppc64le,
+ vmx_vr27_ppc64le,
+ vmx_vr28_ppc64le,
+ vmx_vr29_ppc64le,
+ vmx_vr30_ppc64le,
+ vmx_vr31_ppc64le,
+ vmx_vscr_ppc64le,
+ vmx_vrsave_ppc64le,
+ k_last_vmx_ppc64le = vmx_vrsave_ppc64le,
+
+ k_first_vsx_ppc64le,
+ vsx_vs0_ppc64le = k_first_vsx_ppc64le,
+ vsx_vs1_ppc64le,
+ vsx_vs2_ppc64le,
+ vsx_vs3_ppc64le,
+ vsx_vs4_ppc64le,
+ vsx_vs5_ppc64le,
+ vsx_vs6_ppc64le,
+ vsx_vs7_ppc64le,
+ vsx_vs8_ppc64le,
+ vsx_vs9_ppc64le,
+ vsx_vs10_ppc64le,
+ vsx_vs11_ppc64le,
+ vsx_vs12_ppc64le,
+ vsx_vs13_ppc64le,
+ vsx_vs14_ppc64le,
+ vsx_vs15_ppc64le,
+ vsx_vs16_ppc64le,
+ vsx_vs17_ppc64le,
+ vsx_vs18_ppc64le,
+ vsx_vs19_ppc64le,
+ vsx_vs20_ppc64le,
+ vsx_vs21_ppc64le,
+ vsx_vs22_ppc64le,
+ vsx_vs23_ppc64le,
+ vsx_vs24_ppc64le,
+ vsx_vs25_ppc64le,
+ vsx_vs26_ppc64le,
+ vsx_vs27_ppc64le,
+ vsx_vs28_ppc64le,
+ vsx_vs29_ppc64le,
+ vsx_vs30_ppc64le,
+ vsx_vs31_ppc64le,
+ vsx_vs32_ppc64le,
+ vsx_vs33_ppc64le,
+ vsx_vs34_ppc64le,
+ vsx_vs35_ppc64le,
+ vsx_vs36_ppc64le,
+ vsx_vs37_ppc64le,
+ vsx_vs38_ppc64le,
+ vsx_vs39_ppc64le,
+ vsx_vs40_ppc64le,
+ vsx_vs41_ppc64le,
+ vsx_vs42_ppc64le,
+ vsx_vs43_ppc64le,
+ vsx_vs44_ppc64le,
+ vsx_vs45_ppc64le,
+ vsx_vs46_ppc64le,
+ vsx_vs47_ppc64le,
+ vsx_vs48_ppc64le,
+ vsx_vs49_ppc64le,
+ vsx_vs50_ppc64le,
+ vsx_vs51_ppc64le,
+ vsx_vs52_ppc64le,
+ vsx_vs53_ppc64le,
+ vsx_vs54_ppc64le,
+ vsx_vs55_ppc64le,
+ vsx_vs56_ppc64le,
+ vsx_vs57_ppc64le,
+ vsx_vs58_ppc64le,
+ vsx_vs59_ppc64le,
+ vsx_vs60_ppc64le,
+ vsx_vs61_ppc64le,
+ vsx_vs62_ppc64le,
+ vsx_vs63_ppc64le,
+ k_last_vsx_ppc64le = vsx_vs63_ppc64le,
+
+ k_num_registers_ppc64le,
+ k_num_gpr_registers_ppc64le = k_last_gpr_ppc64le - k_first_gpr_ppc64le + 1,
+ k_num_fpr_registers_ppc64le = k_last_fpr_ppc64le - k_first_fpr_ppc64le + 1,
+ k_num_vmx_registers_ppc64le = k_last_vmx_ppc64le - k_first_vmx_ppc64le + 1,
+ k_num_vsx_registers_ppc64le = k_last_vsx_ppc64le - k_first_vsx_ppc64le + 1,
+};
+
+#endif // #ifndef lldb_ppc64le_register_enums_h
diff --git a/source/Plugins/Process/elf-core/CMakeLists.txt b/source/Plugins/Process/elf-core/CMakeLists.txt
index c7ffae695320..3082c73f6dda 100644
--- a/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -7,8 +7,10 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
RegisterContextPOSIXCore_arm64.cpp
RegisterContextPOSIXCore_mips64.cpp
RegisterContextPOSIXCore_powerpc.cpp
+ RegisterContextPOSIXCore_ppc64le.cpp
RegisterContextPOSIXCore_s390x.cpp
RegisterContextPOSIXCore_x86_64.cpp
+ RegisterUtilities.cpp
LINK_LIBS
lldbCore
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 71eb6437ceed..7d6a0c9ad2df 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -32,8 +32,7 @@
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
-
-// Project includes
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "ProcessElfCore.h"
#include "ThreadElfCore.h"
@@ -101,10 +100,7 @@ bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp,
ProcessElfCore::ProcessElfCore(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec &core_file)
- : Process(target_sp, listener_sp), m_core_module_sp(),
- m_core_file(core_file), m_dyld_plugin_name(),
- m_os(llvm::Triple::UnknownOS), m_thread_data_valid(false),
- m_thread_data(), m_core_aranges() {}
+ : Process(target_sp, listener_sp), m_core_file(core_file) {}
//----------------------------------------------------------------------
// Destructor
@@ -193,9 +189,8 @@ Status ProcessElfCore::DoLoadCore() {
// Parse thread contexts and auxv structure
if (header->p_type == llvm::ELF::PT_NOTE) {
- error = ParseThreadContextsFromNoteSegment(header, data);
- if (error.Fail())
- return error;
+ if (llvm::Error error = ParseThreadContextsFromNoteSegment(header, data))
+ return Status(std::move(error));
}
// PT_LOAD segments contains address map
if (header->p_type == llvm::ELF::PT_LOAD) {
@@ -404,7 +399,6 @@ size_t ProcessElfCore::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
void ProcessElfCore::Clear() {
m_thread_list.Clear();
- m_os = llvm::Triple::UnknownOS;
SetUnixSignals(std::make_shared<UnixSignals>());
}
@@ -427,43 +421,10 @@ lldb::addr_t ProcessElfCore::GetImageInfoAddress() {
return LLDB_INVALID_ADDRESS;
}
-/// Core files PT_NOTE segment descriptor types
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_TASKSTRUCT,
- NT_PLATFORM,
- NT_AUXV,
- NT_FILE = 0x46494c45,
- NT_PRXFPREG = 0x46e62b7f,
- NT_SIGINFO = 0x53494749,
- NT_OPENBSD_PROCINFO = 10,
- NT_OPENBSD_AUXV = 11,
- NT_OPENBSD_REGS = 20,
- NT_OPENBSD_FPREGS = 21,
-};
-
-namespace FREEBSD {
-
-enum {
- NT_PRSTATUS = 1,
- NT_FPREGSET,
- NT_PRPSINFO,
- NT_THRMISC = 7,
- NT_PROCSTAT_AUXV = 16,
- NT_PPC_VMX = 0x100
-};
-}
-
-namespace NETBSD {
-
-enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 };
-}
-
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
-static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
- ArchSpec &arch) {
+static void ParseFreeBSDPrStatus(ThreadData &thread_data,
+ const DataExtractor &data,
+ const ArchSpec &arch) {
lldb::offset_t offset = 0;
bool lp64 = (arch.GetMachine() == llvm::Triple::aarch64 ||
arch.GetMachine() == llvm::Triple::mips64 ||
@@ -492,12 +453,8 @@ static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
thread_data.gpregset = DataExtractor(data, offset, len);
}
-static void ParseFreeBSDThrMisc(ThreadData &thread_data, DataExtractor &data) {
- lldb::offset_t offset = 0;
- thread_data.name = data.GetCStr(&offset, 20);
-}
-
-static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
+static void ParseNetBSDProcInfo(ThreadData &thread_data,
+ const DataExtractor &data) {
lldb::offset_t offset = 0;
int version = data.GetU32(&offset);
@@ -508,7 +465,8 @@ static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
thread_data.signo = data.GetU32(&offset);
}
-static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
+static void ParseOpenBSDProcInfo(ThreadData &thread_data,
+ const DataExtractor &data) {
lldb::offset_t offset = 0;
int version = data.GetU32(&offset);
@@ -519,202 +477,263 @@ static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
thread_data.signo = data.GetU32(&offset);
}
-/// Parse Thread context from PT_NOTE segment and store it in the thread list
-/// Notes:
-/// 1) A PT_NOTE segment is composed of one or more NOTE entries.
-/// 2) NOTE Entry contains a standard header followed by variable size data.
-/// (see ELFNote structure)
-/// 3) A Thread Context in a core file usually described by 3 NOTE entries.
-/// a) NT_PRSTATUS - Register context
-/// b) NT_PRPSINFO - Process info(pid..)
-/// c) NT_FPREGSET - Floating point registers
-/// 4) The NOTE entries can be in any order
-/// 5) If a core file contains multiple thread contexts then there is two data
-/// forms
-/// a) Each thread context(2 or more NOTE entries) contained in its own
-/// segment (PT_NOTE)
-/// b) All thread context is stored in a single segment(PT_NOTE).
-/// This case is little tricker since while parsing we have to find where
-/// the
-/// new thread starts. The current implementation marks beginning of
-/// new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
-/// For case (b) there may be either one NT_PRPSINFO per thread, or a single
-/// one that applies to all threads (depending on the platform type).
-Status ProcessElfCore::ParseThreadContextsFromNoteSegment(
- const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
- assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
-
+llvm::Expected<std::vector<CoreNote>>
+ProcessElfCore::parseSegment(const DataExtractor &segment) {
lldb::offset_t offset = 0;
- std::unique_ptr<ThreadData> thread_data(new ThreadData);
+ std::vector<CoreNote> result;
+
+ while (offset < segment.GetByteSize()) {
+ ELFNote note = ELFNote();
+ if (!note.Parse(segment, &offset))
+ return llvm::make_error<llvm::StringError>(
+ "Unable to parse note segment", llvm::inconvertibleErrorCode());
+
+ size_t note_start = offset;
+ size_t note_size = llvm::alignTo(note.n_descsz, 4);
+ DataExtractor note_data(segment, note_start, note_size);
+
+ result.push_back({note, note_data});
+ offset += note_size;
+ }
+
+ return std::move(result);
+}
+
+llvm::Error ProcessElfCore::parseFreeBSDNotes(llvm::ArrayRef<CoreNote> notes) {
bool have_prstatus = false;
bool have_prpsinfo = false;
+ ThreadData thread_data;
+ for (const auto &note : notes) {
+ if (note.info.n_name != "FreeBSD")
+ continue;
+
+ if ((note.info.n_type == FREEBSD::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == FREEBSD::NT_PRPSINFO && have_prpsinfo)) {
+ assert(thread_data.gpregset.GetByteSize() > 0);
+ // Add the new thread to thread list
+ m_thread_data.push_back(thread_data);
+ thread_data = ThreadData();
+ have_prstatus = false;
+ have_prpsinfo = false;
+ }
- ArchSpec arch = GetArchitecture();
- ELFLinuxPrPsInfo prpsinfo;
- ELFLinuxPrStatus prstatus;
- ELFLinuxSigInfo siginfo;
- size_t header_size;
- size_t len;
- Status error;
+ switch (note.info.n_type) {
+ case FREEBSD::NT_PRSTATUS:
+ have_prstatus = true;
+ ParseFreeBSDPrStatus(thread_data, note.data, GetArchitecture());
+ break;
+ case FREEBSD::NT_PRPSINFO:
+ have_prpsinfo = true;
+ break;
+ case FREEBSD::NT_THRMISC: {
+ lldb::offset_t offset = 0;
+ thread_data.name = note.data.GetCStr(&offset, 20);
+ break;
+ }
+ case FREEBSD::NT_PROCSTAT_AUXV:
+ // FIXME: FreeBSD sticks an int at the beginning of the note
+ m_auxv = DataExtractor(note.data, 4, note.data.GetByteSize() - 4);
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
+ }
+ }
+ if (!have_prstatus) {
+ return llvm::make_error<llvm::StringError>(
+ "Could not find NT_PRSTATUS note in core file.",
+ llvm::inconvertibleErrorCode());
+ }
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
- // Loop through the NOTE entires in the segment
- while (offset < segment_header->p_filesz) {
- ELFNote note = ELFNote();
- note.Parse(segment_data, &offset);
+llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
+ ThreadData thread_data;
+ for (const auto &note : notes) {
+ // NetBSD per-thread information is stored in notes named
+ // "NetBSD-CORE@nnn" so match on the initial part of the string.
+ if (!llvm::StringRef(note.info.n_name).startswith("NetBSD-CORE"))
+ continue;
+
+ switch (note.info.n_type) {
+ case NETBSD::NT_PROCINFO:
+ ParseNetBSDProcInfo(thread_data, note.data);
+ break;
+ case NETBSD::NT_AUXV:
+ m_auxv = note.data;
+ break;
+
+ case NETBSD::NT_AMD64_REGS:
+ if (GetArchitecture().GetMachine() == llvm::Triple::x86_64)
+ thread_data.gpregset = note.data;
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
+ }
+ }
+ if (thread_data.gpregset.GetByteSize() == 0) {
+ return llvm::make_error<llvm::StringError>(
+ "Could not find general purpose registers note in core file.",
+ llvm::inconvertibleErrorCode());
+ }
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
+
+llvm::Error ProcessElfCore::parseOpenBSDNotes(llvm::ArrayRef<CoreNote> notes) {
+ ThreadData thread_data;
+ for (const auto &note : notes) {
+ // OpenBSD per-thread information is stored in notes named
+ // "OpenBSD@nnn" so match on the initial part of the string.
+ if (!llvm::StringRef(note.info.n_name).startswith("OpenBSD"))
+ continue;
+
+ switch (note.info.n_type) {
+ case OPENBSD::NT_PROCINFO:
+ ParseOpenBSDProcInfo(thread_data, note.data);
+ break;
+ case OPENBSD::NT_AUXV:
+ m_auxv = note.data;
+ break;
+ case OPENBSD::NT_REGS:
+ thread_data.gpregset = note.data;
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
+ }
+ }
+ if (thread_data.gpregset.GetByteSize() == 0) {
+ return llvm::make_error<llvm::StringError>(
+ "Could not find general purpose registers note in core file.",
+ llvm::inconvertibleErrorCode());
+ }
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
- // Beginning of new thread
- if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
- (note.n_type == NT_PRPSINFO && have_prpsinfo)) {
- assert(thread_data->gpregset.GetByteSize() > 0);
+/// A description of a linux process usually contains the following NOTE
+/// entries:
+/// - NT_PRPSINFO - General process information like pid, uid, name, ...
+/// - NT_SIGINFO - Information about the signal that terminated the process
+/// - NT_AUXV - Process auxiliary vector
+/// - NT_FILE - Files mapped into memory
+///
+/// Additionally, for each thread in the process the core file will contain at
+/// least the NT_PRSTATUS note, containing the thread id and general purpose
+/// registers. It may include additional notes for other register sets (floating
+/// point and vector registers, ...). The tricky part here is that some of these
+/// notes have "CORE" in their owner fields, while other set it to "LINUX".
+llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
+ const ArchSpec &arch = GetArchitecture();
+ bool have_prstatus = false;
+ bool have_prpsinfo = false;
+ ThreadData thread_data;
+ for (const auto &note : notes) {
+ if (note.info.n_name != "CORE" && note.info.n_name != "LINUX")
+ continue;
+
+ if ((note.info.n_type == LINUX::NT_PRSTATUS && have_prstatus) ||
+ (note.info.n_type == LINUX::NT_PRPSINFO && have_prpsinfo)) {
+ assert(thread_data.gpregset.GetByteSize() > 0);
// Add the new thread to thread list
- m_thread_data.push_back(*thread_data);
- *thread_data = ThreadData();
+ m_thread_data.push_back(thread_data);
+ thread_data = ThreadData();
have_prstatus = false;
have_prpsinfo = false;
}
- size_t note_start, note_size;
- note_start = offset;
- note_size = llvm::alignTo(note.n_descsz, 4);
-
- // Store the NOTE information in the current thread
- DataExtractor note_data(segment_data, note_start, note_size);
- note_data.SetAddressByteSize(
- m_core_module_sp->GetArchitecture().GetAddressByteSize());
- if (note.n_name == "FreeBSD") {
- m_os = llvm::Triple::FreeBSD;
- switch (note.n_type) {
- case FREEBSD::NT_PRSTATUS:
- have_prstatus = true;
- ParseFreeBSDPrStatus(*thread_data, note_data, arch);
- break;
- case FREEBSD::NT_FPREGSET:
- thread_data->fpregset = note_data;
- break;
- case FREEBSD::NT_PRPSINFO:
- have_prpsinfo = true;
- break;
- case FREEBSD::NT_THRMISC:
- ParseFreeBSDThrMisc(*thread_data, note_data);
- break;
- case FREEBSD::NT_PROCSTAT_AUXV:
- // FIXME: FreeBSD sticks an int at the beginning of the note
- m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
- break;
- case FREEBSD::NT_PPC_VMX:
- thread_data->vregset = note_data;
- break;
- default:
- break;
- }
- } else if (note.n_name.substr(0, 11) == "NetBSD-CORE") {
- // NetBSD per-thread information is stored in notes named
- // "NetBSD-CORE@nnn" so match on the initial part of the string.
- m_os = llvm::Triple::NetBSD;
- if (note.n_type == NETBSD::NT_PROCINFO) {
- ParseNetBSDProcInfo(*thread_data, note_data);
- } else if (note.n_type == NETBSD::NT_AUXV) {
- m_auxv = DataExtractor(note_data);
- } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
- note.n_type == NETBSD::NT_AMD64_REGS) {
- thread_data->gpregset = note_data;
- } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
- note.n_type == NETBSD::NT_AMD64_FPREGS) {
- thread_data->fpregset = note_data;
- }
- } else if (note.n_name.substr(0, 7) == "OpenBSD") {
- // OpenBSD per-thread information is stored in notes named
- // "OpenBSD@nnn" so match on the initial part of the string.
- m_os = llvm::Triple::OpenBSD;
- switch (note.n_type) {
- case NT_OPENBSD_PROCINFO:
- ParseOpenBSDProcInfo(*thread_data, note_data);
- break;
- case NT_OPENBSD_AUXV:
- m_auxv = DataExtractor(note_data);
- break;
- case NT_OPENBSD_REGS:
- thread_data->gpregset = note_data;
- break;
- case NT_OPENBSD_FPREGS:
- thread_data->fpregset = note_data;
- break;
- }
- } else if (note.n_name == "CORE") {
- switch (note.n_type) {
- case NT_PRSTATUS:
- have_prstatus = true;
- error = prstatus.Parse(note_data, arch);
- if (error.Fail())
- return error;
- thread_data->prstatus_sig = prstatus.pr_cursig;
- thread_data->tid = prstatus.pr_pid;
- header_size = ELFLinuxPrStatus::GetSize(arch);
- len = note_data.GetByteSize() - header_size;
- thread_data->gpregset = DataExtractor(note_data, header_size, len);
- break;
- case NT_FPREGSET:
- // In a i386 core file NT_FPREGSET is present, but it's not the result
- // of the FXSAVE instruction like in 64 bit files.
- // The result from FXSAVE is in NT_PRXFPREG for i386 core files
- if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
- thread_data->fpregset = note_data;
- else if(arch.IsMIPS())
- thread_data->fpregset = note_data;
- break;
- case NT_PRPSINFO:
- have_prpsinfo = true;
- error = prpsinfo.Parse(note_data, arch);
- if (error.Fail())
- return error;
- thread_data->name = prpsinfo.pr_fname;
- SetID(prpsinfo.pr_pid);
- break;
- case NT_AUXV:
- m_auxv = DataExtractor(note_data);
- break;
- case NT_FILE: {
- m_nt_file_entries.clear();
- lldb::offset_t offset = 0;
- const uint64_t count = note_data.GetAddress(&offset);
- note_data.GetAddress(&offset); // Skip page size
- for (uint64_t i = 0; i < count; ++i) {
- NT_FILE_Entry entry;
- entry.start = note_data.GetAddress(&offset);
- entry.end = note_data.GetAddress(&offset);
- entry.file_ofs = note_data.GetAddress(&offset);
- m_nt_file_entries.push_back(entry);
- }
- for (uint64_t i = 0; i < count; ++i) {
- const char *path = note_data.GetCStr(&offset);
- if (path && path[0])
- m_nt_file_entries[i].path.SetCString(path);
- }
- } break;
- case NT_SIGINFO: {
- error = siginfo.Parse(note_data, arch);
- if (error.Fail())
- return error;
- thread_data->signo = siginfo.si_signo;
- } break;
- default:
- break;
+ switch (note.info.n_type) {
+ case LINUX::NT_PRSTATUS: {
+ have_prstatus = true;
+ ELFLinuxPrStatus prstatus;
+ Status status = prstatus.Parse(note.data, arch);
+ if (status.Fail())
+ return status.ToError();
+ thread_data.prstatus_sig = prstatus.pr_cursig;
+ thread_data.tid = prstatus.pr_pid;
+ uint32_t header_size = ELFLinuxPrStatus::GetSize(arch);
+ size_t len = note.data.GetByteSize() - header_size;
+ thread_data.gpregset = DataExtractor(note.data, header_size, len);
+ break;
+ }
+ case LINUX::NT_PRPSINFO: {
+ have_prpsinfo = true;
+ ELFLinuxPrPsInfo prpsinfo;
+ Status status = prpsinfo.Parse(note.data, arch);
+ if (status.Fail())
+ return status.ToError();
+ thread_data.name = prpsinfo.pr_fname;
+ SetID(prpsinfo.pr_pid);
+ break;
+ }
+ case LINUX::NT_SIGINFO: {
+ ELFLinuxSigInfo siginfo;
+ Status status = siginfo.Parse(note.data, arch);
+ if (status.Fail())
+ return status.ToError();
+ thread_data.signo = siginfo.si_signo;
+ break;
+ }
+ case LINUX::NT_FILE: {
+ m_nt_file_entries.clear();
+ lldb::offset_t offset = 0;
+ const uint64_t count = note.data.GetAddress(&offset);
+ note.data.GetAddress(&offset); // Skip page size
+ for (uint64_t i = 0; i < count; ++i) {
+ NT_FILE_Entry entry;
+ entry.start = note.data.GetAddress(&offset);
+ entry.end = note.data.GetAddress(&offset);
+ entry.file_ofs = note.data.GetAddress(&offset);
+ m_nt_file_entries.push_back(entry);
}
- } else if (note.n_name == "LINUX") {
- switch (note.n_type) {
- case NT_PRXFPREG:
- thread_data->fpregset = note_data;
+ for (uint64_t i = 0; i < count; ++i) {
+ const char *path = note.data.GetCStr(&offset);
+ if (path && path[0])
+ m_nt_file_entries[i].path.SetCString(path);
}
+ break;
+ }
+ case LINUX::NT_AUXV:
+ m_auxv = note.data;
+ break;
+ default:
+ thread_data.notes.push_back(note);
+ break;
}
-
- offset += note_size;
}
// Add last entry in the note section
- if (thread_data && thread_data->gpregset.GetByteSize() > 0) {
- m_thread_data.push_back(*thread_data);
- }
+ if (have_prstatus)
+ m_thread_data.push_back(thread_data);
+ return llvm::Error::success();
+}
- return error;
+/// Parse Thread context from PT_NOTE segment and store it in the thread list
+/// A note segment consists of one or more NOTE entries, but their types and
+/// meaning differ depending on the OS.
+llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
+ const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+ assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
+
+ auto notes_or_error = parseSegment(segment_data);
+ if(!notes_or_error)
+ return notes_or_error.takeError();
+ switch (GetArchitecture().GetTriple().getOS()) {
+ case llvm::Triple::FreeBSD:
+ return parseFreeBSDNotes(*notes_or_error);
+ case llvm::Triple::Linux:
+ return parseLinuxNotes(*notes_or_error);
+ case llvm::Triple::NetBSD:
+ return parseNetBSDNotes(*notes_or_error);
+ case llvm::Triple::OpenBSD:
+ return parseOpenBSDNotes(*notes_or_error);
+ default:
+ return llvm::make_error<llvm::StringError>(
+ "Don't know how to parse core file. Unsupported OS.",
+ llvm::inconvertibleErrorCode());
+ }
}
uint32_t ProcessElfCore::GetNumThreadContexts() {
@@ -724,15 +743,18 @@ uint32_t ProcessElfCore::GetNumThreadContexts() {
}
ArchSpec ProcessElfCore::GetArchitecture() {
- ObjectFileELF *core_file =
- (ObjectFileELF *)(m_core_module_sp->GetObjectFile());
ArchSpec arch;
- core_file->GetArchitecture(arch);
+ m_core_module_sp->GetObjectFile()->GetArchitecture(arch);
ArchSpec target_arch = GetTarget().GetArchitecture();
-
- if (target_arch.IsMIPS())
+ arch.MergeFrom(target_arch);
+
+ // On MIPS there is no way to differentiate betwenn 32bit and 64bit core files
+ // and this information can't be merged in from the target arch so we fail
+ // back to unconditionally returning the target arch in this config.
+ if (target_arch.IsMIPS()) {
return target_arch;
+ }
return arch;
}
diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.h b/source/Plugins/Process/elf-core/ProcessElfCore.h
index dbf7f926f855..325c0152e028 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -29,6 +29,7 @@
#include "lldb/Utility/Status.h"
#include "Plugins/ObjectFile/ELF/ELFHeader.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
struct ThreadData;
@@ -84,11 +85,21 @@ public:
void RefreshStateAfterStop() override;
+ lldb_private::Status WillResume() override {
+ lldb_private::Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support resuming processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
//------------------------------------------------------------------
// Process Queries
//------------------------------------------------------------------
bool IsAlive() override;
+ bool WarnBeforeDetach() const override { return false; }
+
//------------------------------------------------------------------
// Process Memory
//------------------------------------------------------------------
@@ -139,10 +150,8 @@ private:
std::string m_dyld_plugin_name;
DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);
- llvm::Triple::OSType m_os;
-
// True if m_thread_contexts contains valid entries
- bool m_thread_data_valid;
+ bool m_thread_data_valid = false;
// Contain thread data read from NOTE segments
std::vector<ThreadData> m_thread_data;
@@ -160,7 +169,7 @@ private:
std::vector<NT_FILE_Entry> m_nt_file_entries;
// Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
- lldb_private::Status ParseThreadContextsFromNoteSegment(
+ llvm::Error ParseThreadContextsFromNoteSegment(
const elf::ELFProgramHeader *segment_header,
lldb_private::DataExtractor segment_data);
@@ -170,6 +179,13 @@ private:
// Parse a contiguous address range of the process from LOAD segment
lldb::addr_t
AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header);
+
+ llvm::Expected<std::vector<lldb_private::CoreNote>>
+ parseSegment(const lldb_private::DataExtractor &segment);
+ llvm::Error parseFreeBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
+ llvm::Error parseNetBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
+ llvm::Error parseOpenBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
+ llvm::Error parseLinuxNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
};
#endif // liblldb_ProcessElfCore_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 81d88e69b97f..0d683153d9ed 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -16,7 +16,7 @@ using namespace lldb_private;
RegisterContextCorePOSIX_arm::RegisterContextCorePOSIX_arm(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_arm(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
index e095eac5eaf8..a98d64caee17 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_arm_h_
#define liblldb_RegisterContextCorePOSIX_arm_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -24,7 +21,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_arm() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 41c02bf94c37..919f8901d39a 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "RegisterContextPOSIXCore_arm64.h"
-
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Thread.h"
@@ -16,7 +16,7 @@ using namespace lldb_private;
RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_arm64(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 3a2bbdb0a2eb..c519b1557189 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_arm64_h_
#define liblldb_RegisterContextCorePOSIX_arm64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -24,7 +21,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_arm64() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
index 7549cf074be7..e252b5a35e9c 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp
@@ -16,12 +16,15 @@ using namespace lldb_private;
RegisterContextCorePOSIX_mips64::RegisterContextCorePOSIX_mips64(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_mips64(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ DataExtractor fpregset = getRegset(
+ notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
index 2cb527a8de7c..cf1d8a5bc2d1 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_mips64_h_
#define liblldb_RegisterContextCorePOSIX_mips64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/DataExtractor.h"
@@ -24,7 +21,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_mips64() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
index 62f6413722f7..8670e341a277 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp
@@ -17,17 +17,21 @@ using namespace lldb_private;
RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset,
- const DataExtractor &vregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_powerpc(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ ArchSpec arch = register_info->GetTargetArchitecture();
+ DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
m_fpr.SetByteOrder(fpregset.GetByteOrder());
+
+ DataExtractor vregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc);
m_vec_buffer.reset(
new DataBufferHeap(vregset.GetDataStart(), vregset.GetByteSize()));
m_vec.SetData(m_vec_buffer);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
index aaa95e5d2397..c352ab5912ff 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_powerpc_h_
#define liblldb_RegisterContextCorePOSIX_powerpc_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataExtractor.h"
class RegisterContextCorePOSIX_powerpc : public RegisterContextPOSIX_powerpc {
@@ -23,8 +20,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset,
- const lldb_private::DataExtractor &vregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_powerpc() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
new file mode 100644
index 000000000000..2237e72353ac
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
@@ -0,0 +1,132 @@
+//===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextPOSIXCore_ppc64le.h"
+
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/DataBufferHeap.h"
+
+#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+
+using namespace lldb_private;
+
+RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le(
+ Thread &thread, RegisterInfoInterface *register_info,
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
+ : RegisterContextPOSIX_ppc64le(thread, 0, register_info) {
+ m_gpr_buffer.reset(
+ new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ ArchSpec arch = register_info->GetTargetArchitecture();
+ DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
+ m_fpr_buffer.reset(
+ new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
+ m_fpr.SetData(m_fpr_buffer);
+ m_fpr.SetByteOrder(fpregset.GetByteOrder());
+
+ DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc);
+ m_vmx_buffer.reset(
+ new DataBufferHeap(vmxregset.GetDataStart(), vmxregset.GetByteSize()));
+ m_vmx.SetData(m_vmx_buffer);
+ m_vmx.SetByteOrder(vmxregset.GetByteOrder());
+
+ DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc);
+ m_vsx_buffer.reset(
+ new DataBufferHeap(vsxregset.GetDataStart(), vsxregset.GetByteSize()));
+ m_vsx.SetData(m_vsx_buffer);
+ m_vsx.SetByteOrder(vsxregset.GetByteOrder());
+}
+
+size_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const {
+ return k_num_fpr_registers_ppc64le * sizeof(uint64_t);
+}
+
+size_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const {
+ return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 +
+ sizeof(uint32_t);
+}
+
+size_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const {
+ return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2;
+}
+
+bool RegisterContextCorePOSIX_ppc64le::ReadRegister(
+ const RegisterInfo *reg_info, RegisterValue &value) {
+ lldb::offset_t offset = reg_info->byte_offset;
+
+ if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint64_t v;
+ offset -= GetGPRSize();
+ offset = m_fpr.CopyData(offset, reg_info->byte_size, &v);
+
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder());
+ return true;
+ }
+ } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ offset -= GetGPRSize() + GetFPRSize();
+ offset = m_vmx.CopyData(offset, reg_info->byte_size, &v);
+
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
+ return true;
+ }
+ } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+ uint32_t v[4];
+ lldb::offset_t tmp_offset;
+ offset -= GetGPRSize() + GetFPRSize() + GetVMXSize();
+
+ if (offset < GetVSXSize() / 2) {
+ tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v);
+
+ if (tmp_offset != reg_info->byte_size / 2) {
+ return false;
+ }
+
+ uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t);
+ tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst);
+
+ if (tmp_offset != reg_info->byte_size / 2) {
+ return false;
+ }
+
+ value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder());
+ return true;
+ } else {
+ offset =
+ m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v);
+ if (offset == reg_info->byte_size) {
+ value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder());
+ return true;
+ }
+ }
+ } else {
+ uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+
+ if (offset == reg_info->byte_offset + reg_info->byte_size) {
+ if (reg_info->byte_size < sizeof(v))
+ value = (uint32_t)v;
+ else
+ value = v;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool RegisterContextCorePOSIX_ppc64le::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue &value) {
+ return false;
+}
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
new file mode 100644
index 000000000000..c860781d60be
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h
@@ -0,0 +1,49 @@
+//===-- RegisterContextPOSIXCore_ppc64le.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_RegisterContextCorePOSIX_ppc64le_h_
+#define liblldb_RegisterContextCorePOSIX_ppc64le_h_
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+#include "lldb/Utility/DataExtractor.h"
+
+class RegisterContextCorePOSIX_ppc64le : public RegisterContextPOSIX_ppc64le {
+public:
+ RegisterContextCorePOSIX_ppc64le(
+ lldb_private::Thread &thread,
+ lldb_private::RegisterInfoInterface *register_info,
+ const lldb_private::DataExtractor &gpregset,
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
+
+ bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+ lldb_private::RegisterValue &value) override;
+
+ bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+ const lldb_private::RegisterValue &value) override;
+
+protected:
+ size_t GetFPRSize() const;
+
+ size_t GetVMXSize() const;
+
+ size_t GetVSXSize() const;
+
+private:
+ lldb::DataBufferSP m_gpr_buffer;
+ lldb::DataBufferSP m_fpr_buffer;
+ lldb::DataBufferSP m_vmx_buffer;
+ lldb::DataBufferSP m_vsx_buffer;
+ lldb_private::DataExtractor m_gpr;
+ lldb_private::DataExtractor m_fpr;
+ lldb_private::DataExtractor m_vmx;
+ lldb_private::DataExtractor m_vsx;
+};
+
+#endif // liblldb_RegisterContextCorePOSIX_ppc64le_h_
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
index b3530a8d6a42..f0edbf1ea854 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp
@@ -17,13 +17,15 @@ using namespace lldb_private;
RegisterContextCorePOSIX_s390x::RegisterContextCorePOSIX_s390x(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_s390x(thread, 0, register_info) {
m_gpr_buffer.reset(
new DataBufferHeap(gpregset.GetDataStart(), gpregset.GetByteSize()));
m_gpr.SetData(m_gpr_buffer);
m_gpr.SetByteOrder(gpregset.GetByteOrder());
+ DataExtractor fpregset = getRegset(
+ notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
m_fpr_buffer.reset(
new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize()));
m_fpr.SetData(m_fpr_buffer);
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
index 2b4ae10a87bd..0df136372bdd 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_s390x_h_
#define liblldb_RegisterContextCorePOSIX_s390x_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_s390x.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Utility/DataExtractor.h"
class RegisterContextCorePOSIX_s390x : public RegisterContextPOSIX_s390x {
@@ -23,7 +20,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
~RegisterContextCorePOSIX_s390x() override;
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
index 5766923186d1..a5c7ffda1da5 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp
@@ -16,7 +16,7 @@ using namespace lldb_private;
RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(
Thread &thread, RegisterInfoInterface *register_info,
- const DataExtractor &gpregset, const DataExtractor &fpregset)
+ const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
: RegisterContextPOSIX_x86(thread, 0, register_info) {
size_t size, len;
@@ -27,6 +27,8 @@ RegisterContextCorePOSIX_x86_64::RegisterContextCorePOSIX_x86_64(
if (len != size)
m_gpregset.reset();
+ DataExtractor fpregset = getRegset(
+ notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
size = sizeof(FXSAVE);
m_fpregset.reset(new uint8_t[size]);
len =
diff --git a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
index 8340368f8c3c..509624174a89 100644
--- a/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
+++ b/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h
@@ -10,11 +10,8 @@
#ifndef liblldb_RegisterContextCorePOSIX_x86_64_h_
#define liblldb_RegisterContextCorePOSIX_x86_64_h_
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "Plugins/Process/Utility/RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
class RegisterContextCorePOSIX_x86_64 : public RegisterContextPOSIX_x86 {
public:
@@ -22,7 +19,7 @@ public:
lldb_private::Thread &thread,
lldb_private::RegisterInfoInterface *register_info,
const lldb_private::DataExtractor &gpregset,
- const lldb_private::DataExtractor &fpregset);
+ llvm::ArrayRef<lldb_private::CoreNote> notes);
bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
lldb_private::RegisterValue &value) override;
diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/source/Plugins/Process/elf-core/RegisterUtilities.cpp
new file mode 100644
index 000000000000..3837abadd0f6
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterUtilities.cpp
@@ -0,0 +1,39 @@
+//===-- RegisterUtilities.cpp -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace lldb_private;
+
+static llvm::Optional<uint32_t>
+getNoteType(const llvm::Triple &Triple,
+ llvm::ArrayRef<RegsetDesc> RegsetDescs) {
+ for (const auto &Entry : RegsetDescs) {
+ if (Entry.OS != Triple.getOS())
+ continue;
+ if (Entry.Arch != llvm::Triple::UnknownArch &&
+ Entry.Arch != Triple.getArch())
+ continue;
+ return Entry.Note;
+ }
+ return llvm::None;
+}
+
+DataExtractor lldb_private::getRegset(llvm::ArrayRef<CoreNote> Notes,
+ const llvm::Triple &Triple,
+ llvm::ArrayRef<RegsetDesc> RegsetDescs) {
+ auto TypeOr = getNoteType(Triple, RegsetDescs);
+ if (!TypeOr)
+ return DataExtractor();
+ uint32_t Type = *TypeOr;
+ auto Iter = llvm::find_if(
+ Notes, [Type](const CoreNote &Note) { return Note.info.n_type == Type; });
+ return Iter == Notes.end() ? DataExtractor() : Iter->data;
+}
diff --git a/source/Plugins/Process/elf-core/RegisterUtilities.h b/source/Plugins/Process/elf-core/RegisterUtilities.h
new file mode 100644
index 000000000000..9170d94c04b6
--- /dev/null
+++ b/source/Plugins/Process/elf-core/RegisterUtilities.h
@@ -0,0 +1,110 @@
+//===-- RegisterUtilities.h -------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_REGISTERUTILITIES_H
+#define LLDB_REGISTERUTILITIES_H
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "lldb/Utility/DataExtractor.h"
+
+namespace lldb_private {
+/// Core files PT_NOTE segment descriptor types
+
+namespace FREEBSD {
+enum {
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_THRMISC = 7,
+ NT_PROCSTAT_AUXV = 16,
+ NT_PPC_VMX = 0x100
+};
+}
+
+namespace NETBSD {
+enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 };
+}
+
+namespace OPENBSD {
+enum {
+ NT_PROCINFO = 10,
+ NT_AUXV = 11,
+ NT_REGS = 20,
+ NT_FPREGS = 21,
+};
+}
+
+namespace LINUX {
+enum {
+ NT_PRSTATUS = 1,
+ NT_FPREGSET,
+ NT_PRPSINFO,
+ NT_TASKSTRUCT,
+ NT_PLATFORM,
+ NT_AUXV,
+ NT_FILE = 0x46494c45,
+ NT_SIGINFO = 0x53494749,
+ NT_PPC_VMX = 0x100,
+ NT_PPC_VSX = 0x102,
+ NT_PRXFPREG = 0x46e62b7f,
+};
+}
+
+struct CoreNote {
+ ELFNote info;
+ DataExtractor data;
+};
+
+// A structure describing how to find a register set in a core file from a given
+// OS.
+struct RegsetDesc {
+ // OS to which this entry applies to. Must not be UnknownOS.
+ llvm::Triple::OSType OS;
+
+ // Architecture to which this entry applies to. Can be UnknownArch, in which
+ // case it applies to all architectures of a given OS.
+ llvm::Triple::ArchType Arch;
+
+ // The note type under which the register set can be found.
+ uint32_t Note;
+};
+
+// Returns the register set in Notes which corresponds to the specified Triple
+// according to the list of register set descriptions in RegsetDescs. The list
+// is scanned linearly, so you can use a more specific entry (e.g. linux-i386)
+// to override a more general entry (e.g. general linux), as long as you place
+// it earlier in the list. If a register set is not found, it returns an empty
+// DataExtractor.
+DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
+ const llvm::Triple &Triple,
+ llvm::ArrayRef<RegsetDesc> RegsetDescs);
+
+constexpr RegsetDesc FPR_Desc[] = {
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_FPREGSET},
+ // In a i386 core file NT_FPREGSET is present, but it's not the result
+ // of the FXSAVE instruction like in 64 bit files.
+ // The result from FXSAVE is in NT_PRXFPREG for i386 core files
+ {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET},
+ {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::NT_AMD64_FPREGS},
+ {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
+};
+
+constexpr RegsetDesc PPC_VMX_Desc[] = {
+ {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, FREEBSD::NT_PPC_VMX},
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VMX},
+};
+
+constexpr RegsetDesc PPC_VSX_Desc[] = {
+ {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_PPC_VSX},
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef LLDB_REGISTERUTILITIES_H
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 096c20363c78..10c1ed288b2c 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -18,9 +18,9 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
+#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
@@ -28,11 +28,13 @@
#include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
#include "ProcessElfCore.h"
#include "RegisterContextPOSIXCore_arm.h"
#include "RegisterContextPOSIXCore_arm64.h"
#include "RegisterContextPOSIXCore_mips64.h"
#include "RegisterContextPOSIXCore_powerpc.h"
+#include "RegisterContextPOSIXCore_ppc64le.h"
#include "RegisterContextPOSIXCore_s390x.h"
#include "RegisterContextPOSIXCore_x86_64.h"
#include "ThreadElfCore.h"
@@ -45,8 +47,7 @@ using namespace lldb_private;
//----------------------------------------------------------------------
ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
: Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
- m_signo(td.signo), m_gpregset_data(td.gpregset),
- m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
+ m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {}
ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
@@ -142,6 +143,9 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
case llvm::Triple::mips64:
reg_interface = new RegisterContextLinux_mips64(arch);
break;
+ case llvm::Triple::ppc64le:
+ reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
+ break;
case llvm::Triple::systemz:
reg_interface = new RegisterContextLinux_s390x(arch);
break;
@@ -191,36 +195,39 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
switch (arch.GetMachine()) {
case llvm::Triple::aarch64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::arm:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::mipsel:
case llvm::Triple::mips:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
- *this, reg_interface, m_gpregset_data, m_fpregset_data,
- m_vregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
+ break;
+ case llvm::Triple::ppc64le:
+ m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_ppc64le(
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::systemz:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
- *this, reg_interface, m_gpregset_data, m_fpregset_data));
+ *this, reg_interface, m_gpregset_data, m_notes));
break;
default:
break;
@@ -249,7 +256,7 @@ ELFLinuxPrStatus::ELFLinuxPrStatus() {
memset(this, 0, sizeof(ELFLinuxPrStatus));
}
-size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
+size_t ELFLinuxPrStatus::GetSize(const lldb_private::ArchSpec &arch) {
constexpr size_t mips_linux_pr_status_size_o32 = 96;
constexpr size_t mips_linux_pr_status_size_n32 = 72;
if (arch.IsMIPS()) {
@@ -265,6 +272,7 @@ size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
switch (arch.GetCore()) {
case lldb_private::ArchSpec::eCore_s390x_generic:
case lldb_private::ArchSpec::eCore_x86_64_x86_64:
+ case lldb_private::ArchSpec::eCore_ppc64le_generic:
return sizeof(ELFLinuxPrStatus);
case lldb_private::ArchSpec::eCore_x86_32_i386:
case lldb_private::ArchSpec::eCore_x86_32_i486:
@@ -274,7 +282,8 @@ size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
}
}
-Status ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
+Status ELFLinuxPrStatus::Parse(const DataExtractor &data,
+ const ArchSpec &arch) {
Status error;
if (GetSize(arch) > data.GetByteSize()) {
error.SetErrorStringWithFormat(
@@ -323,7 +332,7 @@ ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
memset(this, 0, sizeof(ELFLinuxPrPsInfo));
}
-size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
+size_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) {
constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
if (arch.IsMIPS()) {
uint8_t address_byte_size = arch.GetAddressByteSize();
@@ -344,7 +353,8 @@ size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
}
}
-Status ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
+Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
+ const ArchSpec &arch) {
Status error;
ByteOrder byteorder = data.GetByteOrder();
if (GetSize(arch) > data.GetByteSize()) {
@@ -413,7 +423,7 @@ size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
}
}
-Status ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
+Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
Status error;
if (GetSize(arch) > data.GetByteSize()) {
error.SetErrorStringWithFormat(
diff --git a/source/Plugins/Process/elf-core/ThreadElfCore.h b/source/Plugins/Process/elf-core/ThreadElfCore.h
index 521875413715..335f698dbb24 100644
--- a/source/Plugins/Process/elf-core/ThreadElfCore.h
+++ b/source/Plugins/Process/elf-core/ThreadElfCore.h
@@ -10,14 +10,11 @@
#ifndef liblldb_ThreadElfCore_h_
#define liblldb_ThreadElfCore_h_
-// C Includes
-// C++ Includes
-#include <string>
-
-// Other libraries and framework includes
-// Project includes
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataExtractor.h"
+#include "llvm/ADT/DenseMap.h"
+#include <string>
struct compat_timeval {
alignas(8) uint64_t tv_sec;
@@ -57,15 +54,15 @@ struct ELFLinuxPrStatus {
ELFLinuxPrStatus();
- lldb_private::Status Parse(lldb_private::DataExtractor &data,
- lldb_private::ArchSpec &arch);
+ lldb_private::Status Parse(const lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
// Return the bytesize of the structure
// 64 bit - just sizeof
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
- static size_t GetSize(lldb_private::ArchSpec &arch);
+ static size_t GetSize(const lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxPrStatus) == 112,
@@ -78,7 +75,7 @@ struct ELFLinuxSigInfo {
ELFLinuxSigInfo();
- lldb_private::Status Parse(lldb_private::DataExtractor &data,
+ lldb_private::Status Parse(const lldb_private::DataExtractor &data,
const lldb_private::ArchSpec &arch);
// Return the bytesize of the structure
@@ -113,15 +110,15 @@ struct ELFLinuxPrPsInfo {
ELFLinuxPrPsInfo();
- lldb_private::Status Parse(lldb_private::DataExtractor &data,
- lldb_private::ArchSpec &arch);
+ lldb_private::Status Parse(const lldb_private::DataExtractor &data,
+ const lldb_private::ArchSpec &arch);
// Return the bytesize of the structure
// 64 bit - just sizeof
// 32 bit - hardcoded because we are reusing the struct, but some of the
// members are smaller -
// so the layout is not the same
- static size_t GetSize(lldb_private::ArchSpec &arch);
+ static size_t GetSize(const lldb_private::ArchSpec &arch);
};
static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
@@ -129,8 +126,7 @@ static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
struct ThreadData {
lldb_private::DataExtractor gpregset;
- lldb_private::DataExtractor fpregset;
- lldb_private::DataExtractor vregset;
+ std::vector<lldb_private::CoreNote> notes;
lldb::tid_t tid;
int signo = 0;
int prstatus_sig = 0;
@@ -177,8 +173,7 @@ protected:
int m_signo;
lldb_private::DataExtractor m_gpregset_data;
- lldb_private::DataExtractor m_fpregset_data;
- lldb_private::DataExtractor m_vregset_data;
+ std::vector<lldb_private::CoreNote> m_notes;
bool CalculateStopInfo() override;
};
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 5e51feef1d3f..7ae25f83c5f8 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -7,6 +7,10 @@ set(LLDB_PLUGINS
lldbPluginPlatformMacOSX
)
+if(HAVE_LIBCOMPRESSION)
+ set(LIBCOMPRESSION compression)
+endif()
+
add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
GDBRemoteClientBase.cpp
GDBRemoteCommunication.cpp
@@ -30,6 +34,7 @@ add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
lldbTarget
lldbUtility
${LLDB_PLUGINS}
+ ${LIBCOMPRESSION}
LINK_COMPONENTS
Support
)
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 0c4df7e3f306..949cf19db658 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -600,10 +600,9 @@ bool GDBRemoteCommunication::DecompressPacket() {
#if defined(HAVE_LIBCOMPRESSION)
// libcompression is weak linked so check that compression_decode_buffer() is
// available
- if (compression_decode_buffer != NULL &&
- (m_compression_type == CompressionType::ZlibDeflate ||
- m_compression_type == CompressionType::LZFSE ||
- m_compression_type == CompressionType::LZ4)) {
+ if (m_compression_type == CompressionType::ZlibDeflate ||
+ m_compression_type == CompressionType::LZFSE ||
+ m_compression_type == CompressionType::LZ4) {
compression_algorithm compression_type;
if (m_compression_type == CompressionType::LZFSE)
compression_type = COMPRESSION_LZFSE;
@@ -815,7 +814,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
// checksum
if (m_bytes[0] == '$' && total_length > 4) {
for (size_t i = 0; !binary && i < total_length; ++i) {
- if (isprint(m_bytes[i]) == 0 && isspace(m_bytes[i]) == 0) {
+ unsigned char c = m_bytes[i];
+ if (isprint(c) == 0 && isspace(c) == 0) {
binary = true;
}
}
@@ -1375,3 +1375,39 @@ void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
}
}
}
+
+void llvm::format_provider<GDBRemoteCommunication::PacketResult>::format(
+ const GDBRemoteCommunication::PacketResult &result, raw_ostream &Stream,
+ StringRef Style) {
+ using PacketResult = GDBRemoteCommunication::PacketResult;
+
+ switch (result) {
+ case PacketResult::Success:
+ Stream << "Success";
+ break;
+ case PacketResult::ErrorSendFailed:
+ Stream << "ErrorSendFailed";
+ break;
+ case PacketResult::ErrorSendAck:
+ Stream << "ErrorSendAck";
+ break;
+ case PacketResult::ErrorReplyFailed:
+ Stream << "ErrorReplyFailed";
+ break;
+ case PacketResult::ErrorReplyTimeout:
+ Stream << "ErrorReplyTimeout";
+ break;
+ case PacketResult::ErrorReplyInvalid:
+ Stream << "ErrorReplyInvalid";
+ break;
+ case PacketResult::ErrorReplyAck:
+ Stream << "ErrorReplyAck";
+ break;
+ case PacketResult::ErrorDisconnected:
+ Stream << "ErrorDisconnected";
+ break;
+ case PacketResult::ErrorNoSequenceLock:
+ Stream << "ErrorNoSequenceLock";
+ break;
+ }
+}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index ce90de3e8470..ecc9386e49c7 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -290,4 +290,14 @@ private:
} // namespace process_gdb_remote
} // namespace lldb_private
+namespace llvm {
+template <>
+struct format_provider<
+ lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult> {
+ static void format(const lldb_private::process_gdb_remote::
+ GDBRemoteCommunication::PacketResult &state,
+ raw_ostream &Stream, StringRef Style);
+};
+} // namespace llvm
+
#endif // liblldb_GDBRemoteCommunication_h_
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index e6fd386b903b..867f57c475ce 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1022,10 +1022,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
std::string avail_name;
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "lzfse") {
avail_type = CompressionType::LZFSE;
@@ -1037,10 +1034,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
#endif
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "zlib-deflate") {
avail_type = CompressionType::ZlibDeflate;
@@ -1064,10 +1058,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
#endif
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "lz4") {
avail_type = CompressionType::LZ4;
@@ -1079,10 +1070,7 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression(
#endif
#if defined(HAVE_LIBCOMPRESSION)
- // libcompression is weak linked so test if compression_decode_buffer() is
- // available
- if (compression_decode_buffer != NULL &&
- avail_type == CompressionType::None) {
+ if (avail_type == CompressionType::None) {
for (auto compression : supported_compressions) {
if (compression == "lzma") {
avail_type = CompressionType::LZMA;
@@ -1601,21 +1589,24 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
// and we only want to override this behavior if we have explicitly
// received a qHostInfo telling us otherwise
if (m_qHostInfo_is_valid != eLazyBoolYes) {
- // On targets like MIPS, watchpoint exceptions are always generated
- // before the instruction is executed. The connected target may not
- // support qHostInfo or qWatchpointSupportInfo packets.
+ // On targets like MIPS and ppc64le, watchpoint exceptions are always
+ // generated before the instruction is executed. The connected target
+ // may not support qHostInfo or qWatchpointSupportInfo packets.
if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
- atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el ||
+ atype == llvm::Triple::ppc64le)
after = false;
else
after = true;
} else {
- // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
- // if it is not calculated before.
- if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
- (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
- atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
+ // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to
+ // eLazyBoolNo if it is not calculated before.
+ if ((m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
+ (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+ atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)) ||
+ atype == llvm::Triple::ppc64le) {
m_watchpoints_trigger_after_instruction = eLazyBoolNo;
+ }
after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
}
@@ -2624,8 +2615,8 @@ size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
* tid.
* Assume pid=tid=1 in such cases.
*/
- if (response.IsUnsupportedResponse() && thread_ids.size() == 0 &&
- IsConnected()) {
+ if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
+ thread_ids.size() == 0 && IsConnected()) {
thread_ids.push_back(1);
}
} else {
@@ -3451,7 +3442,9 @@ ParseModuleSpec(StructuredData::Dictionary *dict) {
if (!dict->GetValueForKeyAsString("uuid", string))
return llvm::None;
- result.GetUUID().SetFromStringRef(string, string.size());
+ if (result.GetUUID().SetFromStringRef(string, string.size() / 2) !=
+ string.size())
+ return llvm::None;
if (!dict->GetValueForKeyAsInteger("file_offset", integer))
return llvm::None;
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 712d85eed082..ba67b8246398 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -20,10 +20,8 @@
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StructuredData.h"
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index f53db502be93..3cf6b8ac07b2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -403,8 +403,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
match_info.SetMatchAllUsers(
Args::StringToBoolean(value, false, &success));
} else if (key.equals("triple")) {
- match_info.GetProcessInfo().GetArchitecture().SetTriple(
- value.str().c_str(), NULL);
+ match_info.GetProcessInfo().GetArchitecture() =
+ HostInfo::GetAugmentedArchSpec(value);
} else {
success = false;
}
@@ -973,8 +973,7 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
const uint32_t bytes_left = packet.GetBytesLeft();
if (bytes_left > 0) {
const char *arch_triple = packet.Peek();
- ArchSpec arch_spec(arch_triple, NULL);
- m_process_launch_info.SetArchitecture(arch_spec);
+ m_process_launch_info.SetArchitecture(HostInfo::GetAugmentedArchSpec(arch_triple));
return SendOKResponse();
}
return SendErrorResponse(13);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 9294359dbef1..32741c2404e2 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -204,21 +204,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
});
}
-Status
-GDBRemoteCommunicationServerLLGS::SetLaunchArguments(const char *const args[],
- int argc) {
- if ((argc < 1) || !args || !args[0] || !args[0][0])
- return Status("%s: no process command line specified to launch",
- __FUNCTION__);
-
- m_process_launch_info.SetArguments(const_cast<const char **>(args), true);
- return Status();
-}
-
-Status
-GDBRemoteCommunicationServerLLGS::SetLaunchFlags(unsigned int launch_flags) {
- m_process_launch_info.GetFlags().Set(launch_flags);
- return Status();
+void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) {
+ m_process_launch_info = info;
}
Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
@@ -244,13 +231,8 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
"process but one already exists");
auto process_or =
m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
- if (!process_or) {
- Status status(process_or.takeError());
- llvm::errs() << llvm::formatv(
- "failed to launch executable `{0}`: {1}",
- m_process_launch_info.GetArguments().GetArgumentAtIndex(0), status);
- return status;
- }
+ if (!process_or)
+ return Status(process_or.takeError());
m_debugged_process_up = std::move(*process_or);
}
@@ -396,12 +378,12 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf,
}
static void WriteRegisterValueInHexFixedWidth(
- StreamString &response, NativeRegisterContextSP &reg_ctx_sp,
+ StreamString &response, NativeRegisterContext &reg_ctx,
const RegisterInfo &reg_info, const RegisterValue *reg_value_p,
lldb::ByteOrder byte_order) {
RegisterValue reg_value;
if (!reg_value_p) {
- Status error = reg_ctx_sp->ReadRegister(&reg_info, reg_value);
+ Status error = reg_ctx.ReadRegister(&reg_info, reg_value);
if (error.Success())
reg_value_p = &reg_value;
// else log.
@@ -423,9 +405,7 @@ static void WriteRegisterValueInHexFixedWidth(
static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
- NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
- if (!reg_ctx_sp)
- return nullptr;
+ NativeRegisterContext& reg_ctx = thread.GetRegisterContext();
JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
@@ -448,14 +428,14 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
for (const uint32_t *generic_reg_p = k_expedited_registers;
*generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
- uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, *generic_reg_p);
if (reg_num == LLDB_INVALID_REGNUM)
continue; // Target does not support the given register.
#endif
const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+ reg_ctx.GetRegisterInfoAtIndex(reg_num);
if (reg_info_p == nullptr) {
if (log)
log->Printf(
@@ -469,7 +449,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
// registers.
RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
if (log)
log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
@@ -480,7 +460,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) {
}
StreamString stream;
- WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p,
+ WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p,
&reg_value, lldb::eByteOrderBig);
register_object_sp->SetObject(
@@ -523,16 +503,16 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
// Ensure we can get info on the given thread.
uint32_t thread_idx = 0;
- for (NativeThreadProtocolSP thread_sp;
- (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
+ for (NativeThreadProtocol *thread;
+ (thread = process.GetThreadAtIndex(thread_idx)) != nullptr;
++thread_idx) {
- lldb::tid_t tid = thread_sp->GetID();
+ lldb::tid_t tid = thread->GetID();
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread_sp->GetStopReason(tid_stop_info, description))
+ if (!thread->GetStopReason(tid_stop_info, description))
return nullptr;
const int signum = tid_stop_info.details.signal.signo;
@@ -548,7 +528,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
threads_array_sp->AppendObject(thread_obj_sp);
if (!abridged) {
- if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp))
+ if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread))
thread_obj_sp->SetObject("registers", registers_sp);
}
@@ -556,7 +536,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
if (signum != 0)
thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
- const std::string thread_name = thread_sp->GetName();
+ const std::string thread_name = thread->GetName();
if (!thread_name.empty())
thread_obj_sp->SetObject("name",
std::make_shared<JSONString>(thread_name));
@@ -604,14 +584,14 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
m_debugged_process_up->GetID(), tid);
// Ensure we can get info on the given thread.
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid));
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread)
return SendErrorResponse(51);
// Grab the reason this thread stopped.
struct ThreadStopInfo tid_stop_info;
std::string description;
- if (!thread_sp->GetStopReason(tid_stop_info, description))
+ if (!thread->GetStopReason(tid_stop_info, description))
return SendErrorResponse(52);
// FIXME implement register handling for exec'd inferiors.
@@ -638,7 +618,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.Printf("thread:%" PRIx64 ";", tid);
// Include the thread name if there is one.
- const std::string thread_name = thread_sp->GetName();
+ const std::string thread_name = thread->GetName();
if (!thread_name.empty()) {
size_t thread_name_len = thread_name.length();
@@ -665,15 +645,13 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutCString("threads:");
uint32_t thread_index = 0;
- NativeThreadProtocolSP listed_thread_sp;
- for (listed_thread_sp =
- m_debugged_process_up->GetThreadAtIndex(thread_index);
- listed_thread_sp; ++thread_index,
- listed_thread_sp = m_debugged_process_up->GetThreadAtIndex(
- thread_index)) {
+ NativeThreadProtocol *listed_thread;
+ for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ listed_thread; ++thread_index,
+ listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
if (thread_index > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, listed_thread_sp->GetID());
+ response.Printf("%" PRIx64, listed_thread->GetID());
}
response.PutChar(';');
@@ -701,20 +679,18 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
uint32_t i = 0;
response.PutCString("thread-pcs");
char delimiter = ':';
- for (NativeThreadProtocolSP thread_sp;
- (thread_sp = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
+ for (NativeThreadProtocol *thread;
+ (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr;
++i) {
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (!reg_ctx_sp)
- continue;
+ NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
- uint32_t reg_to_read = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+ uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber(
eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(reg_to_read);
+ reg_ctx.GetRegisterInfoAtIndex(reg_to_read);
RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
if (error.Fail()) {
if (log)
log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
@@ -727,7 +703,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
response.PutChar(delimiter);
delimiter = ',';
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
&reg_value, endian::InlHostByteOrder());
}
@@ -739,49 +715,48 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
//
// Grab the register context.
- NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
- if (reg_ctx_sp) {
- // Expedite all registers in the first register set (i.e. should be GPRs)
- // that are not contained in other registers.
- const RegisterSet *reg_set_p;
- if (reg_ctx_sp->GetRegisterSetCount() > 0 &&
- ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
- "from set '%s' (registers set count: %zu)",
- __FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- reg_set_p->num_registers);
-
- for (const uint32_t *reg_num_p = reg_set_p->registers;
- *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
- const RegisterInfo *const reg_info_p =
- reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p);
- if (reg_info_p == nullptr) {
+ NativeRegisterContext& reg_ctx = thread->GetRegisterContext();
+ // Expedite all registers in the first register set (i.e. should be GPRs)
+ // that are not contained in other registers.
+ const RegisterSet *reg_set_p;
+ if (reg_ctx.GetRegisterSetCount() > 0 &&
+ ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
+ "from set '%s' (registers set count: %zu)",
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ reg_set_p->num_registers);
+
+ for (const uint32_t *reg_num_p = reg_set_p->registers;
+ *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+ const RegisterInfo *const reg_info_p =
+ reg_ctx.GetRegisterInfoAtIndex(*reg_num_p);
+ if (reg_info_p == nullptr) {
+ if (log)
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
+ "register info for register set '%s', register index "
+ "%" PRIu32,
+ __FUNCTION__,
+ reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+ *reg_num_p);
+ } else if (reg_info_p->value_regs == nullptr) {
+ // Only expediate registers that are not contained in other registers.
+ RegisterValue reg_value;
+ Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
+ if (error.Success()) {
+ response.Printf("%.02x:", *reg_num_p);
+ WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p,
+ &reg_value, lldb::eByteOrderBig);
+ response.PutChar(';');
+ } else {
if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
- "register info for register set '%s', register index "
- "%" PRIu32,
+ log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
+ "register '%s' index %" PRIu32 ": %s",
__FUNCTION__,
- reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
- *reg_num_p);
- } else if (reg_info_p->value_regs == nullptr) {
- // Only expediate registers that are not contained in other registers.
- RegisterValue reg_value;
- Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
- if (error.Success()) {
- response.Printf("%.02x:", *reg_num_p);
- WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
- &reg_value, lldb::eByteOrderBig);
- response.PutChar(';');
- } else {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
- "register '%s' index %" PRIu32 ": %s",
- __FUNCTION__, reg_info_p->name ? reg_info_p->name
- : "<unnamed-register>",
- *reg_num_p, error.AsCString());
- }
+ reg_info_p->name ? reg_info_p->name
+ : "<unnamed-register>",
+ *reg_num_p, error.AsCString());
}
}
}
@@ -837,6 +812,7 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
// We are ready to exit the debug monitor.
m_exit_now = true;
+ m_mainloop.RequestTermination();
}
void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
@@ -1316,12 +1292,12 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID();
SetCurrentThreadID(tid);
- NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetCurrentThread();
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread();
+ if (!thread)
return SendErrorResponse(69);
StreamString response;
- response.Printf("QC%" PRIx64, thread_sp->GetID());
+ response.Printf("QC%" PRIx64, thread->GetID());
return SendPacketNoLock(response.GetString());
}
@@ -1692,14 +1668,12 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
return SendErrorResponse(68);
// Ensure we have a thread.
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadAtIndex(0));
- if (!thread_sp)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0);
+ if (!thread)
return SendErrorResponse(69);
// Get the register context for the first thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp)
- return SendErrorResponse(69);
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Parse out the register number from the request.
packet.SetFilePos(strlen("qRegisterInfo"));
@@ -1710,11 +1684,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount())
+ if (reg_index >= reg_context.GetUserRegisterCount())
return SendErrorResponse(69);
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info)
return SendErrorResponse(69);
@@ -1796,7 +1769,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
};
const char *const register_set_name =
- reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
+ reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index);
if (register_set_name) {
response.PutCString("set:");
response.PutCString(register_set_name);
@@ -1908,18 +1881,17 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
response.PutChar('m');
LLDB_LOG(log, "starting thread iteration");
- NativeThreadProtocolSP thread_sp;
+ NativeThreadProtocol *thread;
uint32_t thread_index;
for (thread_index = 0,
- thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index);
- thread_sp; ++thread_index,
- thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
- LLDB_LOG(log, "iterated thread {0}({1}, tid={2})", thread_index,
- thread_sp ? "is not null" : "null",
- thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID);
+ thread = m_debugged_process_up->GetThreadAtIndex(thread_index);
+ thread; ++thread_index,
+ thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) {
+ LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
+ thread->GetID());
if (thread_index > 0)
response.PutChar(',');
- response.Printf("%" PRIx64, thread_sp->GetID());
+ response.Printf("%" PRIx64, thread->GetID());
}
LLDB_LOG(log, "finished thread iteration");
@@ -1951,38 +1923,27 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
}
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s failed, no thread available",
- __FUNCTION__);
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
+ LLDB_LOG(log, "failed, no thread available");
return SendErrorResponse(0x15);
}
// Get the thread's register context.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (reg_index >= reg_context.GetUserRegisterCount()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
"register %" PRIu32 " beyond register count %" PRIu32,
__FUNCTION__, reg_index,
- reg_context_sp->GetUserRegisterCount());
+ reg_context.GetUserRegisterCount());
return SendErrorResponse(0x15);
}
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
@@ -1996,7 +1957,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
// Retrieve the value
RegisterValue reg_value;
- Status error = reg_context_sp->ReadRegister(reg_info, reg_value);
+ Status error = reg_context.ReadRegister(reg_info, reg_value);
if (error.Fail()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
@@ -2047,24 +2008,13 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
return SendIllFormedResponse(
packet, "P packet missing '=' char after register number");
- // Get process architecture.
- ArchSpec process_arch;
- if (!m_debugged_process_up ||
- !m_debugged_process_up->GetArchitecture(process_arch)) {
- if (log)
- log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve "
- "inferior architecture",
- __FUNCTION__);
- return SendErrorResponse(0x49);
- }
-
// Parse out the value.
uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
"available (thread index 0)",
@@ -2073,18 +2023,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
}
// Get the thread's register context.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- if (log)
- log->Printf(
- "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
- " failed, no register context available for the thread",
- __FUNCTION__, m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
-
- const RegisterInfo *reg_info =
- reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
+ const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index);
if (!reg_info) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
@@ -2095,12 +2035,11 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Return the end of registers response if we've iterated one past the end of
// the register set.
- if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+ if (reg_index >= reg_context.GetUserRegisterCount()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
"register %" PRIu32 " beyond register count %" PRIu32,
- __FUNCTION__, reg_index,
- reg_context_sp->GetUserRegisterCount());
+ __FUNCTION__, reg_index, reg_context.GetUserRegisterCount());
return SendErrorResponse(0x47);
}
@@ -2115,8 +2054,10 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
// Build the reginfos response.
StreamGDBRemote response;
- RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder());
- Status error = reg_context_sp->WriteRegister(reg_info, reg_value);
+ RegisterValue reg_value(
+ reg_bytes, reg_size,
+ m_debugged_process_up->GetArchitecture().GetByteOrder());
+ Status error = reg_context.WriteRegister(reg_info, reg_value);
if (error.Fail()) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
@@ -2177,8 +2118,8 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
// Ensure we have the given thread when not specifying -1 (all threads) or 0
// (any thread).
if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
- NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid));
- if (!thread_sp) {
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread) {
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
" not found",
@@ -2739,8 +2680,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
// Double check that we have such a thread.
// TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
- NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetThreadByID(tid);
- if (!thread_sp || thread_sp->GetID() != tid)
+ NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid);
+ if (!thread)
return SendErrorResponse(0x33);
// Create the step action for the given thread.
@@ -2865,8 +2806,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
packet.SetFilePos(strlen("QSaveRegisterState"));
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (m_thread_suffix_supported)
return SendIllFormedResponse(
packet, "No thread specified in QSaveRegisterState packet");
@@ -2876,18 +2817,11 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
}
// Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext& reg_context = thread->GetRegisterContext();
// Save registers to a buffer.
DataBufferSP register_data_sp;
- Status error = reg_context_sp->ReadAllRegisterValues(register_data_sp);
+ Status error = reg_context.ReadAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to save all register values: {1}",
m_debugged_process_up->GetID(), error);
@@ -2930,8 +2864,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
}
// Get the thread to use.
- NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
- if (!thread_sp) {
+ NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+ if (!thread) {
if (m_thread_suffix_supported)
return SendIllFormedResponse(
packet, "No thread specified in QRestoreRegisterState packet");
@@ -2941,14 +2875,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
}
// Grab the register context for the thread.
- NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
- if (!reg_context_sp) {
- LLDB_LOG(
- log,
- "pid {0} tid {1} failed, no register context available for the thread",
- m_debugged_process_up->GetID(), thread_sp->GetID());
- return SendErrorResponse(0x15);
- }
+ NativeRegisterContext &reg_context = thread->GetRegisterContext();
// Retrieve register state buffer, then remove from the list.
DataBufferSP register_data_sp;
@@ -2969,7 +2896,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
m_saved_registers_map.erase(it);
}
- Status error = reg_context_sp->WriteAllRegisterValues(register_data_sp);
+ Status error = reg_context.WriteAllRegisterValues(register_data_sp);
if (error.Fail()) {
LLDB_LOG(log, "pid {0} failed to restore all register values: {1}",
m_debugged_process_up->GetID(), error);
@@ -3219,14 +3146,12 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
}
}
-NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
StringExtractorGDBRemote &packet) {
- NativeThreadProtocolSP thread_sp;
-
// We have no thread if we don't have a process.
if (!m_debugged_process_up ||
m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)
- return thread_sp;
+ return nullptr;
// If the client hasn't asked for thread suffix support, there will not be a
// thread suffix.
@@ -3234,7 +3159,7 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
if (!m_thread_suffix_supported) {
const lldb::tid_t current_tid = GetCurrentThreadID();
if (current_tid == LLDB_INVALID_THREAD_ID)
- return thread_sp;
+ return nullptr;
else if (current_tid == 0) {
// Pick a thread.
return m_debugged_process_up->GetThreadAtIndex(0);
@@ -3251,11 +3176,11 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
"error: expected ';' prior to start of thread suffix: packet "
"contents = '%s'",
__FUNCTION__, packet.GetStringRef().c_str());
- return thread_sp;
+ return nullptr;
}
if (!packet.GetBytesLeft())
- return thread_sp;
+ return nullptr;
// Parse out thread: portion.
if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
@@ -3264,14 +3189,14 @@ NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
"error: expected 'thread:' but not found, packet contents = "
"'%s'",
__FUNCTION__, packet.GetStringRef().c_str());
- return thread_sp;
+ return nullptr;
}
packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
if (tid != 0)
return m_debugged_process_up->GetThreadByID(tid);
- return thread_sp;
+ return nullptr;
}
lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 71199473bb8e..5a74d1acaa23 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -43,32 +43,7 @@ public:
MainLoop &mainloop,
const NativeProcessProtocol::Factory &process_factory);
- //------------------------------------------------------------------
- /// Specify the program to launch and its arguments.
- ///
- /// @param[in] args
- /// The command line to launch.
- ///
- /// @param[in] argc
- /// The number of elements in the args array of cstring pointers.
- ///
- /// @return
- /// An Status object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Status SetLaunchArguments(const char *const args[], int argc);
-
- //------------------------------------------------------------------
- /// Specify the launch flags for the process.
- ///
- /// @param[in] launch_flags
- /// The launch flags to use when launching this process.
- ///
- /// @return
- /// An Status object indicating the success or failure of making
- /// the setting.
- //------------------------------------------------------------------
- Status SetLaunchFlags(unsigned int launch_flags);
+ void SetLaunchInfo(const ProcessLaunchInfo &info);
//------------------------------------------------------------------
/// Launch a process with the current launch settings.
@@ -234,7 +209,7 @@ private:
void HandleInferiorState_Stopped(NativeProcessProtocol *process);
- NativeThreadProtocolSP GetThreadFromSuffix(StringExtractorGDBRemote &packet);
+ NativeThreadProtocol *GetThreadFromSuffix(StringExtractorGDBRemote &packet);
uint32_t GetNextSavedRegistersID();
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index 977c34c2a69b..04ed9d704e13 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -128,8 +128,9 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
llvm::StringRef platform_ip;
int platform_port;
llvm::StringRef platform_path;
- bool ok = UriParser::Parse(GetConnection()->GetURI(), platform_scheme,
- platform_ip, platform_port, platform_path);
+ std::string platform_uri = GetConnection()->GetURI();
+ bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip,
+ platform_port, platform_path);
UNUSED_IF_ASSERT_DISABLED(ok);
assert(ok);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 612c7144451e..e418deee01f3 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -178,7 +178,7 @@ bool GDBRemoteRegisterContext::GetPrimordialRegister(
const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
- StringExtractorGDBRemote response;
+
if (DataBufferSP buffer_sp =
gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
return PrivateSetRegisterValue(
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index be11dd9bc7ec..35d02c15ab85 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -29,7 +29,6 @@
#include <sstream>
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
@@ -244,7 +243,7 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
//----------------------------------------------------------------------
ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
ListenerSP listener_sp)
- : Process(target_sp, listener_sp), m_flags(0), m_gdb_comm(),
+ : Process(target_sp, listener_sp),
m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
m_register_info(),
m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
@@ -818,7 +817,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
if (object_file) {
error = EstablishConnectionIfNeeded(launch_info);
if (error.Success()) {
- lldb_utility::PseudoTerminal pty;
+ PseudoTerminal pty;
const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
PlatformSP platform_sp(GetTarget().GetPlatform());
@@ -947,8 +946,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module,
SetPrivateState(SetThreadStopInfo(response));
if (!disable_stdio) {
- if (pty.GetMasterFileDescriptor() !=
- lldb_utility::PseudoTerminal::invalid_fd)
+ if (pty.GetMasterFileDescriptor() != PseudoTerminal::invalid_fd)
SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
}
}
@@ -3255,7 +3253,6 @@ Status ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
}
void ProcessGDBRemote::Clear() {
- m_flags = 0;
m_thread_list_real.Clear();
m_thread_list.Clear();
}
@@ -3289,7 +3286,7 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) {
}
return error;
}
-#if defined(__APPLE__)
+#if !defined(_WIN32)
#define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
#endif
@@ -3333,8 +3330,8 @@ Status ProcessGDBRemote::LaunchAndConnectToDebugserver(
lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
- // Use a socketpair on Apple for now until other platforms can verify it
- // works and is fast enough
+ // Use a socketpair on non-Windows systems for security and performance
+ // reasons.
{
int sockets[2]; /* the pair of socket descriptors */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
@@ -4168,7 +4165,6 @@ struct GdbServerTargetInfo {
std::string osabi;
stringVec includes;
RegisterSetMap reg_set_map;
- XMLNode feature_node;
};
bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
@@ -4374,8 +4370,8 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
XMLNode target_node = xml_document.GetRootElement("target");
if (target_node) {
- XMLNode feature_node;
- target_node.ForEachChildElement([&target_info, &feature_node](
+ std::vector<XMLNode> feature_nodes;
+ target_node.ForEachChildElement([&target_info, &feature_nodes](
const XMLNode &node) -> bool {
llvm::StringRef name = node.GetName();
if (name == "architecture") {
@@ -4387,7 +4383,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
if (!href.empty())
target_info.includes.push_back(href.str());
} else if (name == "feature") {
- feature_node = node;
+ feature_nodes.push_back(node);
} else if (name == "groups") {
node.ForEachChildElementWithName(
"group", [&target_info](const XMLNode &node) -> bool {
@@ -4423,7 +4419,7 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
// set the Target's architecture yet, so the ABI is also potentially
// incorrect.
ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use);
- if (feature_node) {
+ for (auto &feature_node : feature_nodes) {
ParseRegisters(feature_node, target_info, this->m_register_info,
abi_to_use_sp, cur_reg_num, reg_offset);
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 54a472d7332e..42d1c4ecd666 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -18,9 +18,6 @@
#include <string>
#include <vector>
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/LoadedModuleInfoList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -28,6 +25,7 @@
#include "lldb/Host/HostThread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamGDBRemote.h"
@@ -263,7 +261,6 @@ protected:
eBroadcastBitAsyncThreadDidExit = (1 << 2)
};
- Flags m_flags; // Process specific flags (see eFlags enums)
GDBRemoteCommunicationClient m_gdb_comm;
std::atomic<lldb::pid_t> m_debugserver_pid;
std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet
@@ -324,10 +321,6 @@ protected:
void Clear();
- Flags &GetFlags() { return m_flags; }
-
- const Flags &GetFlags() const { return m_flags; }
-
bool UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 5197e8f9adfc..27dd03bfc7bc 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -10,7 +10,6 @@
#include "ThreadGDBRemote.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index a6178500dfc5..d21651b77ee0 100644
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -468,7 +468,7 @@ Status ProcessMachCore::DoLoadCore() {
// it to match the core file which is always single arch.
ArchSpec arch(m_core_module_sp->GetArchitecture());
if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
- arch.SetTriple("i386", GetTarget().GetPlatform().get());
+ arch = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
}
if (arch.IsValid())
GetTarget().SetArchitecture(arch);
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
index 3917b99bd63d..2b44105c13b1 100644
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
@@ -12,7 +12,6 @@
#include "lldb/Utility/SafeMachO.h"
#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
@@ -20,6 +19,7 @@
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/StreamString.h"
diff --git a/source/Plugins/Process/minidump/MinidumpParser.h b/source/Plugins/Process/minidump/MinidumpParser.h
index df6deb482afd..b7329ffc0028 100644
--- a/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/source/Plugins/Process/minidump/MinidumpParser.h
@@ -14,8 +14,7 @@
// Project includes
#include "MinidumpTypes.h"
-// Other libraries and framework includes
-#include "lldb/Core/ArchSpec.h"
+#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/Status.h"
diff --git a/source/Plugins/Process/minidump/ProcessMinidump.h b/source/Plugins/Process/minidump/ProcessMinidump.h
index d5c46be97352..4b91d1ba396a 100644
--- a/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -82,6 +82,14 @@ public:
bool GetProcessInfo(ProcessInstanceInfo &info) override;
+ Status WillResume() override {
+ Status error;
+ error.SetErrorStringWithFormat(
+ "error: %s does not support resuming processes",
+ GetPluginName().GetCString());
+ return error;
+ }
+
MinidumpParser m_minidump_parser;
protected:
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.cpp b/source/Plugins/Process/minidump/ThreadMinidump.cpp
index 9c21cc92376f..3fafb6134e7f 100644
--- a/source/Plugins/Process/minidump/ThreadMinidump.cpp
+++ b/source/Plugins/Process/minidump/ThreadMinidump.cpp
@@ -17,8 +17,8 @@
// Other libraries and framework includes
#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
-
#include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
@@ -43,8 +43,6 @@ ThreadMinidump::~ThreadMinidump() {}
void ThreadMinidump::RefreshStateAfterStop() {}
-void ThreadMinidump::ClearStackFrames() {}
-
RegisterContextSP ThreadMinidump::GetRegisterContext() {
if (!m_reg_context_sp) {
m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
@@ -76,20 +74,18 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
reg_interface = new RegisterContextLinux_i386(arch);
lldb::DataBufferSP buf =
ConvertMinidumpContext_x86_32(m_gpregset_data, reg_interface);
- DataExtractor gpregs(buf, lldb::eByteOrderLittle, 4);
- DataExtractor fpregs;
+ DataExtractor gpregset(buf, lldb::eByteOrderLittle, 4);
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
- *this, reg_interface, gpregs, fpregs));
+ *this, reg_interface, gpregset, {}));
break;
}
case llvm::Triple::x86_64: {
reg_interface = new RegisterContextLinux_x86_64(arch);
lldb::DataBufferSP buf =
ConvertMinidumpContext_x86_64(m_gpregset_data, reg_interface);
- DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8);
- DataExtractor fpregs;
+ DataExtractor gpregset(buf, lldb::eByteOrderLittle, 8);
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
- *this, reg_interface, gpregs, fpregs));
+ *this, reg_interface, gpregset, {}));
break;
}
default:
diff --git a/source/Plugins/Process/minidump/ThreadMinidump.h b/source/Plugins/Process/minidump/ThreadMinidump.h
index 97db452edfff..74ac44f74dcf 100644
--- a/source/Plugins/Process/minidump/ThreadMinidump.h
+++ b/source/Plugins/Process/minidump/ThreadMinidump.h
@@ -37,8 +37,6 @@ public:
lldb::RegisterContextSP
CreateRegisterContextForFrame(StackFrame *frame) override;
- void ClearStackFrames() override;
-
protected:
lldb::RegisterContextSP m_thread_reg_ctx_sp;
llvm::ArrayRef<uint8_t> m_gpregset_data;