diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Process')
52 files changed, 3485 insertions, 1381 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index 4b48844..5a0b5ed 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -258,8 +258,7 @@ ProcessFreeBSD::SendMessage(const ProcessMessage &message) case ProcessMessage::eLimboMessage: case ProcessMessage::eExitMessage: - m_exit_status = message.GetExitStatus(); - SetExitStatus(m_exit_status, NULL); + SetExitStatus(message.GetExitStatus(), NULL); break; case ProcessMessage::eSignalMessage: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 63439b1..84e35ba 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -25,6 +25,7 @@ #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Host/Host.h" +#include "lldb/Host/ThreadLauncher.h" #include "lldb/Target/Thread.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/PseudoTerminal.h" @@ -112,6 +113,7 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data, log->Printf("PT_GETREGS: ax=0x%lx", r->r_rax); } #endif +#ifndef __powerpc__ if (req == PT_GETDBREGS || req == PT_SETDBREGS) { struct dbreg *r = (struct dbreg *) addr; char setget = (req == PT_GETDBREGS) ? 'G' : 'S'; @@ -119,6 +121,7 @@ PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data, for (int i = 0; i <= 7; i++) log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]); } +#endif } return result; @@ -309,9 +312,14 @@ ReadRegOperation::Execute(ProcessMonitor *monitor) if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)®s, 0)) < 0) { m_result = false; } else { - if (m_size == sizeof(uintptr_t)) - m_value = *(uintptr_t *)(((caddr_t)®s) + m_offset); - else + // 'struct reg' contains only 32- or 64-bit register values. Punt on + // others. Also, not all entries may be uintptr_t sized, such as 32-bit + // processes on powerpc64 (probably the same for i386 on amd64) + if (m_size == sizeof(uint32_t)) + m_value = *(uint32_t *)(((caddr_t)®s) + m_offset); + else if (m_size == sizeof(uint64_t)) + m_value = *(uint64_t *)(((caddr_t)®s) + m_offset); + else memcpy(&m_value, (((caddr_t)®s) + m_offset), m_size); m_result = true; } @@ -810,8 +818,6 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, const lldb_private::ProcessLaunchInfo & /* launch_info */, lldb_private::Error &error) : m_process(static_cast<ProcessFreeBSD *>(process)), - m_operation_thread(LLDB_INVALID_HOST_THREAD), - m_monitor_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), m_terminal_fd(-1), m_operation(0) @@ -852,7 +858,7 @@ WAIT_AGAIN: // Finally, start monitoring the child process for change in state. m_monitor_thread = Host::StartMonitoringChildProcess( ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) + if (!m_monitor_thread.IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString("Process launch failed."); @@ -864,8 +870,6 @@ ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, lldb::pid_t pid, lldb_private::Error &error) : m_process(static_cast<ProcessFreeBSD *>(process)), - m_operation_thread(LLDB_INVALID_HOST_THREAD), - m_monitor_thread(LLDB_INVALID_HOST_THREAD), m_pid(pid), m_terminal_fd(-1), m_operation(0) @@ -904,7 +908,7 @@ WAIT_AGAIN: // Finally, start monitoring the child process for change in state. m_monitor_thread = Host::StartMonitoringChildProcess( ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) + if (!m_monitor_thread.IsJoinable()) { error.SetErrorToGenericError(); error.SetErrorString("Process attach failed."); @@ -924,11 +928,10 @@ ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error) { static const char *g_thread_name = "lldb.process.freebsd.operation"; - if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) + if (m_operation_thread.IsJoinable()) return; - m_operation_thread = - Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error); + m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error); } void * @@ -1101,11 +1104,10 @@ ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error { static const char *g_thread_name = "lldb.process.freebsd.operation"; - if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) + if (m_operation_thread.IsJoinable()) return; - m_operation_thread = - Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error); + m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error); } void * @@ -1113,14 +1115,13 @@ ProcessMonitor::AttachOpThread(void *arg) { AttachArgs *args = static_cast<AttachArgs*>(arg); - if (!Attach(args)) - return NULL; + Attach(args); ServeOperation(args); return NULL; } -bool +void ProcessMonitor::Attach(AttachArgs *args) { lldb::pid_t pid = args->m_pid; @@ -1132,27 +1133,24 @@ ProcessMonitor::Attach(AttachArgs *args) { args->m_error.SetErrorToGenericError(); args->m_error.SetErrorString("Attaching to process 1 is not allowed."); - goto FINISH; + return; } // Attach to the requested process. if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) { args->m_error.SetErrorToErrno(); - goto FINISH; + return; } int status; if ((status = waitpid(pid, NULL, 0)) < 0) { args->m_error.SetErrorToErrno(); - goto FINISH; + return; } process.SendMessage(ProcessMessage::Attach(pid)); - -FINISH: - return args->m_error.Success(); } size_t @@ -1714,13 +1712,11 @@ ProcessMonitor::DupDescriptor(const char *path, int fd, int flags) void ProcessMonitor::StopMonitoringChildProcess() { - lldb::thread_result_t thread_result; - - if (IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) + if (m_monitor_thread.IsJoinable()) { - Host::ThreadCancel(m_monitor_thread, NULL); - Host::ThreadJoin(m_monitor_thread, &thread_result, NULL); - m_monitor_thread = LLDB_INVALID_HOST_THREAD; + m_monitor_thread.Cancel(); + m_monitor_thread.Join(nullptr); + m_monitor_thread.Reset(); } } @@ -1764,12 +1760,10 @@ ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid) void ProcessMonitor::StopOpThread() { - lldb::thread_result_t result; - - if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) + if (!m_operation_thread.IsJoinable()) return; - Host::ThreadCancel(m_operation_thread, NULL); - Host::ThreadJoin(m_operation_thread, &result, NULL); - m_operation_thread = LLDB_INVALID_HOST_THREAD; + m_operation_thread.Cancel(); + m_operation_thread.Join(nullptr); + m_operation_thread.Reset(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 314743b..935fd85 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -17,6 +17,7 @@ // C++ Includes // Other libraries and framework includes #include "lldb/lldb-types.h" +#include "lldb/Host/HostThread.h" #include "lldb/Host/Mutex.h" namespace lldb_private @@ -212,8 +213,8 @@ public: private: ProcessFreeBSD *m_process; - lldb::thread_t m_operation_thread; - lldb::thread_t m_monitor_thread; + lldb_private::HostThread m_operation_thread; + lldb_private::HostThread m_monitor_thread; lldb::pid_t m_pid; int m_terminal_fd; @@ -289,7 +290,7 @@ private: static void * AttachOpThread(void *args); - static bool + static void Attach(AttachArgs *args); static void diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp index d48f8f9..1057585 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp @@ -20,27 +20,30 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/State.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostNativeThread.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "llvm/ADT/SmallString.h" #include "POSIXStopInfo.h" #include "POSIXThread.h" #include "ProcessPOSIX.h" #include "ProcessPOSIXLog.h" -#include "ProcessMonitor.h" +#include "Plugins/Process/Linux/ProcessMonitor.h" #include "RegisterContextPOSIXProcessMonitor_arm64.h" #include "RegisterContextPOSIXProcessMonitor_mips64.h" +#include "RegisterContextPOSIXProcessMonitor_powerpc.h" #include "RegisterContextPOSIXProcessMonitor_x86.h" -#include "RegisterContextLinux_arm64.h" -#include "RegisterContextLinux_i386.h" -#include "RegisterContextLinux_x86_64.h" -#include "RegisterContextFreeBSD_i386.h" -#include "RegisterContextFreeBSD_mips64.h" -#include "RegisterContextFreeBSD_x86_64.h" - -#include "UnwindLLDB.h" +#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_i386.h" +#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" +#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/UnwindLLDB.h" using namespace lldb; using namespace lldb_private; @@ -140,7 +143,9 @@ POSIXThread::GetName () { if (!m_thread_name_valid) { - SetName(Host::GetThreadName(GetProcess()->GetID(), GetID()).c_str()); + llvm::SmallString<32> thread_name; + HostNativeThread::GetName(GetID(), thread_name); + m_thread_name = thread_name.c_str(); m_thread_name_valid = true; } @@ -164,6 +169,14 @@ POSIXThread::GetRegisterContext() case llvm::Triple::FreeBSD: switch (target_arch.GetMachine()) { + case llvm::Triple::ppc: +#ifndef __powerpc64__ + reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch); + break; +#endif + case llvm::Triple::ppc64: + reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch); + break; case llvm::Triple::mips64: reg_interface = new RegisterContextFreeBSD_mips64(target_arch); break; @@ -226,6 +239,14 @@ POSIXThread::GetRegisterContext() m_reg_context_sp.reset(reg_ctx); break; } + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + { + RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx = new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0, reg_interface); + m_posix_thread = reg_ctx; + m_reg_context_sp.reset(reg_ctx); + break; + } case llvm::Triple::x86: case llvm::Triple::x86_64: { @@ -621,6 +642,8 @@ POSIXThread::GetRegisterIndexFromOffset(unsigned offset) case llvm::Triple::aarch64: case llvm::Triple::mips64: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: case llvm::Triple::x86: case llvm::Triple::x86_64: { @@ -652,6 +675,8 @@ POSIXThread::GetRegisterName(unsigned reg) case llvm::Triple::aarch64: case llvm::Triple::mips64: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: case llvm::Triple::x86: case llvm::Triple::x86_64: name = GetRegisterContext()->GetRegisterName(reg); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index f340631..0e5ab5a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -16,6 +16,7 @@ // Other libraries and framework includes #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/State.h" #include "lldb/Host/FileSpec.h" @@ -28,7 +29,7 @@ #include "ProcessPOSIX.h" #include "ProcessPOSIXLog.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "ProcessMonitor.h" +#include "Plugins/Process/Linux/ProcessMonitor.h" #include "POSIXThread.h" using namespace lldb; @@ -140,8 +141,8 @@ ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) // Resolve the executable module ModuleSP exe_module_sp; FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); - error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), - m_target.GetArchitecture(), + ModuleSpec exe_module_spec(process_info.GetExecutableFile(), m_target.GetArchitecture()); + error = platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp, executable_search_paths.GetSize() ? &executable_search_paths : NULL); if (!error.Success()) @@ -176,9 +177,9 @@ ProcessPOSIX::WillLaunch(Module* module) } const char * -ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const char *default_path) +ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const char *default_path, + const char *dbg_pts_path) { - const char *pts_name = "/dev/pts/"; const char *path = NULL; if (file_action) @@ -190,11 +191,11 @@ ProcessPOSIX::GetFilePath(const lldb_private::FileAction *file_action, const cha // (/dev/pts). If so, convert to using a different default path // instead to redirect I/O to the debugger console. This should // also handle user overrides to /dev/null or a different file. - if (!path || ::strncmp(path, pts_name, ::strlen(pts_name)) == 0) + if (!path || (dbg_pts_path && + ::strncmp(path, dbg_pts_path, ::strlen(dbg_pts_path)) == 0)) path = default_path; } } - return path; } @@ -224,14 +225,16 @@ ProcessPOSIX::DoLaunch (Module *module, const char *stdout_path = NULL; const char *stderr_path = NULL; + const char * dbg_pts_path = launch_info.GetPTY().GetSlaveName(NULL,0); + file_action = launch_info.GetFileActionForFD (STDIN_FILENO); - stdin_path = GetFilePath(file_action, stdin_path); + stdin_path = GetFilePath(file_action, stdin_path, dbg_pts_path); file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); - stdout_path = GetFilePath(file_action, stdout_path); + stdout_path = GetFilePath(file_action, stdout_path, dbg_pts_path); file_action = launch_info.GetFileActionForFD (STDERR_FILENO); - stderr_path = GetFilePath(file_action, stderr_path); + stderr_path = GetFilePath(file_action, stderr_path, dbg_pts_path); m_monitor = new ProcessMonitor (this, module, @@ -338,6 +341,11 @@ ProcessPOSIX::DoDestroy() { assert(m_monitor); m_exit_now = true; + if (GetID() == LLDB_INVALID_PROCESS_ID) + { + error.SetErrorString("invalid process id"); + return error; + } if (!m_monitor->Kill()) { error.SetErrorToErrno(); @@ -363,11 +371,11 @@ ProcessPOSIX::DoDidExec() ProcessInstanceInfo process_info; platform_sp->GetProcessInfo(GetID(), process_info); ModuleSP exe_module_sp; + ModuleSpec exe_module_spec(process_info.GetExecutableFile(), target->GetArchitecture()); FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); - Error error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), - target->GetArchitecture(), - exe_module_sp, - executable_search_paths.GetSize() ? &executable_search_paths : NULL); + Error error = platform_sp->ResolveExecutable(exe_module_spec, + exe_module_sp, + executable_search_paths.GetSize() ? &executable_search_paths : NULL); if (!error.Success()) return; target->SetExecutableModule(exe_module_sp, true); @@ -432,8 +440,7 @@ ProcessPOSIX::SendMessage(const ProcessMessage &message) // FIXME: I'm not sure we need to do this. if (message.GetTID() == GetID()) { - m_exit_status = message.GetExitStatus(); - SetExitStatus(m_exit_status, NULL); + SetExitStatus(message.GetExitStatus(), NULL); } else if (!IsAThreadRunning()) SetPrivateState(eStateStopped); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h index 033accf..f152356 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h @@ -42,104 +42,104 @@ public: // Process protocol. //------------------------------------------------------------------ virtual void - Finalize(); + Finalize() override; virtual bool - CanDebug(lldb_private::Target &target, bool plugin_specified_by_name); + CanDebug(lldb_private::Target &target, bool plugin_specified_by_name) override; virtual lldb_private::Error - WillLaunch(lldb_private::Module *module); + WillLaunch(lldb_private::Module *module) override; virtual lldb_private::Error - DoAttachToProcessWithID(lldb::pid_t pid); + DoAttachToProcessWithID(lldb::pid_t pid) override; virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info); + DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override; virtual lldb_private::Error DoLaunch (lldb_private::Module *exe_module, - lldb_private::ProcessLaunchInfo &launch_info); + lldb_private::ProcessLaunchInfo &launch_info) override; virtual void - DidLaunch(); + DidLaunch() override; virtual lldb_private::Error - DoResume(); + DoResume() override; virtual lldb_private::Error - DoHalt(bool &caused_stop); + DoHalt(bool &caused_stop) override; virtual lldb_private::Error - DoDetach(bool keep_stopped) = 0; + DoDetach(bool keep_stopped) override = 0; virtual lldb_private::Error - DoSignal(int signal); + DoSignal(int signal) override; virtual lldb_private::Error - DoDestroy(); + DoDestroy() override; virtual void - DoDidExec(); + DoDidExec() override; virtual void - RefreshStateAfterStop(); + RefreshStateAfterStop() override; virtual bool - IsAlive(); + IsAlive() override; virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - lldb_private::Error &error); + lldb_private::Error &error) override; virtual size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error); + lldb_private::Error &error) override; virtual lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, - lldb_private::Error &error); + lldb_private::Error &error) override; virtual lldb_private::Error - DoDeallocateMemory(lldb::addr_t ptr); + DoDeallocateMemory(lldb::addr_t ptr) override; virtual size_t GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site); virtual lldb_private::Error - EnableBreakpointSite(lldb_private::BreakpointSite *bp_site); + EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; virtual lldb_private::Error - DisableBreakpointSite(lldb_private::BreakpointSite *bp_site); + DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; virtual lldb_private::Error - EnableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true); + EnableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override; virtual lldb_private::Error - DisableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true); + DisableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override; virtual lldb_private::Error - GetWatchpointSupportInfo(uint32_t &num); + GetWatchpointSupportInfo(uint32_t &num) override; virtual lldb_private::Error - GetWatchpointSupportInfo(uint32_t &num, bool &after); + GetWatchpointSupportInfo(uint32_t &num, bool &after) override; virtual uint32_t UpdateThreadListIfNeeded(); virtual bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list) = 0; + lldb_private::ThreadList &new_thread_list) override = 0; virtual lldb::ByteOrder GetByteOrder() const; virtual lldb::addr_t - GetImageInfoAddress(); + GetImageInfoAddress() override; virtual size_t - PutSTDIN(const char *buf, size_t len, lldb_private::Error &error); + PutSTDIN(const char *buf, size_t len, lldb_private::Error &error) override; const lldb::DataBufferSP GetAuxvData () override; @@ -154,7 +154,8 @@ public: ProcessMonitor & GetMonitor() { assert(m_monitor); return *m_monitor; } - const char *GetFilePath(const lldb_private::FileAction *file_action, const char *default_path); + const char *GetFilePath(const lldb_private::FileAction *file_action, const char *default_path, + const char *dbg_pts_path); /// Stops all threads in the process. /// The \p stop_tid parameter indicates the thread which initiated the stop. diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp index 9109cdb..ec34d9e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -10,10 +10,10 @@ #include "lldb/Target/Thread.h" #include "lldb/Core/RegisterValue.h" -#include "RegisterContextPOSIX_arm64.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" #include "ProcessPOSIX.h" #include "RegisterContextPOSIXProcessMonitor_arm64.h" -#include "ProcessMonitor.h" +#include "Plugins/Process/Linux/ProcessMonitor.h" #define REG_CONTEXT_SIZE (GetGPRSize()) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp index 9bfe236..6717d20 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp @@ -10,10 +10,10 @@ #include "lldb/Target/Thread.h" #include "lldb/Core/RegisterValue.h" -#include "RegisterContextPOSIX_mips64.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" #include "ProcessPOSIX.h" #include "RegisterContextPOSIXProcessMonitor_mips64.h" -#include "ProcessMonitor.h" +#include "Plugins/Process/Linux/ProcessMonitor.h" using namespace lldb_private; using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp new file mode 100644 index 0000000..b542db4 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -0,0 +1,321 @@ +//===-- RegisterContextPOSIXProcessMonitor_powerpc.h ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include "lldb/Target/Thread.h" +#include "lldb/Core/RegisterValue.h" + +#include "RegisterContextPOSIX_powerpc.h" +#include "ProcessPOSIX.h" +#include "RegisterContextPOSIXProcessMonitor_powerpc.h" +#include "ProcessMonitor.h" + +using namespace lldb_private; +using namespace lldb; + +#define REG_CONTEXT_SIZE (GetGPRSize()) + +RegisterContextPOSIXProcessMonitor_powerpc::RegisterContextPOSIXProcessMonitor_powerpc(Thread &thread, + uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info) + : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) +{ +} + +ProcessMonitor & +RegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() +{ + ProcessSP base = CalculateProcess(); + ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); + return process->GetMonitor(); +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() +{ + ProcessMonitor &monitor = GetMonitor(); + return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() +{ + // XXX not yet implemented + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() +{ + ProcessMonitor &monitor = GetMonitor(); + return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() +{ + // XXX not yet implemented + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const unsigned reg, + RegisterValue &value) +{ + ProcessMonitor &monitor = GetMonitor(); + return monitor.ReadRegisterValue(m_thread.GetID(), + GetRegisterOffset(reg), + GetRegisterName(reg), + GetRegisterSize(reg), + value); +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const unsigned reg, + const RegisterValue &value) +{ + unsigned reg_to_write = reg; + RegisterValue value_to_write = value; + + // Check if this is a subregister of a full register. + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); + if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) + { + RegisterValue full_value; + uint32_t full_reg = reg_info->invalidate_regs[0]; + const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); + + // Read the full register. + if (ReadRegister(full_reg_info, full_value)) + { + Error error; + ByteOrder byte_order = GetByteOrder(); + uint8_t dst[RegisterValue::kMaxRegisterByteSize]; + + // Get the bytes for the full register. + const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, + dst, + sizeof(dst), + byte_order, + error); + if (error.Success() && dest_size) + { + uint8_t src[RegisterValue::kMaxRegisterByteSize]; + + // Get the bytes for the source data. + const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); + if (error.Success() && src_size && (src_size < dest_size)) + { + // Copy the src bytes to the destination. + memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); + // Set this full register as the value to write. + value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); + value_to_write.SetType(full_reg_info); + reg_to_write = full_reg; + } + } + } + } + + ProcessMonitor &monitor = GetMonitor(); + // Account for the fact that 32-bit targets on powerpc64 really use 64-bit + // registers in ptrace, but expose here 32-bit registers with a higher + // offset. + uint64_t offset = GetRegisterOffset(reg_to_write); + offset &= ~(sizeof(uintptr_t) - 1); + return monitor.WriteRegisterValue(m_thread.GetID(), + offset, + GetRegisterName(reg_to_write), + value_to_write); +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) +{ + if (!reg_info) + return false; + + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + + if (IsFPR(reg)) + { + if (!ReadFPR()) + return false; + } + else + { + uint32_t full_reg = reg; + bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); + + if (is_subreg) + { + // Read the full aligned 64-bit register. + full_reg = reg_info->invalidate_regs[0]; + } + + bool success = ReadRegister(full_reg, value); + + if (success) + { + // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. + if (is_subreg && (reg_info->byte_offset & 0x1)) + value.SetUInt64(value.GetAsUInt64() >> 8); + + // If our return byte size was greater than the return value reg size, then + // use the type specified by reg_info rather than the uint64_t default + if (value.GetByteSize() > reg_info->byte_size) + value.SetType(reg_info); + } + return success; + } + + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) +{ + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + + if (IsGPR(reg)) + return WriteRegister(reg, value); + + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ReadAllRegisterValues(DataBufferSP &data_sp) +{ + bool success = false; + data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); + if (data_sp && ReadGPR () && ReadFPR ()) + { + uint8_t *dst = data_sp->GetBytes(); + success = dst != 0; + + if (success) + { + ::memcpy (dst, &m_gpr_powerpc, GetGPRSize()); + dst += GetGPRSize(); + } + } + return success; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::WriteAllRegisterValues(const DataBufferSP &data_sp) +{ + bool success = false; + if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) + { + uint8_t *src = data_sp->GetBytes(); + if (src) + { + ::memcpy (&m_gpr_powerpc, src, GetGPRSize()); + + if (WriteGPR()) + { + src += GetGPRSize(); + } + } + } + return success; +} + +uint32_t +RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpoint(addr_t addr, size_t size, + bool read, bool write) +{ + const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); + uint32_t hw_index; + + for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) + { + if (IsWatchpointVacant(hw_index)) + return SetHardwareWatchpointWithIndex(addr, size, + read, write, + hw_index); + } + + return LLDB_INVALID_INDEX32; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ClearHardwareWatchpoint(uint32_t hw_index) +{ + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::HardwareSingleStep(bool enable) +{ + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::UpdateAfterBreakpoint() +{ + lldb::addr_t pc; + + if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) + return false; + + return true; +} + +unsigned +RegisterContextPOSIXProcessMonitor_powerpc::GetRegisterIndexFromOffset(unsigned offset) +{ + unsigned reg; + for (reg = 0; reg < k_num_registers_powerpc; reg++) + { + if (GetRegisterInfo()[reg].byte_offset == offset) + break; + } + assert(reg < k_num_registers_powerpc && "Invalid register offset."); + return reg; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointHit(uint32_t hw_index) +{ + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::ClearWatchpointHits() +{ + return false; +} + +addr_t +RegisterContextPOSIXProcessMonitor_powerpc::GetWatchpointAddress(uint32_t hw_index) +{ + return LLDB_INVALID_ADDRESS; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::IsWatchpointVacant(uint32_t hw_index) +{ + return false; +} + +bool +RegisterContextPOSIXProcessMonitor_powerpc::SetHardwareWatchpointWithIndex(addr_t addr, size_t size, + bool read, bool write, + uint32_t hw_index) +{ + return false; +} + +uint32_t +RegisterContextPOSIXProcessMonitor_powerpc::NumSupportedHardwareWatchpoints() +{ + return 0; +} + diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h new file mode 100644 index 0000000..92a3312 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_powerpc.h @@ -0,0 +1,95 @@ +//===-- RegisterContextPOSIXProcessMonitor_powerpc.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_RegisterContextPOSIXProcessMonitor_powerpc_H_ +#define liblldb_RegisterContextPOSIXProcessMonitor_powerpc_H_ + +#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" + +class RegisterContextPOSIXProcessMonitor_powerpc: + public RegisterContextPOSIX_powerpc, + public POSIXBreakpointProtocol +{ +public: + RegisterContextPOSIXProcessMonitor_powerpc(lldb_private::Thread &thread, + uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + +protected: + bool + ReadGPR(); + + bool + ReadFPR(); + + bool + WriteGPR(); + + bool + WriteFPR(); + + // lldb_private::RegisterContext + bool + ReadRegister(const unsigned reg, lldb_private::RegisterValue &value); + + bool + WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value); + + bool + ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); + + bool + WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + + bool + ReadAllRegisterValues(lldb::DataBufferSP &data_sp); + + bool + WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); + + uint32_t + SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write); + + bool + ClearHardwareWatchpoint(uint32_t hw_index); + + bool + HardwareSingleStep(bool enable); + + // POSIXBreakpointProtocol + bool + UpdateAfterBreakpoint(); + + unsigned + GetRegisterIndexFromOffset(unsigned offset); + + bool + IsWatchpointHit(uint32_t hw_index); + + bool + ClearWatchpointHits(); + + lldb::addr_t + GetWatchpointAddress(uint32_t hw_index); + + bool + IsWatchpointVacant(uint32_t hw_index); + + bool + SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index); + + uint32_t + NumSupportedHardwareWatchpoints(); + +private: + ProcessMonitor & + GetMonitor(); +}; + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp index e534f3b..1956e45 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -10,9 +10,13 @@ #include "lldb/Target/Thread.h" #include "lldb/Core/RegisterValue.h" -#include "ProcessPOSIX.h" +#include "Plugins/Process/POSIX/ProcessPOSIX.h" #include "RegisterContextPOSIXProcessMonitor_x86.h" -#include "ProcessMonitor.h" +#if defined(__FreeBSD__) +#include "Plugins/Process/FreeBSD/ProcessMonitor.h" +#else +#include "Plugins/Process/Linux/ProcessMonitor.h" +#endif using namespace lldb_private; using namespace lldb; @@ -48,6 +52,7 @@ size_and_rw_bits(size_t size, bool read, bool write) return (0x2 << 2) | rw; default: assert(0 && "invalid size, must be one of 1, 2, 4, or 8"); + return 0; // Unreachable. Just to silence compiler. } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMDefines.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMDefines.h index 2c8ad35..cfb33be 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMDefines.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMDefines.h @@ -45,7 +45,8 @@ typedef enum #define COND_AL 0xE // Always (unconditional) Always (unconditional) Any #define COND_UNCOND 0xF -static inline const char *ARMCondCodeToString(uint32_t CC) +static inline const char * +ARMCondCodeToString(uint32_t CC) { switch (CC) { default: assert(0 && "Unknown condition code"); @@ -67,6 +68,37 @@ static inline const char *ARMCondCodeToString(uint32_t CC) } } +static inline bool +ARMConditionPassed(const uint32_t condition, const uint32_t cpsr) +{ + const uint32_t cpsr_n = (cpsr >> 31) & 1u; // Negative condition code flag + const uint32_t cpsr_z = (cpsr >> 30) & 1u; // Zero condition code flag + const uint32_t cpsr_c = (cpsr >> 29) & 1u; // Carry condition code flag + const uint32_t cpsr_v = (cpsr >> 28) & 1u; // Overflow condition code flag + + switch (condition) { + case COND_EQ: return (cpsr_z == 1); + case COND_NE: return (cpsr_z == 0); + case COND_CS: return (cpsr_c == 1); + case COND_CC: return (cpsr_c == 0); + case COND_MI: return (cpsr_n == 1); + case COND_PL: return (cpsr_n == 0); + case COND_VS: return (cpsr_v == 1); + case COND_VC: return (cpsr_v == 0); + case COND_HI: return ((cpsr_c == 1) && (cpsr_z == 0)); + case COND_LS: return ((cpsr_c == 0) || (cpsr_z == 1)); + case COND_GE: return (cpsr_n == cpsr_v); + case COND_LT: return (cpsr_n != cpsr_v); + case COND_GT: return ((cpsr_z == 0) && (cpsr_n == cpsr_v)); + case COND_LE: return ((cpsr_z == 1) || (cpsr_n != cpsr_v)); + case COND_AL: + case COND_UNCOND: + default: + return true; + } + return false; +} + // Bit positions for CPSR #define CPSR_T_POS 5 #define CPSR_F_POS 6 diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 3507ccf..1088924 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -81,6 +81,7 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict else { Clear(); + printf("error: register sets must have valid names\n"); return 0; } } @@ -121,6 +122,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (reg_info.name == NULL) { Clear(); + printf("error: registers must have valid names\n"); + reg_info_dict.Dump(); return 0; } @@ -290,6 +293,7 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (!success) { Clear(); + reg_info_dict.Dump(); return 0; } } @@ -297,6 +301,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (bitsize == 0) { Clear(); + printf("error: invalid or missing 'bitsize' key/value pair in register dictionary\n"); + reg_info_dict.Dump(); return 0; } @@ -308,6 +314,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (Args::StringToFormat(format_cstr, reg_info.format, NULL).Fail()) { Clear(); + printf("error: invalid 'format' value in register dictionary\n"); + reg_info_dict.Dump(); return 0; } } @@ -326,6 +334,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (static_cast<size_t>(set) >= m_sets.size()) { Clear(); + printf("error: invalid 'set' value in register dictionary, valid values are 0 - %i\n", (int)set); + reg_info_dict.Dump(); return 0; } @@ -409,6 +419,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict else { Clear(); + printf("error: items in the 'registers' array must be dictionaries\n"); + regs.Dump(); return 0; } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp index 590bb01..206b829 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.cpp @@ -39,7 +39,7 @@ HistoryThread::HistoryThread (lldb_private::Process &process, m_originating_unique_thread_id (tid), m_queue_id (LLDB_INVALID_QUEUE_ID) { - m_unwinder_ap.reset (new HistoryUnwind (*this, pcs, stop_id, stop_id_is_valid)); + m_unwinder_ap.reset (new HistoryUnwind (*this, pcs, stop_id_is_valid)); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) log->Printf ("%p HistoryThread::HistoryThread", diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h index f9a431d..51173c6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h @@ -101,6 +101,18 @@ public: { m_thread_name = name; } + + virtual const char * + GetName () + { + return m_thread_name.c_str(); + } + + virtual void + SetName(const char *name) + { + m_thread_name = name; + } protected: virtual lldb::StackFrameListSP diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp index f809ebe..14afcbe 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp @@ -24,11 +24,9 @@ using namespace lldb_private; HistoryUnwind::HistoryUnwind (Thread &thread, std::vector<lldb::addr_t> pcs, - uint32_t stop_id, bool stop_id_is_valid) : Unwind (thread), m_pcs (pcs), - m_stop_id (stop_id), m_stop_id_is_valid (stop_id_is_valid) { } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h index 0661b80..733f93e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h @@ -21,7 +21,7 @@ namespace lldb_private { class HistoryUnwind : public lldb_private::Unwind { public: - HistoryUnwind (Thread &thread, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid); + HistoryUnwind (Thread &thread, std::vector<lldb::addr_t> pcs, bool stop_id_is_valid); virtual ~HistoryUnwind (); @@ -42,7 +42,6 @@ protected: private: std::vector<lldb::addr_t> m_pcs; - uint32_t m_stop_id; bool m_stop_id_is_valid; }; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 4a94457..7db83ae 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -98,13 +98,11 @@ lldb_private::InferiorCallMmap (Process *process, ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset }; - ThreadPlanCallFunction *call_function_thread_plan - = new ThreadPlanCallFunction (*thread, - mmap_range.GetBaseAddress(), - clang_void_ptr_type, - args, - options); - lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); + lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, + mmap_range.GetBaseAddress(), + clang_void_ptr_type, + args, + options)); if (call_plan_sp) { StreamFile error_strm; @@ -241,13 +239,11 @@ lldb_private::InferiorCall (Process *process, ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); ClangASTType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); - ThreadPlanCallFunction *call_function_thread_plan - = new ThreadPlanCallFunction (*thread, - *address, - clang_void_ptr_type, - llvm::ArrayRef<addr_t>(), - options); - lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); + lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, + *address, + clang_void_ptr_type, + llvm::ArrayRef<addr_t>(), + options)); if (call_plan_sp) { StreamString error_strm; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InstructionUtils.h index 8139900..6226fbc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InstructionUtils.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/InstructionUtils.h @@ -20,7 +20,7 @@ static inline uint64_t Bits64 (const uint64_t bits, const uint32_t msbit, const uint32_t lsbit) { assert(msbit < 64 && lsbit <= msbit); - return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1); + return (bits >> lsbit) & ((1ull << (msbit - lsbit + 1)) - 1); } // Return the bit field(s) from the most significant bit (msbit) to the diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index fb49df6..11a3eef 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -53,7 +53,7 @@ LinuxSignals::Reset() AddSignal (24, "SIGXCPU", "XCPU", false, true , true , "CPU resource exceeded"); AddSignal (25, "SIGXFSZ", "XFSZ", false, true , true , "file size limit exceeded"); AddSignal (26, "SIGVTALRM", "VTALRM", false, true , true , "virtual time alarm"); - AddSignal (27, "SIGPROF", "PROF", false, true , true , "profiling time alarm"); + AddSignal (27, "SIGPROF", "PROF", false, false, false, "profiling time alarm"); AddSignal (28, "SIGWINCH", "WINCH", false, true , true , "window size changes"); AddSignal (29, "SIGPOLL", "POLL", false, true , true , "pollable event"); AddSignal (29, "SIGIO", "IO", false, true , true , "input/output ready"); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp new file mode 100644 index 0000000..5170e6d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.cpp @@ -0,0 +1,230 @@ +//===-- RegisterContextFreeBSD_powerpc.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include <vector> +#include "RegisterContextPOSIX_powerpc.h" +#include "RegisterContextFreeBSD_powerpc.h" + +using namespace lldb_private; +using namespace lldb; + +// http://svnweb.freebsd.org/base/head/sys/powerpc/include/reg.h +typedef struct _GPR64 +{ + 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 lr; + uint64_t cr; + uint64_t xer; + uint64_t ctr; + uint64_t pc; +} GPR64; + +typedef struct _GPR32 +{ + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; + uint32_t r12; + uint32_t r13; + uint32_t r14; + uint32_t r15; + uint32_t r16; + uint32_t r17; + uint32_t r18; + uint32_t r19; + uint32_t r20; + uint32_t r21; + uint32_t r22; + uint32_t r23; + uint32_t r24; + uint32_t r25; + uint32_t r26; + uint32_t r27; + uint32_t r28; + uint32_t r29; + uint32_t r30; + uint32_t r31; + uint32_t lr; + uint32_t cr; + uint32_t xer; + uint32_t ctr; + uint32_t pc; +} GPR32; + +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; + +//--------------------------------------------------------------------------- +// Include RegisterInfos_powerpc to declare our g_register_infos_powerpc structure. +//--------------------------------------------------------------------------- +#define DECLARE_REGISTER_INFOS_POWERPC_STRUCT +#include "RegisterInfos_powerpc.h" +#undef DECLARE_REGISTER_INFOS_POWERPC_STRUCT + +RegisterContextFreeBSD_powerpc::RegisterContextFreeBSD_powerpc(const ArchSpec &target_arch) : + RegisterInfoInterface(target_arch) +{ +} + +RegisterContextFreeBSD_powerpc::~RegisterContextFreeBSD_powerpc() +{ +} + +size_t +RegisterContextFreeBSD_powerpc::GetGPRSize() const +{ + // This is an 'abstract' base, so no GPR struct. + return 0; +} + +const RegisterInfo * +RegisterContextFreeBSD_powerpc::GetRegisterInfo() const +{ + //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc); + llvm_unreachable("Abstract class!"); + return NULL; +} + +uint32_t +RegisterContextFreeBSD_powerpc::GetRegisterCount () const +{ + return 0; +} + +RegisterContextFreeBSD_powerpc32::RegisterContextFreeBSD_powerpc32(const ArchSpec &target_arch) : + RegisterContextFreeBSD_powerpc(target_arch) +{ +} + +RegisterContextFreeBSD_powerpc32::~RegisterContextFreeBSD_powerpc32() +{ +} + +size_t +RegisterContextFreeBSD_powerpc32::GetGPRSize() const +{ + return sizeof(GPR32); +} + +const RegisterInfo * +RegisterContextFreeBSD_powerpc32::GetRegisterInfo() const +{ + //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc); + return g_register_infos_powerpc32; +} + +uint32_t +RegisterContextFreeBSD_powerpc32::GetRegisterCount () const +{ + return static_cast<uint32_t> (sizeof (g_register_infos_powerpc32) / sizeof (g_register_infos_powerpc32 [0])); +} + +RegisterContextFreeBSD_powerpc64::RegisterContextFreeBSD_powerpc64(const ArchSpec &target_arch) : + RegisterContextFreeBSD_powerpc(target_arch) +{ +} + +RegisterContextFreeBSD_powerpc64::~RegisterContextFreeBSD_powerpc64() +{ +} + +size_t +RegisterContextFreeBSD_powerpc64::GetGPRSize() const +{ + return sizeof(GPR64); +} + +const RegisterInfo * +RegisterContextFreeBSD_powerpc64::GetRegisterInfo() const +{ + //assert (m_target_arch.GetCore() == ArchSpec::eCore_powerpc); + if (m_target_arch.GetMachine() == llvm::Triple::ppc) + return g_register_infos_powerpc64_32; + return g_register_infos_powerpc64; +} + +uint32_t +RegisterContextFreeBSD_powerpc64::GetRegisterCount () const +{ + return static_cast<uint32_t> (sizeof (g_register_infos_powerpc64) / sizeof (g_register_infos_powerpc64 [0])); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h new file mode 100644 index 0000000..b907fe9 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h @@ -0,0 +1,66 @@ +//===-- RegisterContextFreeBSD_powerpc.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_RegisterContextFreeBSD_powerpc_H_ +#define liblldb_RegisterContextFreeBSD_powerpc_H_ + +#include "RegisterContextPOSIX.h" + +class RegisterContextFreeBSD_powerpc: + public lldb_private::RegisterInfoInterface +{ +public: + RegisterContextFreeBSD_powerpc(const lldb_private::ArchSpec &target_arch); + virtual ~RegisterContextFreeBSD_powerpc(); + + size_t + GetGPRSize() const override; + + const lldb_private::RegisterInfo * + GetRegisterInfo() const override; + + uint32_t + GetRegisterCount() const override; +}; + +class RegisterContextFreeBSD_powerpc32: + public RegisterContextFreeBSD_powerpc +{ +public: + RegisterContextFreeBSD_powerpc32(const lldb_private::ArchSpec &target_arch); + virtual ~RegisterContextFreeBSD_powerpc32(); + + size_t + GetGPRSize() const override; + + const lldb_private::RegisterInfo * + GetRegisterInfo() const override; + + uint32_t + GetRegisterCount() const override; +}; + +class RegisterContextFreeBSD_powerpc64: + public RegisterContextFreeBSD_powerpc +{ +public: + RegisterContextFreeBSD_powerpc64(const lldb_private::ArchSpec &target_arch); + virtual ~RegisterContextFreeBSD_powerpc64(); + + size_t + GetGPRSize() const override; + + const lldb_private::RegisterInfo * + GetRegisterInfo() const override; + + uint32_t + GetRegisterCount() const override; +}; + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index b58e6bb..f47d687 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -172,6 +172,21 @@ RegisterContextLLDB::InitializeZerothFrame() m_sym_ctx_valid = true; } + if (m_sym_ctx.symbol) + { + UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'", + current_pc, m_sym_ctx.symbol == NULL ? "" : m_sym_ctx.symbol->GetName().AsCString()); + } + else if (m_sym_ctx.function) + { + UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'", + current_pc, m_sym_ctx.symbol == NULL ? "" : m_sym_ctx.function->GetName().AsCString()); + } + else + { + UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", current_pc); + } + AddressRange addr_range; m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range); @@ -217,7 +232,6 @@ RegisterContextLLDB::InitializeZerothFrame() m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); UnwindPlan::RowSP active_row; - int cfa_offset = 0; lldb::RegisterKind row_register_kind = eRegisterKindGeneric; if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { @@ -239,18 +253,13 @@ RegisterContextLLDB::InitializeZerothFrame() } - addr_t cfa_regval = LLDB_INVALID_ADDRESS; - if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval)) + if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa)) { UnwindLogMsg ("could not read CFA register for this frame."); m_frame_type = eNotAValidFrame; return; } - cfa_offset = active_row->GetCFAOffset (); - m_cfa = cfa_regval + cfa_offset; - - UnwindLogMsg ("cfa_regval = 0x%16.16" PRIx64 " (cfa_regval = 0x%16.16" PRIx64 ", cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset); UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 " using %s UnwindPlan", (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa, @@ -294,20 +303,27 @@ RegisterContextLLDB::InitializeNonZerothFrame() if (log) { - UnwindLogMsg ("pc = 0x%16.16" PRIx64, pc); + UnwindLogMsg ("pc = 0x%" PRIx64, pc); addr_t reg_val; if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) - UnwindLogMsg ("fp = 0x%16.16" PRIx64, reg_val); + UnwindLogMsg ("fp = 0x%" PRIx64, reg_val); if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) - UnwindLogMsg ("sp = 0x%16.16" PRIx64, reg_val); + UnwindLogMsg ("sp = 0x%" PRIx64, reg_val); } - // A pc of 0x0 means it's the end of the stack crawl - if (pc == 0) + // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap handler function + bool above_trap_handler = false; + if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame()) + above_trap_handler = true; + + if (pc == 0 || pc == 0x1) { - m_frame_type = eNotAValidFrame; - UnwindLogMsg ("this frame has a pc of 0x0"); - return; + if (above_trap_handler == false) + { + m_frame_type = eNotAValidFrame; + UnwindLogMsg ("this frame has a pc of 0x0"); + return; + } } ExecutionContext exe_ctx(m_thread.shared_from_this()); @@ -363,35 +379,31 @@ RegisterContextLLDB::InitializeNonZerothFrame() m_all_registers_available = false; m_current_offset = -1; m_current_offset_backed_up_one = -1; - addr_t cfa_regval = LLDB_INVALID_ADDRESS; RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); if (row.get()) { - uint32_t cfa_regnum = row->GetCFARegister(); - int cfa_offset = row->GetCFAOffset(); - if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval)) + if (!ReadCFAValueForRow (row_register_kind, row, m_cfa)) { UnwindLogMsg ("failed to get cfa value"); if (m_frame_type != eSkipFrame) // don't override eSkipFrame { - m_frame_type = eNormalFrame; + m_frame_type = eNotAValidFrame; } return; } - m_cfa = cfa_regval + cfa_offset; // A couple of sanity checks.. - if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1) + if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) { UnwindLogMsg ("could not find a valid cfa address"); m_frame_type = eNotAValidFrame; return; } - // cfa_regval should point into the stack memory; if we can query memory region permissions, + // m_cfa should point into the stack memory; if we can query memory region permissions, // see if the memory is allocated & readable. - if (process->GetLoadAddressPermissions(cfa_regval, permissions) + if (process->GetLoadAddressPermissions(m_cfa, permissions) && (permissions & ePermissionsReadable) == 0) { m_frame_type = eNotAValidFrame; @@ -406,6 +418,17 @@ RegisterContextLLDB::InitializeNonZerothFrame() return; } + if (CheckIfLoopingStack ()) + { + TryFallbackUnwindPlan(); + if (CheckIfLoopingStack ()) + { + UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping"); + m_frame_type = eNotAValidFrame; + return; + } + } + UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64, (uint64_t) m_cfa); return; } @@ -431,6 +454,21 @@ RegisterContextLLDB::InitializeNonZerothFrame() m_sym_ctx_valid = true; } + if (m_sym_ctx.symbol) + { + UnwindLogMsg ("with pc value of 0x%" PRIx64 ", symbol name is '%s'", + pc, m_sym_ctx.symbol == NULL ? "" : m_sym_ctx.symbol->GetName().AsCString()); + } + else if (m_sym_ctx.function) + { + UnwindLogMsg ("with pc value of 0x%" PRIx64 ", function name is '%s'", + pc, m_sym_ctx.symbol == NULL ? "" : m_sym_ctx.function->GetName().AsCString()); + } + else + { + UnwindLogMsg ("with pc value of 0x%" PRIx64 ", no symbol/function name is known.", pc); + } + AddressRange addr_range; if (!m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range)) { @@ -461,17 +499,22 @@ RegisterContextLLDB::InitializeNonZerothFrame() // to the ABI plugin and consult that. if (decr_pc_and_recompute_addr_range) { - Address temporary_pc(m_current_pc); - temporary_pc.SetOffset(m_current_pc.GetOffset() - 1); - m_sym_ctx.Clear(false); + UnwindLogMsg ("Backing up the pc value of 0x%" PRIx64 " by 1 and re-doing symbol lookup; old symbol was %s", + pc, m_sym_ctx.symbol == NULL ? "" : m_sym_ctx.symbol->GetName().AsCString()); + Address temporary_pc; + temporary_pc.SetLoadAddress (pc - 1, &process->GetTarget()); + m_sym_ctx.Clear (false); m_sym_ctx_valid = false; uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; - if (pc_module_sp->ResolveSymbolContextForAddress (temporary_pc, resolve_scope, m_sym_ctx) & resolve_scope) + ModuleSP temporary_module_sp = temporary_pc.GetModule(); + if (temporary_module_sp && + temporary_module_sp->ResolveSymbolContextForAddress (temporary_pc, resolve_scope, m_sym_ctx) & resolve_scope) { if (m_sym_ctx.GetAddressRange (resolve_scope, 0, false, addr_range)) m_sym_ctx_valid = true; } + UnwindLogMsg ("Symbol is now %s", m_sym_ctx.symbol == NULL ? "" : m_sym_ctx.symbol->GetName().AsCString()); } // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function. @@ -479,13 +522,15 @@ RegisterContextLLDB::InitializeNonZerothFrame() if (addr_range.GetBaseAddress().IsValid()) { m_start_pc = addr_range.GetBaseAddress(); - m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); + m_current_offset = pc - m_start_pc.GetLoadAddress (&process->GetTarget()); m_current_offset_backed_up_one = m_current_offset; if (decr_pc_and_recompute_addr_range && m_current_offset_backed_up_one > 0) { m_current_offset_backed_up_one--; if (m_sym_ctx_valid) - m_current_pc.SetOffset(m_current_pc.GetOffset() - 1); + { + m_current_pc.SetLoadAddress (pc - 1, &process->GetTarget()); + } } } else @@ -512,7 +557,6 @@ RegisterContextLLDB::InitializeNonZerothFrame() m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); UnwindPlan::RowSP active_row; - int cfa_offset = 0; RegisterKind row_register_kind = eRegisterKindGeneric; // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get @@ -553,27 +597,33 @@ RegisterContextLLDB::InitializeNonZerothFrame() return; } - addr_t cfa_regval = LLDB_INVALID_ADDRESS; - if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval)) + if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa)) { UnwindLogMsg ("failed to get cfa reg %d/%d", row_register_kind, active_row->GetCFARegister()); m_frame_type = eNotAValidFrame; return; } - cfa_offset = active_row->GetCFAOffset (); - m_cfa = cfa_regval + cfa_offset; + UnwindLogMsg ("m_cfa = 0x%" PRIx64, m_cfa); - UnwindLogMsg ("cfa_regval = 0x%16.16" PRIx64 " (cfa_regval = 0x%16.16" PRIx64 ", cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset); - - // A couple of sanity checks.. - if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1) + if (CheckIfLoopingStack ()) { - UnwindLogMsg ("could not find a valid cfa address"); - m_frame_type = eNotAValidFrame; - return; + TryFallbackUnwindPlan(); + if (CheckIfLoopingStack ()) + { + UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping"); + m_frame_type = eNotAValidFrame; + return; + } } + UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64, + (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa); +} + +bool +RegisterContextLLDB::CheckIfLoopingStack () +{ // If we have a bad stack setup, we can get the same CFA value multiple times -- or even // more devious, we can actually oscillate between two CFA values. Detect that here and // break out to avoid a possible infinite loop in lldb trying to unwind the stack. @@ -581,29 +631,19 @@ RegisterContextLLDB::InitializeNonZerothFrame() addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS; if (GetNextFrame().get() && GetNextFrame()->GetCFA(next_frame_cfa)) { - bool repeating_frames = false; if (next_frame_cfa == m_cfa) { - repeating_frames = true; - } - else - { - if (GetNextFrame()->GetNextFrame() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa) - && next_next_frame_cfa == m_cfa) - { - repeating_frames = true; - } + // We have a loop in the stack unwind + return true; } - if (repeating_frames && abi && abi->FunctionCallsChangeCFA()) + if (GetNextFrame()->GetNextFrame().get() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa) + && next_next_frame_cfa == m_cfa) { - UnwindLogMsg ("same CFA address as next frame, assuming the unwind is looping - stopping"); - m_frame_type = eNotAValidFrame; - return; + // We have a loop in the stack unwind + return true; } } - - UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64, - (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa); + return false; } @@ -715,13 +755,17 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () uint32_t permissions; addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()); if (current_pc_addr == 0 - || (process->GetLoadAddressPermissions (current_pc_addr, permissions) + || (process && + process->GetLoadAddressPermissions (current_pc_addr, permissions) && (permissions & ePermissionsExecutable) == 0)) { - unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); - abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); - m_frame_type = eNormalFrame; - return unwind_plan_sp; + if (abi) + { + unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); + abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); + m_frame_type = eNormalFrame; + return unwind_plan_sp; + } } } @@ -764,10 +808,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () // is properly encoded in the eh_frame section, so prefer that if available. // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of // how to unwind out of sigtramp. - if (m_frame_type == eTrapHandlerFrame) + if (m_frame_type == eTrapHandlerFrame && process) { m_fast_unwind_plan_sp.reset(); - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one); if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc) && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) { return unwind_plan_sp; @@ -782,7 +826,7 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () // But there is not. if (process && process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx)) { - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one); if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) { UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it", @@ -792,7 +836,7 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () } // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions - if (behaves_like_zeroth_frame) + if (behaves_like_zeroth_frame && process) { unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one); if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) @@ -812,7 +856,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () } // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); + if (process) + { + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (process->GetTarget(), m_current_offset_backed_up_one); + } int valid_offset = -1; if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) { @@ -822,7 +869,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible. - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one); + if (process) + { + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one); + } if (unwind_plan_sp && unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) { // We probably have an UnwindPlan created by inspecting assembly instructions, and we probably @@ -908,6 +958,16 @@ RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::Unwind switch (regloc.type) { + case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: + { + const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); + + if (!other_reg_info) + return false; + + success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value); + } + break; case UnwindLLDB::RegisterLocation::eRegisterInRegister: { const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); @@ -962,6 +1022,12 @@ RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindL switch (regloc.type) { + case UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext: + { + const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); + success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value); + } + break; case UnwindLLDB::RegisterLocation::eRegisterInRegister: { const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); @@ -1004,6 +1070,11 @@ RegisterContextLLDB::IsValid () const return m_frame_type != eNotAValidFrame; } +// After the final stack frame in a stack walk we'll get one invalid (eNotAValidFrame) stack frame -- +// one past the end of the stack walk. But higher-level code will need to tell the differnece between +// "the unwind plan below this frame failed" versus "we successfully completed the stack walk" so +// this method helps to disambiguate that. + bool RegisterContextLLDB::IsTrapHandlerFrame () const { @@ -1056,57 +1127,42 @@ RegisterContextLLDB::IsTrapHandlerSymbol (lldb_private::Process *process, const enum UnwindLLDB::RegisterSearchResult RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc) { + RegisterNumber regnum (m_thread, eRegisterKindLLDB, lldb_regnum); + // Have we already found this register location? if (!m_registers.empty()) { std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator; - iterator = m_registers.find (lldb_regnum); + iterator = m_registers.find (regnum.GetAsKind (eRegisterKindLLDB)); if (iterator != m_registers.end()) { regloc = iterator->second; - UnwindLogMsg ("supplying caller's saved reg %d's location, cached", lldb_regnum); + UnwindLogMsg ("supplying caller's saved %s (%d)'s location, cached", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } } - uint32_t sp_regnum = LLDB_INVALID_REGNUM; - uint32_t pc_regnum = LLDB_INVALID_REGNUM; - m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, eRegisterKindLLDB, sp_regnum); - m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, eRegisterKindLLDB, pc_regnum); - - // Are we looking for the CALLER's stack pointer? The stack pointer is defined to be the same as THIS frame's - // CFA so just return the CFA value. This is true on x86-32/x86-64 at least. - if (sp_regnum != LLDB_INVALID_REGNUM && sp_regnum == lldb_regnum) - { - // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value) - assert (sizeof (addr_t) <= sizeof (uint64_t)); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = m_cfa; - m_registers[lldb_regnum] = regloc; - UnwindLogMsg ("supplying caller's stack pointer (%d) value, computed from CFA", lldb_regnum); - return UnwindLLDB::RegisterSearchResult::eRegisterFound; - } - // Look through the available UnwindPlans for the register location. UnwindPlan::Row::RegisterLocation unwindplan_regloc; bool have_unwindplan_regloc = false; - RegisterKind unwindplan_registerkind = (RegisterKind)-1; + RegisterKind unwindplan_registerkind = kNumRegisterKinds; if (m_fast_unwind_plan_sp) { UnwindPlan::RowSP active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind (); - uint32_t row_regnum; - if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum)) + if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM) { - UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme", - lldb_regnum, (int) unwindplan_registerkind); + UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind); return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } - if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc)) + if (active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc)) { - UnwindLogMsg ("supplying caller's saved reg %d's location using FastUnwindPlan", lldb_regnum); + UnwindLogMsg ("supplying caller's saved %s (%d)'s location using FastUnwindPlan", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); have_unwindplan_regloc = true; } } @@ -1119,37 +1175,49 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat if (m_full_unwind_plan_sp) { + RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); - uint32_t row_regnum; - bool row_register_rewritten_to_return_address_reg = false; + + RegisterNumber return_address_reg; // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm), // look for the return address register number in the UnwindPlan's row. - if (lldb_regnum == pc_regnum && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM) + if (pc_regnum.IsValid() + && pc_regnum == regnum + && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM) { - row_regnum = m_full_unwind_plan_sp->GetReturnAddressRegister(); - row_register_rewritten_to_return_address_reg = true; - UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead", - row_regnum); + + return_address_reg.init (m_thread, m_full_unwind_plan_sp->GetRegisterKind(), m_full_unwind_plan_sp->GetReturnAddressRegister()); + regnum = return_address_reg; + UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting %s (%d) instead", + return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB)); } else { - if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum)) + if (regnum.GetAsKind (unwindplan_registerkind) == LLDB_INVALID_REGNUM) { if (unwindplan_registerkind == eRegisterKindGeneric) - UnwindLogMsg ("could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme", lldb_regnum); + { + UnwindLogMsg ("could not convert lldb regnum %s (%d) into eRegisterKindGeneric reg numbering scheme", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); + } else - UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme", - lldb_regnum, (int) unwindplan_registerkind); + { + UnwindLogMsg ("could not convert lldb regnum %s (%d) into %d RegisterKind reg numbering scheme", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), (int) unwindplan_registerkind); + } return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } } - if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc)) + if (regnum.IsValid() + && active_row->GetRegisterInfo (regnum.GetAsKind (unwindplan_registerkind), unwindplan_regloc)) { have_unwindplan_regloc = true; - UnwindLogMsg ("supplying caller's saved reg %d's location using %s UnwindPlan", lldb_regnum, + UnwindLogMsg ("supplying caller's saved %s (%d)'s location using %s UnwindPlan", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), m_full_unwind_plan_sp->GetSourceName().GetCString()); } @@ -1158,19 +1226,19 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat // Handle this specially. if (have_unwindplan_regloc == false - && row_register_rewritten_to_return_address_reg == true - && IsFrameZero() - && row_regnum != LLDB_INVALID_REGNUM) + && return_address_reg.IsValid() + && IsFrameZero()) { - uint32_t ra_regnum_in_lldb_reg_numbering; - if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, row_regnum, eRegisterKindLLDB, ra_regnum_in_lldb_reg_numbering)) + if (return_address_reg.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM) { lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - new_regloc.location.register_number = ra_regnum_in_lldb_reg_numbering; - m_registers[lldb_regnum] = new_regloc; + new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; + new_regloc.location.register_number = return_address_reg.GetAsKind (eRegisterKindLLDB); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc; regloc = new_regloc; - UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0, saved in %d", lldb_regnum, ra_regnum_in_lldb_reg_numbering); + UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0, saved in %d", + return_address_reg.GetName(), return_address_reg.GetAsKind (eRegisterKindLLDB), + return_address_reg.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } } @@ -1187,13 +1255,12 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat // when we're at a call site location. // arch_default_ra_regnum is the return address register # in the Full UnwindPlan register numbering - uint32_t arch_default_ra_regnum = LLDB_INVALID_REGNUM; - if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA, unwindplan_registerkind, arch_default_ra_regnum) - && arch_default_ra_regnum != LLDB_INVALID_REGNUM - && pc_regnum != LLDB_INVALID_REGNUM - && pc_regnum == lldb_regnum + RegisterNumber arch_default_ra_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); + + if (arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM + && pc_regnum == regnum && unwindplan_regloc.IsInOtherRegister() - && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum + && unwindplan_regloc.GetRegisterNumber() == arch_default_ra_regnum.GetAsKind (unwindplan_registerkind) && m_full_unwind_plan_sp->GetSourcedFromCompiler() != eLazyBoolYes && !m_all_registers_available) { @@ -1201,15 +1268,32 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat m_full_unwind_plan_sp->GetSourceName().GetCString()); // Throw away the full unwindplan; install the arch default unwindplan - if (TryFallbackUnwindPlan()) + if (ForceSwitchToFallbackUnwindPlan()) { - // Now re-fetch the pc value we're searching for - uint32_t arch_default_pc_reg = LLDB_INVALID_REGNUM; + // Update for the possibly new unwind plan + unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); - if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, m_full_unwind_plan_sp->GetRegisterKind(), arch_default_pc_reg) - && arch_default_pc_reg != LLDB_INVALID_REGNUM - && active_row - && active_row->GetRegisterInfo (arch_default_pc_reg, unwindplan_regloc)) + + // Sanity check: Verify that we can fetch a pc value and CFA value with this unwind plan + + RegisterNumber arch_default_pc_reg (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + bool can_fetch_pc_value = false; + bool can_fetch_cfa = false; + addr_t cfa_value; + if (active_row) + { + if (arch_default_pc_reg.GetAsKind (unwindplan_registerkind) != LLDB_INVALID_REGNUM + && active_row->GetRegisterInfo (arch_default_pc_reg.GetAsKind (unwindplan_registerkind), unwindplan_regloc)) + { + can_fetch_pc_value = true; + } + if (ReadCFAValueForRow (unwindplan_registerkind, active_row, cfa_value)) + { + can_fetch_cfa = true; + } + } + + if (can_fetch_pc_value && can_fetch_cfa) { have_unwindplan_regloc = true; } @@ -1218,10 +1302,35 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat have_unwindplan_regloc = false; } } + else + { + // We were unable to fall back to another unwind plan + have_unwindplan_regloc = false; + } } } } + if (have_unwindplan_regloc == false) + { + // Did the UnwindPlan fail to give us the caller's stack pointer? + // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as + // the caller's stack pointer. This is true on x86-32/x86-64 at least. + + RegisterNumber sp_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); + if (sp_regnum.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM + && sp_regnum.GetAsKind (eRegisterKindLLDB) == regnum.GetAsKind (eRegisterKindLLDB)) + { + // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value) + assert (sizeof (addr_t) <= sizeof (uint64_t)); + regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; + regloc.location.inferred_value = m_cfa; + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; + UnwindLogMsg ("supplying caller's stack pointer %s (%d) value, computed from CFA", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + } ExecutionContext exe_ctx(m_thread.shared_from_this()); Process *process = exe_ctx.GetProcessPtr(); @@ -1232,11 +1341,11 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat ABI *abi = process ? process->GetABI().get() : NULL; if (abi) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB)); if (reg_info && abi->RegisterIsVolatile (reg_info)) { - UnwindLogMsg ("did not supply reg location for %d (%s) because it is volatile", - lldb_regnum, reg_info->name ? reg_info->name : "??"); + UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile; } } @@ -1245,15 +1354,27 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat { // This is frame 0 - we should return the actual live register context value lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - new_regloc.location.register_number = lldb_regnum; - m_registers[lldb_regnum] = new_regloc; + new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext; + new_regloc.location.register_number = regnum.GetAsKind (eRegisterKindLLDB); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc; regloc = new_regloc; - UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0", lldb_regnum); + UnwindLogMsg ("supplying caller's register %s (%d) from the live RegisterContext at frame 0", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } else - UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum); + { + std::string unwindplan_name (""); + if (m_full_unwind_plan_sp) + { + unwindplan_name += "via '"; + unwindplan_name += m_full_unwind_plan_sp->GetSourceName().AsCString(); + unwindplan_name += "'"; + } + UnwindLogMsg ("no save location for %s (%d) %s", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), + unwindplan_name.c_str()); + } return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } @@ -1262,8 +1383,9 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat { lldb_private::UnwindLLDB::RegisterLocation new_regloc; new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved; - m_registers[lldb_regnum] = new_regloc; - UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = new_regloc; + UnwindLogMsg ("save location for %s (%d) is unspecified, continue searching", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } @@ -1271,7 +1393,8 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat { if (IsFrameZero ()) { - UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum); + UnwindLogMsg ("could not supply caller's %s (%d) location, IsSame", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } else @@ -1285,8 +1408,10 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat int offset = unwindplan_regloc.GetOffset(); regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; regloc.location.inferred_value = m_cfa + offset; - m_registers[lldb_regnum] = regloc; - UnwindLogMsg ("supplying caller's register %d, value is CFA plus offset %d", lldb_regnum, offset); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; + UnwindLogMsg ("supplying caller's register %s (%d), value is CFA plus offset %d [value is 0x%" PRIx64 "]", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), + offset, regloc.location.inferred_value); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } @@ -1295,24 +1420,29 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat int offset = unwindplan_regloc.GetOffset(); regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; regloc.location.target_memory_location = m_cfa + offset; - m_registers[lldb_regnum] = regloc; - UnwindLogMsg ("supplying caller's register %d from the stack, saved at CFA plus offset %d", lldb_regnum, offset); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; + UnwindLogMsg ("supplying caller's register %s (%d) from the stack, saved at CFA plus offset %d [saved at 0x%" PRIx64 "]", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), + offset, regloc.location.target_memory_location); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } if (unwindplan_regloc.IsInOtherRegister()) { uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber(); - uint32_t row_regnum_in_lldb; - if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb)) + RegisterNumber row_regnum (m_thread, unwindplan_registerkind, unwindplan_regnum); + if (row_regnum.GetAsKind (eRegisterKindLLDB) == LLDB_INVALID_REGNUM) { - UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum); + UnwindLogMsg ("could not supply caller's %s (%d) location - was saved in another reg but couldn't convert that regnum", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - regloc.location.register_number = row_regnum_in_lldb; - m_registers[lldb_regnum] = regloc; - UnwindLogMsg ("supplying caller's register %d, saved in register %d", lldb_regnum, row_regnum_in_lldb); + regloc.location.register_number = row_regnum.GetAsKind (eRegisterKindLLDB); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; + UnwindLogMsg ("supplying caller's register %s (%d), saved in register %s (%d)", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB), + row_regnum.GetName(), row_regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } @@ -1334,75 +1464,277 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat { regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; regloc.location.inferred_value = val; - m_registers[lldb_regnum] = regloc; - UnwindLogMsg ("supplying caller's register %d via DWARF expression (IsDWARFExpression)", lldb_regnum); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; + UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsDWARFExpression)", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } else { regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; regloc.location.target_memory_location = val; - m_registers[lldb_regnum] = regloc; - UnwindLogMsg ("supplying caller's register %d via DWARF expression (IsAtDWARFExpression)", lldb_regnum); + m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc; + UnwindLogMsg ("supplying caller's register %s (%d) via DWARF expression (IsAtDWARFExpression)", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterFound; } } - UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed", lldb_regnum); + UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for %s (%d) but failed", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } - UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum); + UnwindLogMsg ("no save location for %s (%d) in this stack frame", + regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB)); // FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported. return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; } -// If the Full unwindplan has been determined to be incorrect, this method will -// replace it with the architecture's default unwindplan, if one is defined. -// It will also find the FuncUnwinders object for this function and replace the -// Full unwind method for the function there so we don't use the errant Full unwindplan -// again in the future of this debug session. -// We're most likely doing this because the Full unwindplan was generated by assembly -// instruction profiling and the profiler got something wrong. +// TryFallbackUnwindPlan() -- this method is a little tricky. +// +// When this is called, the frame above -- the caller frame, the "previous" frame -- +// is invalid or bad. +// +// Instead of stopping the stack walk here, we'll try a different UnwindPlan and see +// if we can get a valid frame above us. +// +// This most often happens when an unwind plan based on assembly instruction inspection +// is not correct -- mostly with hand-written assembly functions or functions where the +// stack frame is set up "out of band", e.g. the kernel saved the register context and +// then called an asynchronous trap handler like _sigtramp. +// +// Often in these cases, if we just do a dumb stack walk we'll get past this tricky +// frame and our usual techniques can continue to be used. bool RegisterContextLLDB::TryFallbackUnwindPlan () { - UnwindPlan::Row::RegisterLocation unwindplan_regloc; - if (m_fallback_unwind_plan_sp.get() == NULL) + if (m_fallback_unwind_plan_sp.get() == nullptr) + return false; + + if (m_full_unwind_plan_sp.get() == nullptr) return false; + if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() + || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName()) + { + return false; + } + + // If a compiler generated unwind plan failed, trying the arch default unwindplan + // isn't going to do any better. + if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) + return false; + + + // Get the caller's pc value and our own CFA value. + // Swap in the fallback unwind plan, re-fetch the caller's pc value and CFA value. + // If they're the same, then the fallback unwind plan provides no benefit. + + RegisterNumber pc_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); + + addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS; + addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS; + addr_t old_this_frame_cfa_value = m_cfa; + UnwindLLDB::RegisterLocation regloc; + if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound) + { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB)); + if (reg_info) + { + RegisterValue reg_value; + if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) + { + old_caller_pc_value = reg_value.GetAsUInt64(); + } + } + } + + // This is a tricky wrinkle! If SavedLocationForRegister() detects a really impossible + // register location for the full unwind plan, it may call ForceSwitchToFallbackUnwindPlan() + // which in turn replaces the full unwindplan with the fallback... in short, we're done, + // we're using the fallback UnwindPlan. + // We checked if m_fallback_unwind_plan_sp was nullptr at the top -- the only way it + // became nullptr since then is via SavedLocationForRegister(). + if (m_fallback_unwind_plan_sp.get() == nullptr) + return true; + + + // Switch the full UnwindPlan to be the fallback UnwindPlan. If we decide this isn't + // working, we need to restore. + // We'll also need to save & restore the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'. UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp; + addr_t old_cfa = m_cfa; + + m_registers.clear(); + + m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; + UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM) { - FuncUnwindersSP func_unwinders_sp; - if (m_sym_ctx_valid && m_current_pc.IsValid() && m_current_pc.GetModule()) + addr_t new_cfa; + if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa) + || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) + { + UnwindLogMsg ("failed to get cfa with fallback unwindplan"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + m_cfa = old_cfa; + return false; + } + m_cfa = new_cfa; + + if (SavedLocationForRegister (pc_regnum.GetAsKind (eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound) { - func_unwinders_sp = m_current_pc.GetModule()->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); - if (func_unwinders_sp) + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(pc_regnum.GetAsKind (eRegisterKindLLDB)); + if (reg_info) { - func_unwinders_sp->InvalidateNonCallSiteUnwindPlan (m_thread); + RegisterValue reg_value; + if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) + { + new_caller_pc_value = reg_value.GetAsUInt64(); + } } } - m_registers.clear(); - m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; - addr_t cfa_regval = LLDB_INVALID_ADDRESS; - if (ReadGPRValue (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row->GetCFARegister(), cfa_regval)) + + + if (new_caller_pc_value == LLDB_INVALID_ADDRESS) { - m_cfa = cfa_regval + active_row->GetCFAOffset (); + UnwindLogMsg ("failed to get a pc value for the caller frame with the fallback unwind plan"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + m_cfa = old_cfa; + return false; + } + + if (old_caller_pc_value != LLDB_INVALID_ADDRESS) + { + if (old_caller_pc_value == new_caller_pc_value && new_cfa == old_this_frame_cfa_value) + { + UnwindLogMsg ("fallback unwind plan got the same values for this frame CFA and caller frame pc, not using"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + m_cfa = old_cfa; + return false; + } } - UnwindLogMsg ("full unwind plan '%s' has been replaced by architecture default unwind plan '%s' for this function from now on.", - original_full_unwind_plan_sp->GetSourceName().GetCString(), m_fallback_unwind_plan_sp->GetSourceName().GetCString()); + UnwindLogMsg ("trying to unwind from this function with the UnwindPlan '%s' because UnwindPlan '%s' failed.", + m_fallback_unwind_plan_sp->GetSourceName().GetCString(), + original_full_unwind_plan_sp->GetSourceName().GetCString()); + + // We've copied the fallback unwind plan into the full - now clear the fallback. m_fallback_unwind_plan_sp.reset(); } return true; } +bool +RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan () +{ + if (m_fallback_unwind_plan_sp.get() == NULL) + return false; + + if (m_full_unwind_plan_sp.get() == NULL) + return false; + + if (m_full_unwind_plan_sp.get() == m_fallback_unwind_plan_sp.get() + || m_full_unwind_plan_sp->GetSourceName() == m_fallback_unwind_plan_sp->GetSourceName()) + { + return false; + } + + UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); + + if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM) + { + addr_t new_cfa; + if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa) + || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) + { + UnwindLogMsg ("failed to get cfa with fallback unwindplan"); + m_fallback_unwind_plan_sp.reset(); + return false; + } + + m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; + m_fallback_unwind_plan_sp.reset(); + + m_registers.clear(); + + m_cfa = new_cfa; + + UnwindLogMsg ("switched unconditionally to the fallback unwindplan %s", m_full_unwind_plan_sp->GetSourceName().GetCString()); + return true; + } + return false; +} + +bool +RegisterContextLLDB::ReadCFAValueForRow (lldb::RegisterKind row_register_kind, + const UnwindPlan::RowSP &row, + addr_t &cfa_value) +{ + RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFARegister()); + RegisterValue reg_value; + + cfa_value = LLDB_INVALID_ADDRESS; + addr_t cfa_reg_contents; + + if (ReadGPRValue (cfa_reg, cfa_reg_contents)) + { + if (row->GetCFAType() == UnwindPlan::Row::CFAIsRegisterDereferenced) + { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB)); + RegisterValue reg_value; + if (reg_info) + { + Error error = ReadRegisterValueFromMemory(reg_info, + cfa_reg_contents, + reg_info->byte_size, + reg_value); + if (error.Success ()) + { + cfa_value = reg_value.GetAsUInt64(); + UnwindLogMsg ("CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64, + cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), + cfa_reg_contents, cfa_value); + return true; + } + else + { + UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64 "] but memory read failed.", + cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), + cfa_reg_contents); + } + } + } + else + { + if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1) + { + UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64, + cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), + cfa_reg_contents); + cfa_reg_contents = LLDB_INVALID_ADDRESS; + return false; + } + cfa_value = cfa_reg_contents + row->GetCFAOffset (); + UnwindLogMsg ("CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d", + cfa_value, + cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), + cfa_reg_contents, row->GetCFAOffset ()); + return true; + } + } + return false; +} + // Retrieve a general purpose register value for THIS frame, as saved by the NEXT frame, i.e. the frame that // this frame called. e.g. // @@ -1471,6 +1803,12 @@ RegisterContextLLDB::ReadGPRValue (lldb::RegisterKind register_kind, uint32_t re return false; } +bool +RegisterContextLLDB::ReadGPRValue (const RegisterNumber ®num, addr_t &value) +{ + return ReadGPRValue (regnum.GetRegisterKind(), regnum.GetRegisterNumber(), value); +} + // Find the value of a register in THIS frame bool @@ -1593,6 +1931,10 @@ RegisterContextLLDB::ReadPC (addr_t& pc) if (!IsValid()) return false; + bool above_trap_handler = false; + if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsTrapHandlerFrame()) + above_trap_handler = true; + if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) { // A pc value of 0 or 1 is impossible in the middle of the stack -- it indicates the end of a stack walk. @@ -1601,6 +1943,7 @@ RegisterContextLLDB::ReadPC (addr_t& pc) // find the bug. if (m_all_registers_available == false + && above_trap_handler == false && (pc == 0 || pc == 1)) { return false; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index d6ecfeb..5f94a97 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -16,6 +16,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Utility/RegisterNumber.h" #include "UnwindLLDB.h" namespace lldb_private { @@ -98,6 +99,12 @@ private: // UnwindLLDB needs to pass around references to RegisterLocations friend class UnwindLLDB; + + // Returns true if we have an unwind loop -- the same stack frame unwinding + // multiple times. + bool + CheckIfLoopingStack (); + // Indicates whether this frame is frame zero -- the currently // executing frame -- or not. bool @@ -175,11 +182,30 @@ private: bool TryFallbackUnwindPlan (); + //------------------------------------------------------------------ + /// Switch to the fallback unwind plan unconditionally without any safety + /// checks that it is providing better results than the normal unwind plan. + /// + /// The only time it is valid to call this method is if the full unwindplan is + /// found to be fundamentally incorrect/impossible. + /// + /// Returns true if it was able to install the fallback unwind plan. + //------------------------------------------------------------------ + bool + ForceSwitchToFallbackUnwindPlan (); + // Get the contents of a general purpose (address-size) register for this frame // (usually retrieved from the next frame) bool ReadGPRValue (lldb::RegisterKind register_kind, uint32_t regnum, lldb::addr_t &value); + bool + ReadGPRValue (const RegisterNumber ®_num, lldb::addr_t &value); + + // Get the CFA register for a given frame. + bool + ReadCFAValueForRow (lldb::RegisterKind register_kind, const UnwindPlan::RowSP &row, lldb::addr_t &value); + lldb::UnwindPlanSP GetFastUnwindPlanForFrame (); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index e246e71..a2ab674 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -149,7 +149,8 @@ RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info, // TOOD: need a better way to detect when "long double" types are // the same bytes size as "double" -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && !defined(__mips__) +#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(_MSC_VER) && \ + !defined(__mips__) && !defined(__powerpc__) && !defined(__ANDROID_NDK__) case sizeof (long double): if (sizeof (long double) == sizeof(uint32_t)) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp new file mode 100644 index 0000000..a9477d5 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -0,0 +1,273 @@ +//===-- RegisterContextPOSIX_powerpc.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/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Host/Endian.h" +#include "llvm/Support/Compiler.h" + +#include "RegisterContextPOSIX_powerpc.h" +#include "Plugins/Process/elf-core/ProcessElfCore.h" + +using namespace lldb_private; +using namespace lldb; + +static const +uint32_t g_gpr_regnums[] = +{ + gpr_r0_powerpc, + gpr_r1_powerpc, + gpr_r2_powerpc, + gpr_r3_powerpc, + gpr_r4_powerpc, + gpr_r5_powerpc, + gpr_r6_powerpc, + gpr_r7_powerpc, + gpr_r8_powerpc, + gpr_r9_powerpc, + gpr_r10_powerpc, + gpr_r11_powerpc, + gpr_r12_powerpc, + gpr_r13_powerpc, + gpr_r14_powerpc, + gpr_r15_powerpc, + gpr_r16_powerpc, + gpr_r17_powerpc, + gpr_r18_powerpc, + gpr_r19_powerpc, + gpr_r20_powerpc, + gpr_r21_powerpc, + gpr_r22_powerpc, + gpr_r23_powerpc, + gpr_r24_powerpc, + gpr_r25_powerpc, + gpr_r26_powerpc, + gpr_r27_powerpc, + gpr_r28_powerpc, + gpr_r29_powerpc, + gpr_r30_powerpc, + gpr_r31_powerpc, + gpr_lr_powerpc, + gpr_cr_powerpc, + gpr_xer_powerpc, + gpr_ctr_powerpc, + gpr_pc_powerpc, +}; + +static const +uint32_t g_fpr_regnums[] = +{ + fpr_f0_powerpc, + fpr_f1_powerpc, + fpr_f2_powerpc, + fpr_f3_powerpc, + fpr_f4_powerpc, + fpr_f5_powerpc, + fpr_f6_powerpc, + fpr_f7_powerpc, + fpr_f8_powerpc, + fpr_f9_powerpc, + fpr_f10_powerpc, + fpr_f11_powerpc, + fpr_f12_powerpc, + fpr_f13_powerpc, + fpr_f14_powerpc, + fpr_f15_powerpc, + fpr_f16_powerpc, + fpr_f17_powerpc, + fpr_f18_powerpc, + fpr_f19_powerpc, + fpr_f20_powerpc, + fpr_f21_powerpc, + fpr_f22_powerpc, + fpr_f23_powerpc, + fpr_f24_powerpc, + fpr_f25_powerpc, + fpr_f26_powerpc, + fpr_f27_powerpc, + fpr_f28_powerpc, + fpr_f29_powerpc, + fpr_f30_powerpc, + fpr_f31_powerpc, + fpr_fpscr_powerpc, +}; + +// Number of register sets provided by this context. +enum +{ + k_num_register_sets = 2 +}; + +static const RegisterSet +g_reg_sets_powerpc[k_num_register_sets] = +{ + { "General Purpose Registers", "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums }, + { "Floating Point Registers", "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums }, +}; + +bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg) +{ + return reg <= k_num_gpr_registers_powerpc; // GPR's come first. +} + +bool +RegisterContextPOSIX_powerpc::IsFPR(unsigned reg) +{ + // XXX + return (reg >= k_first_fpr) && (reg <= k_last_fpr); +} + +RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread, + uint32_t concrete_frame_idx, + RegisterInfoInterface *register_info) + : RegisterContext(thread, concrete_frame_idx) +{ + m_register_info_ap.reset(register_info); + + // elf-core yet to support ReadFPR() + ProcessSP base = CalculateProcess(); + if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic()) + return; +} + +RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc() +{ +} + +void +RegisterContextPOSIX_powerpc::Invalidate() +{ +} + +void +RegisterContextPOSIX_powerpc::InvalidateAllRegisters() +{ +} + +unsigned +RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg) +{ + assert(reg < k_num_registers_powerpc && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned +RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg) +{ + assert(reg < k_num_registers_powerpc && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + +size_t +RegisterContextPOSIX_powerpc::GetRegisterCount() +{ + size_t num_registers = k_num_registers_powerpc; + return num_registers; +} + +size_t +RegisterContextPOSIX_powerpc::GetGPRSize() +{ + return m_register_info_ap->GetGPRSize(); +} + +const RegisterInfo * +RegisterContextPOSIX_powerpc::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_powerpc::GetRegisterInfoAtIndex(size_t reg) +{ + if (reg < k_num_registers_powerpc) + return &GetRegisterInfo()[reg]; + else + return NULL; +} + +size_t +RegisterContextPOSIX_powerpc::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_powerpc::GetRegisterSet(size_t set) +{ + if (IsRegisterSetAvailable(set)) + return &g_reg_sets_powerpc[set]; + else + return NULL; +} + +const char * +RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg) +{ + assert(reg < k_num_registers_powerpc && "Invalid register offset."); + return GetRegisterInfo()[reg].name; +} + +lldb::ByteOrder +RegisterContextPOSIX_powerpc::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_powerpc::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_powerpc::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/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h new file mode 100644 index 0000000..3194c39 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -0,0 +1,173 @@ +//===-- RegisterContextPOSIX_powerpc.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_powerpc_H_ +#define liblldb_RegisterContextPOSIX_powerpc_H_ + +#include "lldb/Core/Log.h" +#include "RegisterContextPOSIX.h" +#include "RegisterContext_powerpc.h" + +class ProcessMonitor; + +// --------------------------------------------------------------------------- +// Internal codes for all powerpc registers. +// --------------------------------------------------------------------------- +enum +{ + k_first_gpr_powerpc, + gpr_r0_powerpc = k_first_gpr_powerpc, + gpr_r1_powerpc, + gpr_r2_powerpc, + gpr_r3_powerpc, + gpr_r4_powerpc, + gpr_r5_powerpc, + gpr_r6_powerpc, + gpr_r7_powerpc, + gpr_r8_powerpc, + gpr_r9_powerpc, + gpr_r10_powerpc, + gpr_r11_powerpc, + gpr_r12_powerpc, + gpr_r13_powerpc, + gpr_r14_powerpc, + gpr_r15_powerpc, + gpr_r16_powerpc, + gpr_r17_powerpc, + gpr_r18_powerpc, + gpr_r19_powerpc, + gpr_r20_powerpc, + gpr_r21_powerpc, + gpr_r22_powerpc, + gpr_r23_powerpc, + gpr_r24_powerpc, + gpr_r25_powerpc, + gpr_r26_powerpc, + gpr_r27_powerpc, + gpr_r28_powerpc, + gpr_r29_powerpc, + gpr_r30_powerpc, + gpr_r31_powerpc, + gpr_lr_powerpc, + gpr_cr_powerpc, + gpr_xer_powerpc, + gpr_ctr_powerpc, + gpr_pc_powerpc, + k_last_gpr_powerpc = gpr_pc_powerpc, + + k_first_fpr, + fpr_f0_powerpc = k_first_fpr, + fpr_f1_powerpc, + fpr_f2_powerpc, + fpr_f3_powerpc, + fpr_f4_powerpc, + fpr_f5_powerpc, + fpr_f6_powerpc, + fpr_f7_powerpc, + fpr_f8_powerpc, + fpr_f9_powerpc, + fpr_f10_powerpc, + fpr_f11_powerpc, + fpr_f12_powerpc, + fpr_f13_powerpc, + fpr_f14_powerpc, + fpr_f15_powerpc, + fpr_f16_powerpc, + fpr_f17_powerpc, + fpr_f18_powerpc, + fpr_f19_powerpc, + fpr_f20_powerpc, + fpr_f21_powerpc, + fpr_f22_powerpc, + fpr_f23_powerpc, + fpr_f24_powerpc, + fpr_f25_powerpc, + fpr_f26_powerpc, + fpr_f27_powerpc, + fpr_f28_powerpc, + fpr_f29_powerpc, + fpr_f30_powerpc, + fpr_f31_powerpc, + fpr_fpscr_powerpc, + k_last_fpr = fpr_fpscr_powerpc, + + k_num_registers_powerpc, + k_num_gpr_registers_powerpc = k_last_gpr_powerpc - k_first_gpr_powerpc + 1, + k_num_fpr_registers_powerpc = k_last_fpr - k_first_fpr + 1, +}; + +class RegisterContextPOSIX_powerpc + : public lldb_private::RegisterContext +{ +public: + RegisterContextPOSIX_powerpc (lldb_private::Thread &thread, + uint32_t concrete_frame_idx, + lldb_private::RegisterInfoInterface *register_info); + + ~RegisterContextPOSIX_powerpc(); + + void + Invalidate(); + + void + InvalidateAllRegisters(); + + size_t + GetRegisterCount(); + + virtual size_t + GetGPRSize(); + + virtual unsigned + GetRegisterSize(unsigned reg); + + virtual unsigned + GetRegisterOffset(unsigned reg); + + const lldb_private::RegisterInfo * + GetRegisterInfoAtIndex(size_t reg); + + size_t + GetRegisterSetCount(); + + const lldb_private::RegisterSet * + GetRegisterSet(size_t set); + + const char * + GetRegisterName(unsigned reg); + + uint32_t + ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num); + +protected: + uint64_t m_gpr_powerpc[k_num_gpr_registers_powerpc]; // general purpose registers. + std::unique_ptr<lldb_private::RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux) + + // 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); + + lldb::ByteOrder GetByteOrder(); + + virtual bool ReadGPR() = 0; + virtual bool ReadFPR() = 0; + virtual bool WriteGPR() = 0; + virtual bool WriteFPR() = 0; +}; + +#endif // #ifndef liblldb_RegisterContextPOSIX_powerpc_H_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index 2925a33..77b6385 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -30,96 +30,96 @@ using namespace lldb; const uint32_t g_gpr_regnums_i386[] = { - gpr_eax_i386, - gpr_ebx_i386, - gpr_ecx_i386, - gpr_edx_i386, - gpr_edi_i386, - gpr_esi_i386, - gpr_ebp_i386, - gpr_esp_i386, - gpr_eip_i386, - gpr_eflags_i386, - gpr_cs_i386, - gpr_fs_i386, - gpr_gs_i386, - gpr_ss_i386, - gpr_ds_i386, - gpr_es_i386, - gpr_ax_i386, - gpr_bx_i386, - gpr_cx_i386, - gpr_dx_i386, - gpr_di_i386, - gpr_si_i386, - gpr_bp_i386, - gpr_sp_i386, - gpr_ah_i386, - gpr_bh_i386, - gpr_ch_i386, - gpr_dh_i386, - gpr_al_i386, - gpr_bl_i386, - gpr_cl_i386, - gpr_dl_i386, + lldb_eax_i386, + lldb_ebx_i386, + lldb_ecx_i386, + lldb_edx_i386, + lldb_edi_i386, + lldb_esi_i386, + lldb_ebp_i386, + lldb_esp_i386, + lldb_eip_i386, + lldb_eflags_i386, + lldb_cs_i386, + lldb_fs_i386, + lldb_gs_i386, + lldb_ss_i386, + lldb_ds_i386, + lldb_es_i386, + lldb_ax_i386, + lldb_bx_i386, + lldb_cx_i386, + lldb_dx_i386, + lldb_di_i386, + lldb_si_i386, + lldb_bp_i386, + lldb_sp_i386, + lldb_ah_i386, + lldb_bh_i386, + lldb_ch_i386, + lldb_dh_i386, + lldb_al_i386, + lldb_bl_i386, + lldb_cl_i386, + lldb_dl_i386, LLDB_INVALID_REGNUM, // Register sets must be terminated with LLDB_INVALID_REGNUM. }; static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - 1 == k_num_gpr_registers_i386, "g_gpr_regnums_i386 has wrong number of register infos"); const uint32_t -g_fpu_regnums_i386[] = -{ - fpu_fctrl_i386, - fpu_fstat_i386, - fpu_ftag_i386, - fpu_fop_i386, - fpu_fiseg_i386, - fpu_fioff_i386, - fpu_foseg_i386, - fpu_fooff_i386, - fpu_mxcsr_i386, - fpu_mxcsrmask_i386, - fpu_st0_i386, - fpu_st1_i386, - fpu_st2_i386, - fpu_st3_i386, - fpu_st4_i386, - fpu_st5_i386, - fpu_st6_i386, - fpu_st7_i386, - fpu_mm0_i386, - fpu_mm1_i386, - fpu_mm2_i386, - fpu_mm3_i386, - fpu_mm4_i386, - fpu_mm5_i386, - fpu_mm6_i386, - fpu_mm7_i386, - fpu_xmm0_i386, - fpu_xmm1_i386, - fpu_xmm2_i386, - fpu_xmm3_i386, - fpu_xmm4_i386, - fpu_xmm5_i386, - fpu_xmm6_i386, - fpu_xmm7_i386, +g_lldb_regnums_i386[] = +{ + lldb_fctrl_i386, + lldb_fstat_i386, + lldb_ftag_i386, + lldb_fop_i386, + lldb_fiseg_i386, + lldb_fioff_i386, + lldb_foseg_i386, + lldb_fooff_i386, + lldb_mxcsr_i386, + lldb_mxcsrmask_i386, + lldb_st0_i386, + lldb_st1_i386, + lldb_st2_i386, + lldb_st3_i386, + lldb_st4_i386, + lldb_st5_i386, + lldb_st6_i386, + lldb_st7_i386, + lldb_mm0_i386, + lldb_mm1_i386, + lldb_mm2_i386, + lldb_mm3_i386, + lldb_mm4_i386, + lldb_mm5_i386, + lldb_mm6_i386, + lldb_mm7_i386, + lldb_xmm0_i386, + lldb_xmm1_i386, + lldb_xmm2_i386, + lldb_xmm3_i386, + lldb_xmm4_i386, + lldb_xmm5_i386, + lldb_xmm6_i386, + lldb_xmm7_i386, LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM. }; -static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) - 1 == k_num_fpr_registers_i386, - "g_fpu_regnums_i386 has wrong number of register infos"); +static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) - 1 == k_num_fpr_registers_i386, + "g_lldb_regnums_i386 has wrong number of register infos"); const uint32_t g_avx_regnums_i386[] = { - fpu_ymm0_i386, - fpu_ymm1_i386, - fpu_ymm2_i386, - fpu_ymm3_i386, - fpu_ymm4_i386, - fpu_ymm5_i386, - fpu_ymm6_i386, - fpu_ymm7_i386, + lldb_ymm0_i386, + lldb_ymm1_i386, + lldb_ymm2_i386, + lldb_ymm3_i386, + lldb_ymm4_i386, + lldb_ymm5_i386, + lldb_ymm6_i386, + lldb_ymm7_i386, LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM. }; static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 == k_num_avx_registers_i386, @@ -128,212 +128,212 @@ static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - 1 = static const uint32_t g_gpr_regnums_x86_64[] = { - gpr_rax_x86_64, - gpr_rbx_x86_64, - gpr_rcx_x86_64, - gpr_rdx_x86_64, - gpr_rdi_x86_64, - gpr_rsi_x86_64, - gpr_rbp_x86_64, - gpr_rsp_x86_64, - gpr_r8_x86_64, - gpr_r9_x86_64, - gpr_r10_x86_64, - gpr_r11_x86_64, - gpr_r12_x86_64, - gpr_r13_x86_64, - gpr_r14_x86_64, - gpr_r15_x86_64, - gpr_rip_x86_64, - gpr_rflags_x86_64, - gpr_cs_x86_64, - gpr_fs_x86_64, - gpr_gs_x86_64, - gpr_ss_x86_64, - gpr_ds_x86_64, - gpr_es_x86_64, - gpr_eax_x86_64, - gpr_ebx_x86_64, - gpr_ecx_x86_64, - gpr_edx_x86_64, - gpr_edi_x86_64, - gpr_esi_x86_64, - gpr_ebp_x86_64, - gpr_esp_x86_64, - gpr_r8d_x86_64, // Low 32 bits or r8 - gpr_r9d_x86_64, // Low 32 bits or r9 - gpr_r10d_x86_64, // Low 32 bits or r10 - gpr_r11d_x86_64, // Low 32 bits or r11 - gpr_r12d_x86_64, // Low 32 bits or r12 - gpr_r13d_x86_64, // Low 32 bits or r13 - gpr_r14d_x86_64, // Low 32 bits or r14 - gpr_r15d_x86_64, // Low 32 bits or r15 - gpr_ax_x86_64, - gpr_bx_x86_64, - gpr_cx_x86_64, - gpr_dx_x86_64, - gpr_di_x86_64, - gpr_si_x86_64, - gpr_bp_x86_64, - gpr_sp_x86_64, - gpr_r8w_x86_64, // Low 16 bits or r8 - gpr_r9w_x86_64, // Low 16 bits or r9 - gpr_r10w_x86_64, // Low 16 bits or r10 - gpr_r11w_x86_64, // Low 16 bits or r11 - gpr_r12w_x86_64, // Low 16 bits or r12 - gpr_r13w_x86_64, // Low 16 bits or r13 - gpr_r14w_x86_64, // Low 16 bits or r14 - gpr_r15w_x86_64, // Low 16 bits or r15 - gpr_ah_x86_64, - gpr_bh_x86_64, - gpr_ch_x86_64, - gpr_dh_x86_64, - gpr_al_x86_64, - gpr_bl_x86_64, - gpr_cl_x86_64, - gpr_dl_x86_64, - gpr_dil_x86_64, - gpr_sil_x86_64, - gpr_bpl_x86_64, - gpr_spl_x86_64, - gpr_r8l_x86_64, // Low 8 bits or r8 - gpr_r9l_x86_64, // Low 8 bits or r9 - gpr_r10l_x86_64, // Low 8 bits or r10 - gpr_r11l_x86_64, // Low 8 bits or r11 - gpr_r12l_x86_64, // Low 8 bits or r12 - gpr_r13l_x86_64, // Low 8 bits or r13 - gpr_r14l_x86_64, // Low 8 bits or r14 - gpr_r15l_x86_64, // Low 8 bits or r15 + lldb_rax_x86_64, + lldb_rbx_x86_64, + lldb_rcx_x86_64, + lldb_rdx_x86_64, + lldb_rdi_x86_64, + lldb_rsi_x86_64, + lldb_rbp_x86_64, + lldb_rsp_x86_64, + lldb_r8_x86_64, + lldb_r9_x86_64, + lldb_r10_x86_64, + lldb_r11_x86_64, + lldb_r12_x86_64, + lldb_r13_x86_64, + lldb_r14_x86_64, + lldb_r15_x86_64, + lldb_rip_x86_64, + lldb_rflags_x86_64, + lldb_cs_x86_64, + lldb_fs_x86_64, + lldb_gs_x86_64, + lldb_ss_x86_64, + lldb_ds_x86_64, + lldb_es_x86_64, + lldb_eax_x86_64, + lldb_ebx_x86_64, + lldb_ecx_x86_64, + lldb_edx_x86_64, + lldb_edi_x86_64, + lldb_esi_x86_64, + lldb_ebp_x86_64, + lldb_esp_x86_64, + lldb_r8d_x86_64, // Low 32 bits or r8 + lldb_r9d_x86_64, // Low 32 bits or r9 + lldb_r10d_x86_64, // Low 32 bits or r10 + lldb_r11d_x86_64, // Low 32 bits or r11 + lldb_r12d_x86_64, // Low 32 bits or r12 + lldb_r13d_x86_64, // Low 32 bits or r13 + lldb_r14d_x86_64, // Low 32 bits or r14 + lldb_r15d_x86_64, // Low 32 bits or r15 + lldb_ax_x86_64, + lldb_bx_x86_64, + lldb_cx_x86_64, + lldb_dx_x86_64, + lldb_di_x86_64, + lldb_si_x86_64, + lldb_bp_x86_64, + lldb_sp_x86_64, + lldb_r8w_x86_64, // Low 16 bits or r8 + lldb_r9w_x86_64, // Low 16 bits or r9 + lldb_r10w_x86_64, // Low 16 bits or r10 + lldb_r11w_x86_64, // Low 16 bits or r11 + lldb_r12w_x86_64, // Low 16 bits or r12 + lldb_r13w_x86_64, // Low 16 bits or r13 + lldb_r14w_x86_64, // Low 16 bits or r14 + lldb_r15w_x86_64, // Low 16 bits or r15 + lldb_ah_x86_64, + lldb_bh_x86_64, + lldb_ch_x86_64, + lldb_dh_x86_64, + lldb_al_x86_64, + lldb_bl_x86_64, + lldb_cl_x86_64, + lldb_dl_x86_64, + lldb_dil_x86_64, + lldb_sil_x86_64, + lldb_bpl_x86_64, + lldb_spl_x86_64, + lldb_r8l_x86_64, // Low 8 bits or r8 + lldb_r9l_x86_64, // Low 8 bits or r9 + lldb_r10l_x86_64, // Low 8 bits or r10 + lldb_r11l_x86_64, // Low 8 bits or r11 + lldb_r12l_x86_64, // Low 8 bits or r12 + lldb_r13l_x86_64, // Low 8 bits or r13 + lldb_r14l_x86_64, // Low 8 bits or r14 + lldb_r15l_x86_64, // Low 8 bits or r15 LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM. }; static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - 1 == k_num_gpr_registers_x86_64, "g_gpr_regnums_x86_64 has wrong number of register infos"); static const uint32_t -g_fpu_regnums_x86_64[] = -{ - fpu_fctrl_x86_64, - fpu_fstat_x86_64, - fpu_ftag_x86_64, - fpu_fop_x86_64, - fpu_fiseg_x86_64, - fpu_fioff_x86_64, - fpu_foseg_x86_64, - fpu_fooff_x86_64, - fpu_mxcsr_x86_64, - fpu_mxcsrmask_x86_64, - fpu_st0_x86_64, - fpu_st1_x86_64, - fpu_st2_x86_64, - fpu_st3_x86_64, - fpu_st4_x86_64, - fpu_st5_x86_64, - fpu_st6_x86_64, - fpu_st7_x86_64, - fpu_mm0_x86_64, - fpu_mm1_x86_64, - fpu_mm2_x86_64, - fpu_mm3_x86_64, - fpu_mm4_x86_64, - fpu_mm5_x86_64, - fpu_mm6_x86_64, - fpu_mm7_x86_64, - fpu_xmm0_x86_64, - fpu_xmm1_x86_64, - fpu_xmm2_x86_64, - fpu_xmm3_x86_64, - fpu_xmm4_x86_64, - fpu_xmm5_x86_64, - fpu_xmm6_x86_64, - fpu_xmm7_x86_64, - fpu_xmm8_x86_64, - fpu_xmm9_x86_64, - fpu_xmm10_x86_64, - fpu_xmm11_x86_64, - fpu_xmm12_x86_64, - fpu_xmm13_x86_64, - fpu_xmm14_x86_64, - fpu_xmm15_x86_64, +g_lldb_regnums_x86_64[] = +{ + lldb_fctrl_x86_64, + lldb_fstat_x86_64, + lldb_ftag_x86_64, + lldb_fop_x86_64, + lldb_fiseg_x86_64, + lldb_fioff_x86_64, + lldb_foseg_x86_64, + lldb_fooff_x86_64, + lldb_mxcsr_x86_64, + lldb_mxcsrmask_x86_64, + lldb_st0_x86_64, + lldb_st1_x86_64, + lldb_st2_x86_64, + lldb_st3_x86_64, + lldb_st4_x86_64, + lldb_st5_x86_64, + lldb_st6_x86_64, + lldb_st7_x86_64, + lldb_mm0_x86_64, + lldb_mm1_x86_64, + lldb_mm2_x86_64, + lldb_mm3_x86_64, + lldb_mm4_x86_64, + lldb_mm5_x86_64, + lldb_mm6_x86_64, + lldb_mm7_x86_64, + lldb_xmm0_x86_64, + lldb_xmm1_x86_64, + lldb_xmm2_x86_64, + lldb_xmm3_x86_64, + lldb_xmm4_x86_64, + lldb_xmm5_x86_64, + lldb_xmm6_x86_64, + lldb_xmm7_x86_64, + lldb_xmm8_x86_64, + lldb_xmm9_x86_64, + lldb_xmm10_x86_64, + lldb_xmm11_x86_64, + lldb_xmm12_x86_64, + lldb_xmm13_x86_64, + lldb_xmm14_x86_64, + lldb_xmm15_x86_64, LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM. }; -static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64, - "g_fpu_regnums_x86_64 has wrong number of register infos"); +static_assert((sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 == k_num_fpr_registers_x86_64, + "g_lldb_regnums_x86_64 has wrong number of register infos"); static const uint32_t g_avx_regnums_x86_64[] = { - fpu_ymm0_x86_64, - fpu_ymm1_x86_64, - fpu_ymm2_x86_64, - fpu_ymm3_x86_64, - fpu_ymm4_x86_64, - fpu_ymm5_x86_64, - fpu_ymm6_x86_64, - fpu_ymm7_x86_64, - fpu_ymm8_x86_64, - fpu_ymm9_x86_64, - fpu_ymm10_x86_64, - fpu_ymm11_x86_64, - fpu_ymm12_x86_64, - fpu_ymm13_x86_64, - fpu_ymm14_x86_64, - fpu_ymm15_x86_64, + lldb_ymm0_x86_64, + lldb_ymm1_x86_64, + lldb_ymm2_x86_64, + lldb_ymm3_x86_64, + lldb_ymm4_x86_64, + lldb_ymm5_x86_64, + lldb_ymm6_x86_64, + lldb_ymm7_x86_64, + lldb_ymm8_x86_64, + lldb_ymm9_x86_64, + lldb_ymm10_x86_64, + lldb_ymm11_x86_64, + lldb_ymm12_x86_64, + lldb_ymm13_x86_64, + lldb_ymm14_x86_64, + lldb_ymm15_x86_64, LLDB_INVALID_REGNUM // Register sets must be terminated with LLDB_INVALID_REGNUM. }; static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - 1 == k_num_avx_registers_x86_64, "g_avx_regnums_x86_64 has wrong number of register infos"); -uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = { gpr_eax_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = { gpr_ebx_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = { gpr_ecx_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = { gpr_edx_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = { gpr_edi_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = { gpr_esi_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = { gpr_ebp_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = { gpr_esp_i386, LLDB_INVALID_REGNUM }; - -uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { gpr_eax_i386, gpr_ax_i386, gpr_ah_i386, gpr_al_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { gpr_ebx_i386, gpr_bx_i386, gpr_bh_i386, gpr_bl_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { gpr_ecx_i386, gpr_cx_i386, gpr_ch_i386, gpr_cl_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { gpr_edx_i386, gpr_dx_i386, gpr_dh_i386, gpr_dl_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { gpr_edi_i386, gpr_di_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { gpr_esi_i386, gpr_si_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { gpr_ebp_i386, gpr_bp_i386, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { gpr_esp_i386, gpr_sp_i386, LLDB_INVALID_REGNUM }; - -uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = { gpr_rax_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = { gpr_rbx_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = { gpr_rcx_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = { gpr_rdx_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = { gpr_rdi_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = { gpr_rsi_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = { gpr_rbp_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = { gpr_rsp_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = { gpr_r8_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = { gpr_r9_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = { gpr_r10_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = { gpr_r11_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = { gpr_r12_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = { gpr_r13_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = { gpr_r14_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = { gpr_r15_x86_64, LLDB_INVALID_REGNUM }; - -uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { gpr_rax_x86_64, gpr_eax_x86_64, gpr_ax_x86_64, gpr_ah_x86_64, gpr_al_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { gpr_rbx_x86_64, gpr_ebx_x86_64, gpr_bx_x86_64, gpr_bh_x86_64, gpr_bl_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { gpr_rcx_x86_64, gpr_ecx_x86_64, gpr_cx_x86_64, gpr_ch_x86_64, gpr_cl_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { gpr_rdx_x86_64, gpr_edx_x86_64, gpr_dx_x86_64, gpr_dh_x86_64, gpr_dl_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { gpr_rdi_x86_64, gpr_edi_x86_64, gpr_di_x86_64, gpr_dil_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { gpr_rsi_x86_64, gpr_esi_x86_64, gpr_si_x86_64, gpr_sil_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { gpr_rbp_x86_64, gpr_ebp_x86_64, gpr_bp_x86_64, gpr_bpl_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { gpr_rsp_x86_64, gpr_esp_x86_64, gpr_sp_x86_64, gpr_spl_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = { gpr_r8_x86_64, gpr_r8d_x86_64, gpr_r8w_x86_64, gpr_r8l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = { gpr_r9_x86_64, gpr_r9d_x86_64, gpr_r9w_x86_64, gpr_r9l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { gpr_r10_x86_64, gpr_r10d_x86_64, gpr_r10w_x86_64, gpr_r10l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { gpr_r11_x86_64, gpr_r11d_x86_64, gpr_r11w_x86_64, gpr_r11l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { gpr_r12_x86_64, gpr_r12d_x86_64, gpr_r12w_x86_64, gpr_r12l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { gpr_r13_x86_64, gpr_r13d_x86_64, gpr_r13w_x86_64, gpr_r13l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { gpr_r14_x86_64, gpr_r14d_x86_64, gpr_r14w_x86_64, gpr_r14l_x86_64, LLDB_INVALID_REGNUM }; -uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = { gpr_r15_x86_64, gpr_r15d_x86_64, gpr_r15w_x86_64, gpr_r15l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = { lldb_eax_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = { lldb_ebx_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = { lldb_ecx_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = { lldb_edx_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = { lldb_edi_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = { lldb_esi_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = { lldb_ebp_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = { lldb_esp_i386, LLDB_INVALID_REGNUM }; + +uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM }; + +uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = { lldb_rax_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = { lldb_rbx_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = { lldb_rcx_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = { lldb_rdx_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = { lldb_rdi_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = { lldb_rsi_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = { lldb_rbp_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = { lldb_rsp_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = { lldb_r8_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = { lldb_r9_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = { lldb_r10_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = { lldb_r11_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = { lldb_r12_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = { lldb_r13_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = { lldb_r14_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = { lldb_r15_x86_64, LLDB_INVALID_REGNUM }; + +uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { lldb_rax_x86_64, lldb_eax_x86_64, lldb_ax_x86_64, lldb_ah_x86_64, lldb_al_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { lldb_rbx_x86_64, lldb_ebx_x86_64, lldb_bx_x86_64, lldb_bh_x86_64, lldb_bl_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { lldb_rcx_x86_64, lldb_ecx_x86_64, lldb_cx_x86_64, lldb_ch_x86_64, lldb_cl_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { lldb_rdx_x86_64, lldb_edx_x86_64, lldb_dx_x86_64, lldb_dh_x86_64, lldb_dl_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { lldb_rdi_x86_64, lldb_edi_x86_64, lldb_di_x86_64, lldb_dil_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { lldb_rsi_x86_64, lldb_esi_x86_64, lldb_si_x86_64, lldb_sil_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { lldb_rbp_x86_64, lldb_ebp_x86_64, lldb_bp_x86_64, lldb_bpl_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { lldb_rsp_x86_64, lldb_esp_x86_64, lldb_sp_x86_64, lldb_spl_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = { lldb_r8_x86_64, lldb_r8d_x86_64, lldb_r8w_x86_64, lldb_r8l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = { lldb_r9_x86_64, lldb_r9d_x86_64, lldb_r9w_x86_64, lldb_r9l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { lldb_r10_x86_64, lldb_r10d_x86_64, lldb_r10w_x86_64, lldb_r10l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { lldb_r11_x86_64, lldb_r11d_x86_64, lldb_r11w_x86_64, lldb_r11l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { lldb_r12_x86_64, lldb_r12d_x86_64, lldb_r12w_x86_64, lldb_r12l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { lldb_r13_x86_64, lldb_r13d_x86_64, lldb_r13w_x86_64, lldb_r13l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { lldb_r14_x86_64, lldb_r14d_x86_64, lldb_r14w_x86_64, lldb_r14l_x86_64, LLDB_INVALID_REGNUM }; +uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = { lldb_r15_x86_64, lldb_r15d_x86_64, lldb_r15w_x86_64, lldb_r15l_x86_64, LLDB_INVALID_REGNUM }; // Number of register sets provided by this context. enum @@ -346,7 +346,7 @@ static const RegisterSet g_reg_sets_i386[k_num_register_sets] = { { "General Purpose Registers", "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 }, - { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386 }, + { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_lldb_regnums_i386 }, { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 } }; @@ -354,7 +354,7 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 }, - { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 }, + { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_lldb_regnums_x86_64 }, { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 } }; @@ -399,16 +399,16 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(Thread &thread, m_reg_info.last_gpr = k_last_gpr_i386; m_reg_info.first_fpr = k_first_fpr_i386; m_reg_info.last_fpr = k_last_fpr_i386; - m_reg_info.first_st = fpu_st0_i386; - m_reg_info.last_st = fpu_st7_i386; - m_reg_info.first_mm = fpu_mm0_i386; - m_reg_info.last_mm = fpu_mm7_i386; - m_reg_info.first_xmm = fpu_xmm0_i386; - m_reg_info.last_xmm = fpu_xmm7_i386; - m_reg_info.first_ymm = fpu_ymm0_i386; - m_reg_info.last_ymm = fpu_ymm7_i386; - m_reg_info.first_dr = dr0_i386; - m_reg_info.gpr_flags = gpr_eflags_i386; + m_reg_info.first_st = lldb_st0_i386; + m_reg_info.last_st = lldb_st7_i386; + m_reg_info.first_mm = lldb_mm0_i386; + m_reg_info.last_mm = lldb_mm7_i386; + m_reg_info.first_xmm = lldb_xmm0_i386; + m_reg_info.last_xmm = lldb_xmm7_i386; + m_reg_info.first_ymm = lldb_ymm0_i386; + m_reg_info.last_ymm = lldb_ymm7_i386; + m_reg_info.first_dr = lldb_dr0_i386; + m_reg_info.gpr_flags = lldb_eflags_i386; break; case llvm::Triple::x86_64: m_reg_info.num_registers = k_num_registers_x86_64; @@ -418,16 +418,16 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(Thread &thread, m_reg_info.last_gpr = k_last_gpr_x86_64; m_reg_info.first_fpr = k_first_fpr_x86_64; m_reg_info.last_fpr = k_last_fpr_x86_64; - m_reg_info.first_st = fpu_st0_x86_64; - m_reg_info.last_st = fpu_st7_x86_64; - m_reg_info.first_mm = fpu_mm0_x86_64; - m_reg_info.last_mm = fpu_mm7_x86_64; - m_reg_info.first_xmm = fpu_xmm0_x86_64; - m_reg_info.last_xmm = fpu_xmm15_x86_64; - m_reg_info.first_ymm = fpu_ymm0_x86_64; - m_reg_info.last_ymm = fpu_ymm15_x86_64; - m_reg_info.first_dr = dr0_x86_64; - m_reg_info.gpr_flags = gpr_rflags_x86_64; + m_reg_info.first_st = lldb_st0_x86_64; + m_reg_info.last_st = lldb_st7_x86_64; + m_reg_info.first_mm = lldb_mm0_x86_64; + m_reg_info.last_mm = lldb_mm7_x86_64; + m_reg_info.first_xmm = lldb_xmm0_x86_64; + m_reg_info.last_xmm = lldb_xmm15_x86_64; + m_reg_info.first_ymm = lldb_ymm0_x86_64; + m_reg_info.last_ymm = lldb_ymm15_x86_64; + m_reg_info.first_dr = lldb_dr0_x86_64; + m_reg_info.gpr_flags = lldb_rflags_x86_64; break; default: assert(false && "Unhandled target architecture."); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index 4db7802..0eec1d9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -11,285 +11,12 @@ #define liblldb_RegisterContextPOSIX_x86_H_ #include "lldb/Core/Log.h" +#include "lldb-x86-register-enums.h" #include "RegisterContextPOSIX.h" #include "RegisterContext_x86.h" class ProcessMonitor; -//--------------------------------------------------------------------------- -// Internal codes for all i386 registers. -//--------------------------------------------------------------------------- -enum -{ - k_first_gpr_i386, - gpr_eax_i386 = k_first_gpr_i386, - gpr_ebx_i386, - gpr_ecx_i386, - gpr_edx_i386, - gpr_edi_i386, - gpr_esi_i386, - gpr_ebp_i386, - gpr_esp_i386, - gpr_eip_i386, - gpr_eflags_i386, - gpr_cs_i386, - gpr_fs_i386, - gpr_gs_i386, - gpr_ss_i386, - gpr_ds_i386, - gpr_es_i386, - - k_first_alias_i386, - gpr_ax_i386 = k_first_alias_i386, - gpr_bx_i386, - gpr_cx_i386, - gpr_dx_i386, - gpr_di_i386, - gpr_si_i386, - gpr_bp_i386, - gpr_sp_i386, - gpr_ah_i386, - gpr_bh_i386, - gpr_ch_i386, - gpr_dh_i386, - gpr_al_i386, - gpr_bl_i386, - gpr_cl_i386, - gpr_dl_i386, - k_last_alias_i386 = gpr_dl_i386, - - k_last_gpr_i386 = k_last_alias_i386, - - k_first_fpr_i386, - fpu_fctrl_i386 = k_first_fpr_i386, - fpu_fstat_i386, - fpu_ftag_i386, - fpu_fop_i386, - fpu_fiseg_i386, - fpu_fioff_i386, - fpu_foseg_i386, - fpu_fooff_i386, - fpu_mxcsr_i386, - fpu_mxcsrmask_i386, - fpu_st0_i386, - fpu_st1_i386, - fpu_st2_i386, - fpu_st3_i386, - fpu_st4_i386, - fpu_st5_i386, - fpu_st6_i386, - fpu_st7_i386, - fpu_mm0_i386, - fpu_mm1_i386, - fpu_mm2_i386, - fpu_mm3_i386, - fpu_mm4_i386, - fpu_mm5_i386, - fpu_mm6_i386, - fpu_mm7_i386, - fpu_xmm0_i386, - fpu_xmm1_i386, - fpu_xmm2_i386, - fpu_xmm3_i386, - fpu_xmm4_i386, - fpu_xmm5_i386, - fpu_xmm6_i386, - fpu_xmm7_i386, - k_last_fpr_i386 = fpu_xmm7_i386, - - k_first_avx_i386, - fpu_ymm0_i386 = k_first_avx_i386, - fpu_ymm1_i386, - fpu_ymm2_i386, - fpu_ymm3_i386, - fpu_ymm4_i386, - fpu_ymm5_i386, - fpu_ymm6_i386, - fpu_ymm7_i386, - k_last_avx_i386 = fpu_ymm7_i386, - - dr0_i386, - dr1_i386, - dr2_i386, - dr3_i386, - dr4_i386, - dr5_i386, - dr6_i386, - dr7_i386, - - k_num_registers_i386, - k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, - k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1, - k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1 -}; - -//--------------------------------------------------------------------------- -// Internal codes for all x86_64 registers. -//--------------------------------------------------------------------------- -enum -{ - k_first_gpr_x86_64, - gpr_rax_x86_64 = k_first_gpr_x86_64, - gpr_rbx_x86_64, - gpr_rcx_x86_64, - gpr_rdx_x86_64, - gpr_rdi_x86_64, - gpr_rsi_x86_64, - gpr_rbp_x86_64, - gpr_rsp_x86_64, - gpr_r8_x86_64, - gpr_r9_x86_64, - gpr_r10_x86_64, - gpr_r11_x86_64, - gpr_r12_x86_64, - gpr_r13_x86_64, - gpr_r14_x86_64, - gpr_r15_x86_64, - gpr_rip_x86_64, - gpr_rflags_x86_64, - gpr_cs_x86_64, - gpr_fs_x86_64, - gpr_gs_x86_64, - gpr_ss_x86_64, - gpr_ds_x86_64, - gpr_es_x86_64, - - k_first_alias_x86_64, - gpr_eax_x86_64 = k_first_alias_x86_64, - gpr_ebx_x86_64, - gpr_ecx_x86_64, - gpr_edx_x86_64, - gpr_edi_x86_64, - gpr_esi_x86_64, - gpr_ebp_x86_64, - gpr_esp_x86_64, - gpr_r8d_x86_64, // Low 32 bits of r8 - gpr_r9d_x86_64, // Low 32 bits of r9 - gpr_r10d_x86_64, // Low 32 bits of r10 - gpr_r11d_x86_64, // Low 32 bits of r11 - gpr_r12d_x86_64, // Low 32 bits of r12 - gpr_r13d_x86_64, // Low 32 bits of r13 - gpr_r14d_x86_64, // Low 32 bits of r14 - gpr_r15d_x86_64, // Low 32 bits of r15 - gpr_ax_x86_64, - gpr_bx_x86_64, - gpr_cx_x86_64, - gpr_dx_x86_64, - gpr_di_x86_64, - gpr_si_x86_64, - gpr_bp_x86_64, - gpr_sp_x86_64, - gpr_r8w_x86_64, // Low 16 bits of r8 - gpr_r9w_x86_64, // Low 16 bits of r9 - gpr_r10w_x86_64, // Low 16 bits of r10 - gpr_r11w_x86_64, // Low 16 bits of r11 - gpr_r12w_x86_64, // Low 16 bits of r12 - gpr_r13w_x86_64, // Low 16 bits of r13 - gpr_r14w_x86_64, // Low 16 bits of r14 - gpr_r15w_x86_64, // Low 16 bits of r15 - gpr_ah_x86_64, - gpr_bh_x86_64, - gpr_ch_x86_64, - gpr_dh_x86_64, - gpr_al_x86_64, - gpr_bl_x86_64, - gpr_cl_x86_64, - gpr_dl_x86_64, - gpr_dil_x86_64, - gpr_sil_x86_64, - gpr_bpl_x86_64, - gpr_spl_x86_64, - gpr_r8l_x86_64, // Low 8 bits of r8 - gpr_r9l_x86_64, // Low 8 bits of r9 - gpr_r10l_x86_64, // Low 8 bits of r10 - gpr_r11l_x86_64, // Low 8 bits of r11 - gpr_r12l_x86_64, // Low 8 bits of r12 - gpr_r13l_x86_64, // Low 8 bits of r13 - gpr_r14l_x86_64, // Low 8 bits of r14 - gpr_r15l_x86_64, // Low 8 bits of r15 - k_last_alias_x86_64 = gpr_r15l_x86_64, - - k_last_gpr_x86_64 = k_last_alias_x86_64, - - k_first_fpr_x86_64, - fpu_fctrl_x86_64 = k_first_fpr_x86_64, - fpu_fstat_x86_64, - fpu_ftag_x86_64, - fpu_fop_x86_64, - fpu_fiseg_x86_64, - fpu_fioff_x86_64, - fpu_foseg_x86_64, - fpu_fooff_x86_64, - fpu_mxcsr_x86_64, - fpu_mxcsrmask_x86_64, - fpu_st0_x86_64, - fpu_st1_x86_64, - fpu_st2_x86_64, - fpu_st3_x86_64, - fpu_st4_x86_64, - fpu_st5_x86_64, - fpu_st6_x86_64, - fpu_st7_x86_64, - fpu_mm0_x86_64, - fpu_mm1_x86_64, - fpu_mm2_x86_64, - fpu_mm3_x86_64, - fpu_mm4_x86_64, - fpu_mm5_x86_64, - fpu_mm6_x86_64, - fpu_mm7_x86_64, - fpu_xmm0_x86_64, - fpu_xmm1_x86_64, - fpu_xmm2_x86_64, - fpu_xmm3_x86_64, - fpu_xmm4_x86_64, - fpu_xmm5_x86_64, - fpu_xmm6_x86_64, - fpu_xmm7_x86_64, - fpu_xmm8_x86_64, - fpu_xmm9_x86_64, - fpu_xmm10_x86_64, - fpu_xmm11_x86_64, - fpu_xmm12_x86_64, - fpu_xmm13_x86_64, - fpu_xmm14_x86_64, - fpu_xmm15_x86_64, - k_last_fpr_x86_64 = fpu_xmm15_x86_64, - - k_first_avx_x86_64, - fpu_ymm0_x86_64 = k_first_avx_x86_64, - fpu_ymm1_x86_64, - fpu_ymm2_x86_64, - fpu_ymm3_x86_64, - fpu_ymm4_x86_64, - fpu_ymm5_x86_64, - fpu_ymm6_x86_64, - fpu_ymm7_x86_64, - fpu_ymm8_x86_64, - fpu_ymm9_x86_64, - fpu_ymm10_x86_64, - fpu_ymm11_x86_64, - fpu_ymm12_x86_64, - fpu_ymm13_x86_64, - fpu_ymm14_x86_64, - fpu_ymm15_x86_64, - k_last_avx_x86_64 = fpu_ymm15_x86_64, - - dr0_x86_64, - dr1_x86_64, - dr2_x86_64, - dr3_x86_64, - dr4_x86_64, - dr5_x86_64, - dr6_x86_64, - dr7_x86_64, - - k_num_registers_x86_64, - k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1, - k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1, - k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1 -}; - class RegisterContextPOSIX_x86 : public lldb_private::RegisterContext { @@ -422,7 +149,7 @@ protected: uint32_t gpr_flags; }; - uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64]; // 64-bit general purpose registers. + uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit general purpose registers. 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. diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp index 46dafa1..200ef4d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.cpp @@ -59,7 +59,7 @@ RegisterContextThreadMemory::UpdateRegisterContext () { OperatingSystem *os = process_sp->GetOperatingSystem (); if (os->IsOperatingSystemPluginThread (thread_sp)) - m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), LLDB_INVALID_ADDRESS); + m_reg_ctx_sp = os->CreateRegisterContextForThread (thread_sp.get(), m_register_data_addr); } } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h new file mode 100644 index 0000000..cf54cc0 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_powerpc.h @@ -0,0 +1,163 @@ +//===-- RegisterContext_powerpc.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_RegisterContext_powerpc_H_ +#define liblldb_RegisterContext_powerpc_H_ + +// GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF) +enum +{ + gcc_dwarf_r0_powerpc = 0, + gcc_dwarf_r1_powerpc, + gcc_dwarf_r2_powerpc, + gcc_dwarf_r3_powerpc, + gcc_dwarf_r4_powerpc, + gcc_dwarf_r5_powerpc, + gcc_dwarf_r6_powerpc, + gcc_dwarf_r7_powerpc, + gcc_dwarf_r8_powerpc, + gcc_dwarf_r9_powerpc, + gcc_dwarf_r10_powerpc, + gcc_dwarf_r11_powerpc, + gcc_dwarf_r12_powerpc, + gcc_dwarf_r13_powerpc, + gcc_dwarf_r14_powerpc, + gcc_dwarf_r15_powerpc, + gcc_dwarf_r16_powerpc, + gcc_dwarf_r17_powerpc, + gcc_dwarf_r18_powerpc, + gcc_dwarf_r19_powerpc, + gcc_dwarf_r20_powerpc, + gcc_dwarf_r21_powerpc, + gcc_dwarf_r22_powerpc, + gcc_dwarf_r23_powerpc, + gcc_dwarf_r24_powerpc, + gcc_dwarf_r25_powerpc, + gcc_dwarf_r26_powerpc, + gcc_dwarf_r27_powerpc, + gcc_dwarf_r28_powerpc, + gcc_dwarf_r29_powerpc, + gcc_dwarf_r30_powerpc, + gcc_dwarf_r31_powerpc, + gcc_dwarf_f0_powerpc, + gcc_dwarf_f1_powerpc, + gcc_dwarf_f2_powerpc, + gcc_dwarf_f3_powerpc, + gcc_dwarf_f4_powerpc, + gcc_dwarf_f5_powerpc, + gcc_dwarf_f6_powerpc, + gcc_dwarf_f7_powerpc, + gcc_dwarf_f8_powerpc, + gcc_dwarf_f9_powerpc, + gcc_dwarf_f10_powerpc, + gcc_dwarf_f11_powerpc, + gcc_dwarf_f12_powerpc, + gcc_dwarf_f13_powerpc, + gcc_dwarf_f14_powerpc, + gcc_dwarf_f15_powerpc, + gcc_dwarf_f16_powerpc, + gcc_dwarf_f17_powerpc, + gcc_dwarf_f18_powerpc, + gcc_dwarf_f19_powerpc, + gcc_dwarf_f20_powerpc, + gcc_dwarf_f21_powerpc, + gcc_dwarf_f22_powerpc, + gcc_dwarf_f23_powerpc, + gcc_dwarf_f24_powerpc, + gcc_dwarf_f25_powerpc, + gcc_dwarf_f26_powerpc, + gcc_dwarf_f27_powerpc, + gcc_dwarf_f28_powerpc, + gcc_dwarf_f29_powerpc, + gcc_dwarf_f30_powerpc, + gcc_dwarf_f31_powerpc, + gcc_dwarf_cr_powerpc, + gcc_dwarf_fpscr_powerpc, + gcc_dwarf_xer_powerpc = 101, + gcc_dwarf_lr_powerpc = 108, + gcc_dwarf_ctr_powerpc, + gcc_dwarf_pc_powerpc, +}; + +// GDB Register numbers (eRegisterKindGDB) +enum +{ + gdb_r0_powerpc = 0, + gdb_r1_powerpc, + gdb_r2_powerpc, + gdb_r3_powerpc, + gdb_r4_powerpc, + gdb_r5_powerpc, + gdb_r6_powerpc, + gdb_r7_powerpc, + gdb_r8_powerpc, + gdb_r9_powerpc, + gdb_r10_powerpc, + gdb_r11_powerpc, + gdb_r12_powerpc, + gdb_r13_powerpc, + gdb_r14_powerpc, + gdb_r15_powerpc, + gdb_r16_powerpc, + gdb_r17_powerpc, + gdb_r18_powerpc, + gdb_r19_powerpc, + gdb_r20_powerpc, + gdb_r21_powerpc, + gdb_r22_powerpc, + gdb_r23_powerpc, + gdb_r24_powerpc, + gdb_r25_powerpc, + gdb_r26_powerpc, + gdb_r27_powerpc, + gdb_r28_powerpc, + gdb_r29_powerpc, + gdb_r30_powerpc, + gdb_r31_powerpc, + gdb_f0_powerpc, + gdb_f1_powerpc, + gdb_f2_powerpc, + gdb_f3_powerpc, + gdb_f4_powerpc, + gdb_f5_powerpc, + gdb_f6_powerpc, + gdb_f7_powerpc, + gdb_f8_powerpc, + gdb_f9_powerpc, + gdb_f10_powerpc, + gdb_f11_powerpc, + gdb_f12_powerpc, + gdb_f13_powerpc, + gdb_f14_powerpc, + gdb_f15_powerpc, + gdb_f16_powerpc, + gdb_f17_powerpc, + gdb_f18_powerpc, + gdb_f19_powerpc, + gdb_f20_powerpc, + gdb_f21_powerpc, + gdb_f22_powerpc, + gdb_f23_powerpc, + gdb_f24_powerpc, + gdb_f25_powerpc, + gdb_f26_powerpc, + gdb_f27_powerpc, + gdb_f28_powerpc, + gdb_f29_powerpc, + gdb_f30_powerpc, + gdb_f31_powerpc, + gdb_cr_powerpc, + gdb_fpscr_powerpc, + gdb_xer_powerpc = 101, + gdb_lr_powerpc = 108, + gdb_ctr_powerpc, + gdb_pc_powerpc, +}; + +#endif // liblldb_RegisterContext_powerpc_H_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index fa152b4..fc94b8b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -42,37 +42,37 @@ // Note that the size and offset will be updated by platform-specific classes. #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_i386 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, NULL, NULL } #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##name##_i386 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_i386 }, NULL, NULL } // RegisterKind: GCC, DWARF, Generic, GDB, LLDB #define DEFINE_FP_ST(reg, i) \ { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ eEncodingVector, eFormatVectorOfUInt8, \ - { gcc_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, gdb_st##i##_i386, fpu_st##i##_i386 }, \ + { gcc_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, gdb_st##i##_i386, lldb_st##i##_i386 }, \ NULL, NULL } #define DEFINE_FP_MM(reg, i) \ { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ eEncodingUint, eFormatHex, \ - { gcc_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, gdb_mm##i##_i386, fpu_mm##i##_i386 }, \ + { gcc_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, gdb_mm##i##_i386, lldb_mm##i##_i386 }, \ NULL, NULL } #define DEFINE_XMM(reg, i) \ { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ eEncodingVector, eFormatVectorOfUInt8, \ - { gcc_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, gdb_##reg##i##_i386, fpu_##reg##i##_i386}, \ + { gcc_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, gdb_##reg##i##_i386, lldb_##reg##i##_i386}, \ NULL, NULL } // I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then differentiate based on register size. #define DEFINE_YMM(reg, i) \ { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(reg[i]), \ eEncodingVector, eFormatVectorOfUInt8, \ - { LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, LLDB_INVALID_REGNUM, gdb_##reg##i##h_i386, fpu_##reg##i##_i386 }, \ + { LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, LLDB_INVALID_REGNUM, gdb_##reg##i##h_i386, lldb_##reg##i##_i386 }, \ NULL, NULL } #define DEFINE_DR(reg, i) \ @@ -82,13 +82,13 @@ #define DEFINE_GPR_PSEUDO_16(reg16, reg32) \ { #reg16, NULL, 2, GPR_OFFSET(reg32), eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg16##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 } #define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ { #reg8, NULL, 1, GPR_OFFSET(reg32)+1, eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 } #define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ { #reg8, NULL, 1, GPR_OFFSET(reg32), eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 } static RegisterInfo g_register_infos_i386[] = diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h new file mode 100644 index 0000000..0454266 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -0,0 +1,144 @@ +//===-- RegisterInfos_powerpc.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#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)) +#define GPR_SIZE(regname) \ + (sizeof(((GPR*)NULL)->regname)) + +#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT + +// 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), eEncodingUint, \ + eFormatHex, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, gpr_##reg##_powerpc }, NULL, NULL } +#define DEFINE_FPR(reg, lldb_kind) \ + { #reg, NULL, 8, FPR_OFFSET(reg), eEncodingIEEE754, \ + eFormatFloat, { gcc_dwarf_##reg##_powerpc, gcc_dwarf_##reg##_powerpc, lldb_kind, gdb_##reg##_powerpc, fpr_##reg##_powerpc }, NULL, NULL } + + // General purpose registers. GCC, DWARF, Generic, GDB +#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(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \ + DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \ + DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \ + DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f3, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f4, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f5, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f6, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f7, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f8, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f9, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f10, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f11, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f12, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f13, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f14, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f15, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f16, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f17, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f18, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f19, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f20, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f21, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f22, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f23, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f24, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f25, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f26, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f27, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f28, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f29, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f30, LLDB_INVALID_REGNUM), \ + DEFINE_FPR(f31, LLDB_INVALID_REGNUM), \ + { "fpscr", NULL, 8, FPR_OFFSET(fpscr), eEncodingUint, eFormatHex, { gcc_dwarf_fpscr_powerpc, gcc_dwarf_fpscr_powerpc, LLDB_INVALID_REGNUM, gdb_fpscr_powerpc, fpr_fpscr_powerpc }, NULL, NULL }, +static RegisterInfo +g_register_infos_powerpc64[] = +{ +#define GPR GPR64 + POWERPC_REGS +#undef GPR +}; + +static RegisterInfo +g_register_infos_powerpc32[] = +{ +#define GPR GPR32 + POWERPC_REGS +#undef GPR +}; + +static RegisterInfo +g_register_infos_powerpc64_32[] = +{ +#define GPR GPR64 +#undef GPR_SIZE +#define GPR_SIZE(reg) (sizeof(uint32_t)) +#undef GPR_OFFSET +#define GPR_OFFSET(regname) \ + (offsetof(GPR, regname) + (sizeof(((GPR *)NULL)->regname) - GPR_SIZE(reg))) + POWERPC_REGS +#undef GPR +}; + +static_assert((sizeof(g_register_infos_powerpc32) / sizeof(g_register_infos_powerpc32[0])) == k_num_registers_powerpc, + "g_register_infos_powerpc32 has wrong number of register infos"); +static_assert((sizeof(g_register_infos_powerpc64) / sizeof(g_register_infos_powerpc64[0])) == k_num_registers_powerpc, + "g_register_infos_powerpc64 has wrong number of register infos"); +static_assert(sizeof(g_register_infos_powerpc64_32) == sizeof(g_register_infos_powerpc64), + "g_register_infos_powerpc64_32 doesn't match size of g_register_infos_powerpc64"); + +#undef DEFINE_FPR +#undef DEFINE_GPR + +#endif // DECLARE_REGISTER_INFOS_POWERPC_STRUCT + +#undef GPR_OFFSET + diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h index c4dc604..c1bcd27 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h @@ -42,34 +42,34 @@ // Note that the size and offset will be updated by platform-specific classes. #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { #reg, alt, sizeof(((GPR*)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_x86_64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, NULL, NULL } #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##name##_x86_64 }, NULL, NULL } + eFormatHex, { kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, NULL, NULL } #define DEFINE_FP_ST(reg, i) \ { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ eEncodingVector, eFormatVectorOfUInt8, \ - { gcc_dwarf_st##i##_x86_64, gcc_dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, gdb_st##i##_x86_64, fpu_st##i##_x86_64 }, \ + { gcc_dwarf_st##i##_x86_64, gcc_dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, gdb_st##i##_x86_64, lldb_st##i##_x86_64 }, \ NULL, NULL } #define DEFINE_FP_MM(reg, i) \ { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ eEncodingUint, eFormatHex, \ - { gcc_dwarf_mm##i##_x86_64, gcc_dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, gdb_st##i##_x86_64, fpu_mm##i##_x86_64 }, \ + { gcc_dwarf_mm##i##_x86_64, gcc_dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, gdb_st##i##_x86_64, lldb_mm##i##_x86_64 }, \ NULL, NULL } #define DEFINE_XMM(reg, i) \ { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ eEncodingVector, eFormatVectorOfUInt8, \ - { gcc_dwarf_##reg##i##_x86_64, gcc_dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##_x86_64, fpu_##reg##i##_x86_64}, \ + { gcc_dwarf_##reg##i##_x86_64, gcc_dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##_x86_64, lldb_##reg##i##_x86_64}, \ NULL, NULL } #define DEFINE_YMM(reg, i) \ { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(reg[i]), \ eEncodingVector, eFormatVectorOfUInt8, \ - { gcc_dwarf_##reg##i##h_x86_64, gcc_dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##h_x86_64, fpu_##reg##i##_x86_64 }, \ + { gcc_dwarf_##reg##i##h_x86_64, gcc_dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##h_x86_64, lldb_##reg##i##_x86_64 }, \ NULL, NULL } #define DEFINE_DR(reg, i) \ @@ -79,16 +79,16 @@ #define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } #define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } #define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } #define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \ - eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } + eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 } static RegisterInfo g_register_infos_x86_64[] = @@ -273,37 +273,37 @@ static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[ #define UPDATE_GPR_INFO(reg, reg64) \ do { \ - g_register_infos[gpr_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \ } while(false); #define UPDATE_GPR_INFO_8H(reg, reg64) \ do { \ - g_register_infos[gpr_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \ } while(false); #define UPDATE_FPR_INFO(reg, reg64) \ do { \ - g_register_infos[fpu_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \ + g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \ } while(false); #define UPDATE_FP_INFO(reg, i) \ do { \ - g_register_infos[fpu_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \ } while(false); #define UPDATE_XMM_INFO(reg, i) \ do { \ - g_register_infos[fpu_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \ } while(false); #define UPDATE_YMM_INFO(reg, i) \ do { \ - g_register_infos[fpu_##reg##i##_i386].byte_offset = YMM_OFFSET(reg[i]); \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(reg[i]); \ } while(false); #define UPDATE_DR_INFO(reg_index) \ do { \ - g_register_infos[dr##reg_index##_i386].byte_offset = DR_OFFSET(reg_index); \ + g_register_infos[lldb_dr##reg_index##_i386].byte_offset = DR_OFFSET(reg_index); \ } while(false); // Update the register offsets diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 0e3e559..a69b38b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -423,9 +423,11 @@ StopInfoMachException::CreateStopReasonWithMachException wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID()); } - // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS - if (thread.GetTemporaryResumeState() == eStateStepping) - return StopInfo::CreateStopReasonToTrace(thread); + else + { + is_actual_breakpoint = true; + is_trace_if_actual_breakpoint_missing = true; + } } else if (exc_code == 1) // EXC_ARM_BREAKPOINT { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 37fd4f4..fc592e6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -172,8 +172,9 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) if (!reg_ctx_sp->IsValid()) { - // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return - // true. Subsequent calls to TryFallbackUnwindPlan() will return false. + // We failed to get a valid RegisterContext. + // See if the regctx below this on the stack has a fallback unwind plan it can use. + // Subsequent calls to TryFallbackUnwindPlan() will return false. if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { return AddOneMoreFrame (abi); @@ -207,18 +208,35 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) // these. if (reg_ctx_sp->IsTrapHandlerFrame() == false) { - // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return - // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + // See if we can find a fallback unwind plan for THIS frame. It may be + // that the UnwindPlan we're using for THIS frame was bad and gave us a + // bad CFA. + // If that's not it, then see if we can change the UnwindPlan for the frame + // below us ("NEXT") -- see if using that other UnwindPlan gets us a better + // unwind state. + if (reg_ctx_sp->TryFallbackUnwindPlan() == false + || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false + || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { - return AddOneMoreFrame (abi); + if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + return AddOneMoreFrame (abi); + } + if (log) + { + log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + } + goto unwind_done; } - if (log) + else { - log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); + if (log) + { + log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.", + cur_idx < 100 ? cur_idx : 100, "", cur_idx); + } } - goto unwind_done; } } if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc)) @@ -366,6 +384,14 @@ UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_privat UnwindLLDB::RegisterSearchResult result; result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc); + // We descended down to the live register context aka stack frame 0 and are reading the value + // out of a live register. + if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound + && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) + { + return true; + } + // If we have unwind instructions saying that register N is saved in register M in the middle of // the stack (and N can equal M here, meaning the register was not used in this function), then // change the register number we're looking for to M and keep looking for a concrete location diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h index eb54003..35d85e2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h @@ -48,7 +48,8 @@ protected: eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location) eRegisterInRegister, // register is available in a (possible other) register (register_number) eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space - eRegisterValueInferred // register val was computed (and is in inferred_value) + eRegisterValueInferred, // register val was computed (and is in inferred_value) + eRegisterInLiveRegisterContext // register value is in a live (stack frame #0) register }; int type; union diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h index c4706d5..99fca30 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -12,6 +12,7 @@ namespace lldb_private { + // LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) //--------------------------------------------------------------------------- // Internal codes for all i386 registers. @@ -19,100 +20,100 @@ namespace lldb_private enum { k_first_gpr_i386, - gpr_eax_i386 = k_first_gpr_i386, - gpr_ebx_i386, - gpr_ecx_i386, - gpr_edx_i386, - gpr_edi_i386, - gpr_esi_i386, - gpr_ebp_i386, - gpr_esp_i386, - gpr_eip_i386, - gpr_eflags_i386, - gpr_cs_i386, - gpr_fs_i386, - gpr_gs_i386, - gpr_ss_i386, - gpr_ds_i386, - gpr_es_i386, + lldb_eax_i386 = k_first_gpr_i386, + lldb_ebx_i386, + lldb_ecx_i386, + lldb_edx_i386, + lldb_edi_i386, + lldb_esi_i386, + lldb_ebp_i386, + lldb_esp_i386, + lldb_eip_i386, + lldb_eflags_i386, + lldb_cs_i386, + lldb_fs_i386, + lldb_gs_i386, + lldb_ss_i386, + lldb_ds_i386, + lldb_es_i386, k_first_alias_i386, - gpr_ax_i386 = k_first_alias_i386, - gpr_bx_i386, - gpr_cx_i386, - gpr_dx_i386, - gpr_di_i386, - gpr_si_i386, - gpr_bp_i386, - gpr_sp_i386, - gpr_ah_i386, - gpr_bh_i386, - gpr_ch_i386, - gpr_dh_i386, - gpr_al_i386, - gpr_bl_i386, - gpr_cl_i386, - gpr_dl_i386, - k_last_alias_i386 = gpr_dl_i386, + lldb_ax_i386 = k_first_alias_i386, + lldb_bx_i386, + lldb_cx_i386, + lldb_dx_i386, + lldb_di_i386, + lldb_si_i386, + lldb_bp_i386, + lldb_sp_i386, + lldb_ah_i386, + lldb_bh_i386, + lldb_ch_i386, + lldb_dh_i386, + lldb_al_i386, + lldb_bl_i386, + lldb_cl_i386, + lldb_dl_i386, + k_last_alias_i386 = lldb_dl_i386, k_last_gpr_i386 = k_last_alias_i386, k_first_fpr_i386, - fpu_fctrl_i386 = k_first_fpr_i386, - fpu_fstat_i386, - fpu_ftag_i386, - fpu_fop_i386, - fpu_fiseg_i386, - fpu_fioff_i386, - fpu_foseg_i386, - fpu_fooff_i386, - fpu_mxcsr_i386, - fpu_mxcsrmask_i386, - fpu_st0_i386, - fpu_st1_i386, - fpu_st2_i386, - fpu_st3_i386, - fpu_st4_i386, - fpu_st5_i386, - fpu_st6_i386, - fpu_st7_i386, - fpu_mm0_i386, - fpu_mm1_i386, - fpu_mm2_i386, - fpu_mm3_i386, - fpu_mm4_i386, - fpu_mm5_i386, - fpu_mm6_i386, - fpu_mm7_i386, - fpu_xmm0_i386, - fpu_xmm1_i386, - fpu_xmm2_i386, - fpu_xmm3_i386, - fpu_xmm4_i386, - fpu_xmm5_i386, - fpu_xmm6_i386, - fpu_xmm7_i386, - k_last_fpr_i386 = fpu_xmm7_i386, + lldb_fctrl_i386 = k_first_fpr_i386, + lldb_fstat_i386, + lldb_ftag_i386, + lldb_fop_i386, + lldb_fiseg_i386, + lldb_fioff_i386, + lldb_foseg_i386, + lldb_fooff_i386, + lldb_mxcsr_i386, + lldb_mxcsrmask_i386, + lldb_st0_i386, + lldb_st1_i386, + lldb_st2_i386, + lldb_st3_i386, + lldb_st4_i386, + lldb_st5_i386, + lldb_st6_i386, + lldb_st7_i386, + lldb_mm0_i386, + lldb_mm1_i386, + lldb_mm2_i386, + lldb_mm3_i386, + lldb_mm4_i386, + lldb_mm5_i386, + lldb_mm6_i386, + lldb_mm7_i386, + lldb_xmm0_i386, + lldb_xmm1_i386, + lldb_xmm2_i386, + lldb_xmm3_i386, + lldb_xmm4_i386, + lldb_xmm5_i386, + lldb_xmm6_i386, + lldb_xmm7_i386, + k_last_fpr_i386 = lldb_xmm7_i386, k_first_avx_i386, - fpu_ymm0_i386 = k_first_avx_i386, - fpu_ymm1_i386, - fpu_ymm2_i386, - fpu_ymm3_i386, - fpu_ymm4_i386, - fpu_ymm5_i386, - fpu_ymm6_i386, - fpu_ymm7_i386, - k_last_avx_i386 = fpu_ymm7_i386, + lldb_ymm0_i386 = k_first_avx_i386, + lldb_ymm1_i386, + lldb_ymm2_i386, + lldb_ymm3_i386, + lldb_ymm4_i386, + lldb_ymm5_i386, + lldb_ymm6_i386, + lldb_ymm7_i386, + k_last_avx_i386 = lldb_ymm7_i386, - dr0_i386, - dr1_i386, - dr2_i386, - dr3_i386, - dr4_i386, - dr5_i386, - dr6_i386, - dr7_i386, + lldb_dr0_i386, + lldb_dr1_i386, + lldb_dr2_i386, + lldb_dr3_i386, + lldb_dr4_i386, + lldb_dr5_i386, + lldb_dr6_i386, + lldb_dr7_i386, k_num_registers_i386, k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1, @@ -126,160 +127,160 @@ namespace lldb_private enum { k_first_gpr_x86_64, - gpr_rax_x86_64 = k_first_gpr_x86_64, - gpr_rbx_x86_64, - gpr_rcx_x86_64, - gpr_rdx_x86_64, - gpr_rdi_x86_64, - gpr_rsi_x86_64, - gpr_rbp_x86_64, - gpr_rsp_x86_64, - gpr_r8_x86_64, - gpr_r9_x86_64, - gpr_r10_x86_64, - gpr_r11_x86_64, - gpr_r12_x86_64, - gpr_r13_x86_64, - gpr_r14_x86_64, - gpr_r15_x86_64, - gpr_rip_x86_64, - gpr_rflags_x86_64, - gpr_cs_x86_64, - gpr_fs_x86_64, - gpr_gs_x86_64, - gpr_ss_x86_64, - gpr_ds_x86_64, - gpr_es_x86_64, + lldb_rax_x86_64 = k_first_gpr_x86_64, + lldb_rbx_x86_64, + lldb_rcx_x86_64, + lldb_rdx_x86_64, + lldb_rdi_x86_64, + lldb_rsi_x86_64, + lldb_rbp_x86_64, + lldb_rsp_x86_64, + lldb_r8_x86_64, + lldb_r9_x86_64, + lldb_r10_x86_64, + lldb_r11_x86_64, + lldb_r12_x86_64, + lldb_r13_x86_64, + lldb_r14_x86_64, + lldb_r15_x86_64, + lldb_rip_x86_64, + lldb_rflags_x86_64, + lldb_cs_x86_64, + lldb_fs_x86_64, + lldb_gs_x86_64, + lldb_ss_x86_64, + lldb_ds_x86_64, + lldb_es_x86_64, k_first_alias_x86_64, - gpr_eax_x86_64 = k_first_alias_x86_64, - gpr_ebx_x86_64, - gpr_ecx_x86_64, - gpr_edx_x86_64, - gpr_edi_x86_64, - gpr_esi_x86_64, - gpr_ebp_x86_64, - gpr_esp_x86_64, - gpr_r8d_x86_64, // Low 32 bits of r8 - gpr_r9d_x86_64, // Low 32 bits of r9 - gpr_r10d_x86_64, // Low 32 bits of r10 - gpr_r11d_x86_64, // Low 32 bits of r11 - gpr_r12d_x86_64, // Low 32 bits of r12 - gpr_r13d_x86_64, // Low 32 bits of r13 - gpr_r14d_x86_64, // Low 32 bits of r14 - gpr_r15d_x86_64, // Low 32 bits of r15 - gpr_ax_x86_64, - gpr_bx_x86_64, - gpr_cx_x86_64, - gpr_dx_x86_64, - gpr_di_x86_64, - gpr_si_x86_64, - gpr_bp_x86_64, - gpr_sp_x86_64, - gpr_r8w_x86_64, // Low 16 bits of r8 - gpr_r9w_x86_64, // Low 16 bits of r9 - gpr_r10w_x86_64, // Low 16 bits of r10 - gpr_r11w_x86_64, // Low 16 bits of r11 - gpr_r12w_x86_64, // Low 16 bits of r12 - gpr_r13w_x86_64, // Low 16 bits of r13 - gpr_r14w_x86_64, // Low 16 bits of r14 - gpr_r15w_x86_64, // Low 16 bits of r15 - gpr_ah_x86_64, - gpr_bh_x86_64, - gpr_ch_x86_64, - gpr_dh_x86_64, - gpr_al_x86_64, - gpr_bl_x86_64, - gpr_cl_x86_64, - gpr_dl_x86_64, - gpr_dil_x86_64, - gpr_sil_x86_64, - gpr_bpl_x86_64, - gpr_spl_x86_64, - gpr_r8l_x86_64, // Low 8 bits of r8 - gpr_r9l_x86_64, // Low 8 bits of r9 - gpr_r10l_x86_64, // Low 8 bits of r10 - gpr_r11l_x86_64, // Low 8 bits of r11 - gpr_r12l_x86_64, // Low 8 bits of r12 - gpr_r13l_x86_64, // Low 8 bits of r13 - gpr_r14l_x86_64, // Low 8 bits of r14 - gpr_r15l_x86_64, // Low 8 bits of r15 - k_last_alias_x86_64 = gpr_r15l_x86_64, + lldb_eax_x86_64 = k_first_alias_x86_64, + lldb_ebx_x86_64, + lldb_ecx_x86_64, + lldb_edx_x86_64, + lldb_edi_x86_64, + lldb_esi_x86_64, + lldb_ebp_x86_64, + lldb_esp_x86_64, + lldb_r8d_x86_64, // Low 32 bits of r8 + lldb_r9d_x86_64, // Low 32 bits of r9 + lldb_r10d_x86_64, // Low 32 bits of r10 + lldb_r11d_x86_64, // Low 32 bits of r11 + lldb_r12d_x86_64, // Low 32 bits of r12 + lldb_r13d_x86_64, // Low 32 bits of r13 + lldb_r14d_x86_64, // Low 32 bits of r14 + lldb_r15d_x86_64, // Low 32 bits of r15 + lldb_ax_x86_64, + lldb_bx_x86_64, + lldb_cx_x86_64, + lldb_dx_x86_64, + lldb_di_x86_64, + lldb_si_x86_64, + lldb_bp_x86_64, + lldb_sp_x86_64, + lldb_r8w_x86_64, // Low 16 bits of r8 + lldb_r9w_x86_64, // Low 16 bits of r9 + lldb_r10w_x86_64, // Low 16 bits of r10 + lldb_r11w_x86_64, // Low 16 bits of r11 + lldb_r12w_x86_64, // Low 16 bits of r12 + lldb_r13w_x86_64, // Low 16 bits of r13 + lldb_r14w_x86_64, // Low 16 bits of r14 + lldb_r15w_x86_64, // Low 16 bits of r15 + lldb_ah_x86_64, + lldb_bh_x86_64, + lldb_ch_x86_64, + lldb_dh_x86_64, + lldb_al_x86_64, + lldb_bl_x86_64, + lldb_cl_x86_64, + lldb_dl_x86_64, + lldb_dil_x86_64, + lldb_sil_x86_64, + lldb_bpl_x86_64, + lldb_spl_x86_64, + lldb_r8l_x86_64, // Low 8 bits of r8 + lldb_r9l_x86_64, // Low 8 bits of r9 + lldb_r10l_x86_64, // Low 8 bits of r10 + lldb_r11l_x86_64, // Low 8 bits of r11 + lldb_r12l_x86_64, // Low 8 bits of r12 + lldb_r13l_x86_64, // Low 8 bits of r13 + lldb_r14l_x86_64, // Low 8 bits of r14 + lldb_r15l_x86_64, // Low 8 bits of r15 + k_last_alias_x86_64 = lldb_r15l_x86_64, k_last_gpr_x86_64 = k_last_alias_x86_64, k_first_fpr_x86_64, - fpu_fctrl_x86_64 = k_first_fpr_x86_64, - fpu_fstat_x86_64, - fpu_ftag_x86_64, - fpu_fop_x86_64, - fpu_fiseg_x86_64, - fpu_fioff_x86_64, - fpu_foseg_x86_64, - fpu_fooff_x86_64, - fpu_mxcsr_x86_64, - fpu_mxcsrmask_x86_64, - fpu_st0_x86_64, - fpu_st1_x86_64, - fpu_st2_x86_64, - fpu_st3_x86_64, - fpu_st4_x86_64, - fpu_st5_x86_64, - fpu_st6_x86_64, - fpu_st7_x86_64, - fpu_mm0_x86_64, - fpu_mm1_x86_64, - fpu_mm2_x86_64, - fpu_mm3_x86_64, - fpu_mm4_x86_64, - fpu_mm5_x86_64, - fpu_mm6_x86_64, - fpu_mm7_x86_64, - fpu_xmm0_x86_64, - fpu_xmm1_x86_64, - fpu_xmm2_x86_64, - fpu_xmm3_x86_64, - fpu_xmm4_x86_64, - fpu_xmm5_x86_64, - fpu_xmm6_x86_64, - fpu_xmm7_x86_64, - fpu_xmm8_x86_64, - fpu_xmm9_x86_64, - fpu_xmm10_x86_64, - fpu_xmm11_x86_64, - fpu_xmm12_x86_64, - fpu_xmm13_x86_64, - fpu_xmm14_x86_64, - fpu_xmm15_x86_64, - k_last_fpr_x86_64 = fpu_xmm15_x86_64, + lldb_fctrl_x86_64 = k_first_fpr_x86_64, + lldb_fstat_x86_64, + lldb_ftag_x86_64, + lldb_fop_x86_64, + lldb_fiseg_x86_64, + lldb_fioff_x86_64, + lldb_foseg_x86_64, + lldb_fooff_x86_64, + lldb_mxcsr_x86_64, + lldb_mxcsrmask_x86_64, + lldb_st0_x86_64, + lldb_st1_x86_64, + lldb_st2_x86_64, + lldb_st3_x86_64, + lldb_st4_x86_64, + lldb_st5_x86_64, + lldb_st6_x86_64, + lldb_st7_x86_64, + lldb_mm0_x86_64, + lldb_mm1_x86_64, + lldb_mm2_x86_64, + lldb_mm3_x86_64, + lldb_mm4_x86_64, + lldb_mm5_x86_64, + lldb_mm6_x86_64, + lldb_mm7_x86_64, + lldb_xmm0_x86_64, + lldb_xmm1_x86_64, + lldb_xmm2_x86_64, + lldb_xmm3_x86_64, + lldb_xmm4_x86_64, + lldb_xmm5_x86_64, + lldb_xmm6_x86_64, + lldb_xmm7_x86_64, + lldb_xmm8_x86_64, + lldb_xmm9_x86_64, + lldb_xmm10_x86_64, + lldb_xmm11_x86_64, + lldb_xmm12_x86_64, + lldb_xmm13_x86_64, + lldb_xmm14_x86_64, + lldb_xmm15_x86_64, + k_last_fpr_x86_64 = lldb_xmm15_x86_64, k_first_avx_x86_64, - fpu_ymm0_x86_64 = k_first_avx_x86_64, - fpu_ymm1_x86_64, - fpu_ymm2_x86_64, - fpu_ymm3_x86_64, - fpu_ymm4_x86_64, - fpu_ymm5_x86_64, - fpu_ymm6_x86_64, - fpu_ymm7_x86_64, - fpu_ymm8_x86_64, - fpu_ymm9_x86_64, - fpu_ymm10_x86_64, - fpu_ymm11_x86_64, - fpu_ymm12_x86_64, - fpu_ymm13_x86_64, - fpu_ymm14_x86_64, - fpu_ymm15_x86_64, - k_last_avx_x86_64 = fpu_ymm15_x86_64, + lldb_ymm0_x86_64 = k_first_avx_x86_64, + lldb_ymm1_x86_64, + lldb_ymm2_x86_64, + lldb_ymm3_x86_64, + lldb_ymm4_x86_64, + lldb_ymm5_x86_64, + lldb_ymm6_x86_64, + lldb_ymm7_x86_64, + lldb_ymm8_x86_64, + lldb_ymm9_x86_64, + lldb_ymm10_x86_64, + lldb_ymm11_x86_64, + lldb_ymm12_x86_64, + lldb_ymm13_x86_64, + lldb_ymm14_x86_64, + lldb_ymm15_x86_64, + k_last_avx_x86_64 = lldb_ymm15_x86_64, - dr0_x86_64, - dr1_x86_64, - dr2_x86_64, - dr3_x86_64, - dr4_x86_64, - dr5_x86_64, - dr6_x86_64, - dr7_x86_64, + lldb_dr0_x86_64, + lldb_dr1_x86_64, + lldb_dr2_x86_64, + lldb_dr3_x86_64, + lldb_dr4_x86_64, + lldb_dr5_x86_64, + lldb_dr6_x86_64, + lldb_dr7_x86_64, k_num_registers_x86_64, k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1, diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 5668167..fb39d73 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -405,14 +405,18 @@ enum { NT_AUXV }; +namespace FREEBSD { + enum { - NT_FREEBSD_PRSTATUS = 1, - NT_FREEBSD_FPREGSET, - NT_FREEBSD_PRPSINFO, - NT_FREEBSD_THRMISC = 7, - NT_FREEBSD_PROCSTAT_AUXV = 16 + NT_PRSTATUS = 1, + NT_FPREGSET, + NT_PRPSINFO, + NT_THRMISC = 7, + NT_PROCSTAT_AUXV = 16 }; +} + // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details. static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, @@ -420,6 +424,7 @@ ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data, { lldb::offset_t offset = 0; bool lp64 = (arch.GetMachine() == llvm::Triple::mips64 || + arch.GetMachine() == llvm::Triple::ppc64 || arch.GetMachine() == llvm::Triple::x86_64); int pr_version = data.GetU32(&offset); @@ -516,20 +521,20 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader * m_os = llvm::Triple::FreeBSD; switch (note.n_type) { - case NT_FREEBSD_PRSTATUS: + case FREEBSD::NT_PRSTATUS: have_prstatus = true; ParseFreeBSDPrStatus(*thread_data, note_data, arch); break; - case NT_FREEBSD_FPREGSET: + case FREEBSD::NT_FPREGSET: thread_data->fpregset = note_data; break; - case NT_FREEBSD_PRPSINFO: + case FREEBSD::NT_PRPSINFO: have_prpsinfo = true; break; - case NT_FREEBSD_THRMISC: + case FREEBSD::NT_THRMISC: ParseFreeBSDThrMisc(*thread_data, note_data); break; - case NT_FREEBSD_PROCSTAT_AUXV: + 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; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 2fc2e4e..7988bee 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -68,52 +68,52 @@ public: //------------------------------------------------------------------ virtual bool CanDebug (lldb_private::Target &target, - bool plugin_specified_by_name); + bool plugin_specified_by_name) override; //------------------------------------------------------------------ // Creating a new process, or attaching to an existing one //------------------------------------------------------------------ virtual lldb_private::Error - DoLoadCore (); + DoLoadCore () override; virtual lldb_private::DynamicLoader * - GetDynamicLoader (); + GetDynamicLoader () override; //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ virtual lldb_private::ConstString - GetPluginName(); + GetPluginName() override; virtual uint32_t - GetPluginVersion(); + GetPluginVersion() override; //------------------------------------------------------------------ // Process Control //------------------------------------------------------------------ virtual lldb_private::Error - DoDestroy (); + DoDestroy () override; virtual void - RefreshStateAfterStop(); + RefreshStateAfterStop() override; //------------------------------------------------------------------ // Process Queries //------------------------------------------------------------------ virtual bool - IsAlive (); + IsAlive () override; //------------------------------------------------------------------ // Process Memory //------------------------------------------------------------------ virtual size_t - ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); + ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override; virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); + DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override; virtual lldb::addr_t - GetImageInfoAddress (); + GetImageInfoAddress () override; lldb_private::ArchSpec GetArchitecture(); @@ -128,7 +128,7 @@ protected: virtual bool UpdateThreadList (lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); + lldb_private::ThreadList &new_thread_list) override; private: //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index fbf397b..f0750a0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -10,7 +10,7 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" -#include "RegisterContextPOSIX.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX.h" #include "RegisterContextPOSIXCore_mips64.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp new file mode 100644 index 0000000..15b1b44 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -0,0 +1,109 @@ +//===-- RegisterContextCorePOSIX_powerpc.cpp ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Target/Thread.h" +#include "RegisterContextPOSIX.h" +#include "RegisterContextPOSIXCore_powerpc.h" + +using namespace lldb_private; + +RegisterContextCorePOSIX_powerpc::RegisterContextCorePOSIX_powerpc(Thread &thread, + RegisterInfoInterface *register_info, + const DataExtractor &gpregset, + const DataExtractor &fpregset) + : 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()); + m_fpr_buffer.reset(new DataBufferHeap(fpregset.GetDataStart(), fpregset.GetByteSize())); + m_fpr.SetData(m_fpr_buffer); + m_fpr.SetByteOrder(fpregset.GetByteOrder()); +} + +RegisterContextCorePOSIX_powerpc::~RegisterContextCorePOSIX_powerpc() +{ +} + +bool +RegisterContextCorePOSIX_powerpc::ReadGPR() +{ + return true; +} + +bool +RegisterContextCorePOSIX_powerpc::ReadFPR() +{ + return true; +} + +bool +RegisterContextCorePOSIX_powerpc::WriteGPR() +{ + assert(0); + return false; +} + +bool +RegisterContextCorePOSIX_powerpc::WriteFPR() +{ + assert(0); + return false; +} + +bool +RegisterContextCorePOSIX_powerpc::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) +{ + lldb::offset_t offset = reg_info->byte_offset; + if (reg_info->name[0] == 'f') { + uint64_t v = m_fpr.GetMaxU64(&offset, reg_info->byte_size); + if (offset == reg_info->byte_offset + reg_info->byte_size) + { + value = v; + 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_powerpc::ReadAllRegisterValues(lldb::DataBufferSP &data_sp) +{ + return false; +} + +bool +RegisterContextCorePOSIX_powerpc::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) +{ + return false; +} + +bool +RegisterContextCorePOSIX_powerpc::WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) +{ + return false; +} + +bool +RegisterContextCorePOSIX_powerpc::HardwareSingleStep(bool enable) +{ + return false; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h new file mode 100644 index 0000000..e657558 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.h @@ -0,0 +1,62 @@ +//===-- RegisterContextCorePOSIX_powerpc.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_powerpc_H_ +#define liblldb_RegisterContextCorePOSIX_powerpc_H_ + +#include "lldb/Core/DataBufferHeap.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h" + +class RegisterContextCorePOSIX_powerpc : + public RegisterContextPOSIX_powerpc +{ +public: + RegisterContextCorePOSIX_powerpc (lldb_private::Thread &thread, + lldb_private::RegisterInfoInterface *register_info, + const lldb_private::DataExtractor &gpregset, + const lldb_private::DataExtractor &fpregset); + + ~RegisterContextCorePOSIX_powerpc(); + + virtual bool + ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); + + virtual bool + WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); + + bool + ReadAllRegisterValues(lldb::DataBufferSP &data_sp); + + bool + WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); + + bool + HardwareSingleStep(bool enable); + +protected: + bool + ReadGPR(); + + bool + ReadFPR(); + + bool + WriteGPR(); + + bool + WriteFPR(); + +private: + lldb::DataBufferSP m_gpr_buffer; + lldb::DataBufferSP m_fpr_buffer; + lldb_private::DataExtractor m_gpr; + lldb_private::DataExtractor m_fpr; +}; + +#endif // #ifndef liblldb_RegisterContextCorePOSIX_powerpc_H_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index 3e09c7b..412c7ad 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -10,7 +10,7 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" -#include "RegisterContextPOSIX.h" +#include "Plugins/Process/Utility/RegisterContextPOSIX.h" #include "RegisterContextPOSIXCore_x86_64.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index d9f6cc0..d62bcfc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -16,11 +16,13 @@ #include "ThreadElfCore.h" #include "ProcessElfCore.h" -#include "RegisterContextLinux_x86_64.h" -#include "RegisterContextFreeBSD_i386.h" -#include "RegisterContextFreeBSD_mips64.h" -#include "RegisterContextFreeBSD_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" +#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" +#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" +#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" +#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" #include "RegisterContextPOSIXCore_mips64.h" +#include "RegisterContextPOSIXCore_powerpc.h" #include "RegisterContextPOSIXCore_x86_64.h" using namespace lldb; @@ -94,6 +96,12 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) { switch (arch.GetMachine()) { + case llvm::Triple::ppc: + reg_interface = new RegisterContextFreeBSD_powerpc32(arch); + break; + case llvm::Triple::ppc64: + reg_interface = new RegisterContextFreeBSD_powerpc64(arch); + break; case llvm::Triple::mips64: reg_interface = new RegisterContextFreeBSD_mips64(arch); break; @@ -138,6 +146,10 @@ ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame) case llvm::Triple::mips64: m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data)); 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)); + 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)); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 1f4dd93..919fa54 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -17,15 +17,16 @@ // C++ Includes // Other libraries and framework includes -#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Log.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" +#include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/TimeValue.h" #include "lldb/Target/Process.h" @@ -153,7 +154,6 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, m_history (512), m_send_acks (true), m_is_platform (is_platform), - m_listen_thread (LLDB_INVALID_HOST_THREAD), m_listen_url () { } @@ -227,9 +227,23 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); ConnectionStatus status = eConnectionStatusSuccess; - size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); + const char *packet_data = packet.GetData(); + const size_t packet_length = packet.GetSize(); + size_t bytes_written = Write (packet_data, packet_length, status, NULL); if (log) { + size_t binary_start_offset = 0; + if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == 0) + { + const char *first_comma = strchr(packet_data, ','); + if (first_comma) + { + const char *second_comma = strchr(first_comma + 1, ','); + if (second_comma) + binary_start_offset = second_comma - packet_data + 1; + } + } + // If logging was just enabled and we have history, then dump out what // we have to the log so we get the historical context. The Dump() call that // logs all of the packet will set a boolean so that we don't dump this more @@ -237,13 +251,27 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le if (!m_history.DidDumpToLog ()) m_history.Dump (log); - log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet.GetSize(), packet.GetData()); + if (binary_start_offset) + { + StreamString strm; + // Print non binary data header + strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)binary_start_offset, packet_data); + const uint8_t *p; + // Print binary data exactly as sent + for (p = (uint8_t*)packet_data + binary_start_offset; *p != '#'; ++p) + strm.Printf("\\x%2.2x", *p); + // Print the checksum + strm.Printf("%*s", (int)3, p); + log->PutCString(strm.GetString().c_str()); + } + else + log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet_length, packet_data); } - m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written); + m_history.AddPacket (packet.GetString(), packet_length, History::ePacketTypeSend, bytes_written); - if (bytes_written == packet.GetSize()) + if (bytes_written == packet_length) { if (GetSendAcks ()) return GetAck (); @@ -253,7 +281,7 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le else { if (log) - log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData()); + log->Printf ("error: failed to send packet: %.*s", (int)packet_length, packet_data); } } return PacketResult::ErrorSendFailed; @@ -447,8 +475,8 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri } if (log) log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", - __FUNCTION__, idx, idx, m_bytes.c_str()); - m_bytes.erase(0, idx); + __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str()); + m_bytes.erase(0, idx - 1); } break; } @@ -606,7 +634,7 @@ Error GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) { Error error; - if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread)) + if (m_listen_thread.IsJoinable()) { error.SetErrorString("listen thread already running"); } @@ -619,7 +647,7 @@ GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) snprintf(listen_url, sizeof(listen_url), "listen://%i", port); m_listen_url = listen_url; SetConnection(new ConnectionFileDescriptor()); - m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error); + m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error); } return error; } @@ -627,11 +655,8 @@ GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port) bool GDBRemoteCommunication::JoinListenThread () { - if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread)) - { - Host::ThreadJoin(m_listen_thread, NULL, NULL); - m_listen_thread = LLDB_INVALID_HOST_THREAD; - } + if (m_listen_thread.IsJoinable()) + m_listen_thread.Join(nullptr); return true; } @@ -738,6 +763,7 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, char named_pipe_path[PATH_MAX]; named_pipe_path[0] = '\0'; + Pipe port_named_pipe; bool listen = false; if (host_and_port[0]) @@ -763,15 +789,11 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, if (::mktemp (named_pipe_path)) { -#if defined(_WIN32) - if ( false ) -#else - if (::mkfifo(named_pipe_path, 0600) == 0) -#endif - { - debugserver_args.AppendArgument("--named-pipe"); - debugserver_args.AppendArgument(named_pipe_path); - } + error = port_named_pipe.CreateNew(named_pipe_path, false); + if (error.Fail()) + return error; + debugserver_args.AppendArgument("--named-pipe"); + debugserver_args.AppendArgument(named_pipe_path); } } else @@ -838,11 +860,15 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, } } while (has_env_var); - // Close STDIN, STDOUT and STDERR. We might need to redirect them - // to "/dev/null" if we run into any problems. + // Close STDIN, STDOUT and STDERR. launch_info.AppendCloseFileAction (STDIN_FILENO); launch_info.AppendCloseFileAction (STDOUT_FILENO); launch_info.AppendCloseFileAction (STDERR_FILENO); + + // Redirect STDIN, STDOUT and STDERR to "/dev/null". + launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false); + launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true); + launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true); error = Host::LaunchProcess(launch_info); @@ -850,20 +876,40 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *hostname, { if (named_pipe_path[0]) { - File name_pipe_file; - error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead); + error = port_named_pipe.OpenAsReader(named_pipe_path, false); if (error.Success()) { char port_cstr[256]; port_cstr[0] = '\0'; size_t num_bytes = sizeof(port_cstr); - error = name_pipe_file.Read(port_cstr, num_bytes); - assert (error.Success()); - assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0'); - out_port = Args::StringToUInt32(port_cstr, 0); - name_pipe_file.Close(); + // Read port from pipe with 10 second timeout. + error = port_named_pipe.ReadWithTimeout(port_cstr, num_bytes, std::chrono::microseconds(10 * 1000000), num_bytes); + if (error.Success()) + { + assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0'); + out_port = Args::StringToUInt32(port_cstr, 0); + if (log) + log->Printf("GDBRemoteCommunication::%s() debugserver listens %u port", __FUNCTION__, out_port); + } + else + { + if (log) + log->Printf("GDBRemoteCommunication::%s() failed to read a port value from named pipe %s: %s", __FUNCTION__, named_pipe_path, error.AsCString()); + + } + port_named_pipe.Close(); + } + else + { + if (log) + log->Printf("GDBRemoteCommunication::%s() failed to open named pipe %s for reading: %s", __FUNCTION__, named_pipe_path, error.AsCString()); + } + const auto err = port_named_pipe.Delete(named_pipe_path); + if (err.Fail()) + { + if (log) + log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s", __FUNCTION__, named_pipe_path, err.AsCString()); } - FileSystem::Unlink(named_pipe_path); } else if (listen) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index b11d385..ac203a6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -20,6 +20,7 @@ #include "lldb/lldb-public.h" #include "lldb/Core/Communication.h" #include "lldb/Core/Listener.h" +#include "lldb/Host/HostThread.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/Predicate.h" #include "lldb/Host/TimeValue.h" @@ -281,8 +282,7 @@ protected: ListenThread (lldb::thread_arg_t arg); private: - - lldb::thread_t m_listen_thread; + lldb_private::HostThread m_listen_thread; std::string m_listen_url; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index 5e4ed76..52750de 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -20,11 +20,11 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "lldb/Interpreter/Args.h" -#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Log.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamGDBRemote.h" #include "lldb/Core/StreamString.h" +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Endian.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" @@ -1643,7 +1643,9 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force) } else if (name.compare("triple") == 0) { - triple.swap(value); + extractor.GetStringRef ().swap (value); + extractor.SetFilePos(0); + extractor.GetHexByteString (triple); ++num_keys_decoded; } else if (name.compare ("distribution_id") == 0) @@ -2331,6 +2333,10 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot } else if (name.compare("triple") == 0) { + StringExtractor extractor; + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString (value); process_info.GetArchitecture ().SetTriple (value.c_str()); } else if (name.compare("name") == 0) @@ -2404,6 +2410,8 @@ GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceIn bool GDBRemoteCommunicationClient::GetCurrentProcessInfo () { + Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); + if (m_qProcessInfo_is_valid == eLazyBoolYes) return true; if (m_qProcessInfo_is_valid == eLazyBoolNo) @@ -2426,6 +2434,7 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo () std::string triple; uint32_t pointer_byte_size = 0; StringExtractor extractor; + ByteOrder byte_order = eByteOrderInvalid; uint32_t num_keys_decoded = 0; lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; while (response.GetNameColonValue(name, value)) @@ -2444,7 +2453,10 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo () } else if (name.compare("triple") == 0) { - triple = value; + StringExtractor extractor; + extractor.GetStringRef().swap(value); + extractor.SetFilePos(0); + extractor.GetHexByteString (triple); ++num_keys_decoded; } else if (name.compare("ostype") == 0) @@ -2459,10 +2471,15 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo () } else if (name.compare("endian") == 0) { - if (value.compare("little") == 0 || - value.compare("big") == 0 || - value.compare("pdp") == 0) - ++num_keys_decoded; + ++num_keys_decoded; + if (value.compare("little") == 0) + byte_order = eByteOrderLittle; + else if (value.compare("big") == 0) + byte_order = eByteOrderBig; + else if (value.compare("pdp") == 0) + byte_order = eByteOrderPDP; + else + --num_keys_decoded; } else if (name.compare("ptrsize") == 0) { @@ -2496,11 +2513,34 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo () } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty()) { - m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub); + llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name); + + assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat); + switch (triple.getObjectFormat()) { + case llvm::Triple::MachO: + m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub); + break; + case llvm::Triple::ELF: + m_process_arch.SetArchitecture (eArchTypeELF, cpu, sub); + break; + case llvm::Triple::COFF: + m_process_arch.SetArchitecture (eArchTypeCOFF, cpu, sub); + break; + case llvm::Triple::UnknownObjectFormat: + if (log) + log->Printf("error: failed to determine target architecture"); + return false; + } + if (pointer_byte_size) { assert (pointer_byte_size == m_process_arch.GetAddressByteSize()); } + if (byte_order != eByteOrderInvalid) + { + assert (byte_order == m_process_arch.GetByteOrder()); + } + m_process_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); m_process_arch.GetTriple().setOSName(llvm::StringRef (os_name)); m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name)); @@ -2931,6 +2971,11 @@ GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtracto uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length) { + Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); + if (log) + log->Printf ("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64, + __FUNCTION__, insert ? "add" : "remove", addr); + // Check if the stub is known not to support this breakpoint type if (!SupportsGDBStoppointPacket(type)) return UINT8_MAX; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index ffcdd16..a714950 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -23,11 +23,11 @@ // Other libraries and framework includes #include "llvm/ADT/Triple.h" #include "lldb/Interpreter/Args.h" -#include "lldb/Core/ConnectionFileDescriptor.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Log.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamString.h" +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Debug.h" #include "lldb/Host/Endian.h" #include "lldb/Host/File.h" @@ -71,7 +71,7 @@ namespace //---------------------------------------------------------------------- GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), - m_platform_sp (Platform::GetDefaultPlatform ()), + m_platform_sp (Platform::GetHostPlatform ()), m_async_thread (LLDB_INVALID_HOST_THREAD), m_process_launch_info (), m_process_launch_error (), @@ -429,6 +429,14 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, case StringExtractorGDBRemote::eServerPacketType_vAttach: packet_result = Handle_vAttach (packet); break; + + case StringExtractorGDBRemote::eServerPacketType_D: + packet_result = Handle_D (packet); + break; + + case StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo: + packet_result = Handle_qThreadStopInfo (packet); + break; } } else @@ -474,13 +482,34 @@ GDBRemoteCommunicationServer::LaunchProcess () // FIXME This looks an awful lot like we could override this in // derived classes, one for lldb-platform, the other for lldb-gdbserver. if (IsGdbServer ()) - return LaunchDebugServerProcess (); + return LaunchProcessForDebugging (); else return LaunchPlatformProcess (); } +bool +GDBRemoteCommunicationServer::ShouldRedirectInferiorOutputOverGdbRemote (const lldb_private::ProcessLaunchInfo &launch_info) const +{ + // Retrieve the file actions specified for stdout and stderr. + auto stdout_file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); + auto stderr_file_action = launch_info.GetFileActionForFD (STDERR_FILENO); + + // If neither stdout and stderr file actions are specified, we're not doing anything special, so + // assume we want to redirect stdout/stderr over gdb-remote $O messages. + if ((stdout_file_action == nullptr) && (stderr_file_action == nullptr)) + { + // Send stdout/stderr over the gdb-remote protocol. + return true; + } + + // Any other setting for either stdout or stderr implies we are either suppressing + // it (with /dev/null) or we've got it set to a PTY. Either way, we don't want the + // output over gdb-remote. + return false; +} + lldb_private::Error -GDBRemoteCommunicationServer::LaunchDebugServerProcess () +GDBRemoteCommunicationServer::LaunchProcessForDebugging () { Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); @@ -503,20 +532,34 @@ GDBRemoteCommunicationServer::LaunchDebugServerProcess () return error; } - // Setup stdout/stderr mapping from inferior. - auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor (); - if (terminal_fd >= 0) + // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as needed. + // llgs local-process debugging may specify PTYs, which will eliminate the need to reflect inferior + // stdout/stderr over the gdb-remote protocol. + if (ShouldRedirectInferiorOutputOverGdbRemote (m_process_launch_info)) { if (log) - log->Printf ("ProcessGDBRemoteCommunicationServer::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd); - error = SetSTDIOFileDescriptor (terminal_fd); - if (error.Fail ()) - return error; + log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " setting up stdout/stderr redirection via $O gdb-remote commands", __FUNCTION__, m_debugged_process_sp->GetID ()); + + // Setup stdout/stderr mapping from inferior to $O + auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor (); + if (terminal_fd >= 0) + { + if (log) + log->Printf ("ProcessGDBRemoteCommunicationServer::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd); + error = SetSTDIOFileDescriptor (terminal_fd); + if (error.Fail ()) + return error; + } + else + { + if (log) + log->Printf ("ProcessGDBRemoteCommunicationServer::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd); + } } else { if (log) - log->Printf ("ProcessGDBRemoteCommunicationServer::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd); + log->Printf ("GDBRemoteCommunicationServer::%s pid %" PRIu64 " skipping stdout/stderr redirection via $O: inferior will communicate over client-provided file descriptors", __FUNCTION__, m_debugged_process_sp->GetID ()); } printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ()); @@ -526,33 +569,10 @@ GDBRemoteCommunicationServer::LaunchDebugServerProcess () if ((pid = m_process_launch_info.GetProcessID ()) != LLDB_INVALID_PROCESS_ID) { // add to spawned pids - { - Mutex::Locker locker (m_spawned_pids_mutex); - // On an lldb-gdbserver, we would expect there to be only one. - assert (m_spawned_pids.empty () && "lldb-gdbserver adding tracked process but one already existed"); - m_spawned_pids.insert (pid); - } - } - - if (error.Success ()) - { - if (log) - log->Printf ("GDBRemoteCommunicationServer::%s beginning check to wait for launched application to hit first stop", __FUNCTION__); - - int iteration = 0; - // Wait for the process to hit its first stop state. - while (!StateIsStoppedState (m_debugged_process_sp->GetState (), false)) - { - if (log) - log->Printf ("GDBRemoteCommunicationServer::%s waiting for launched process to hit first stop (%d)...", __FUNCTION__, iteration++); - - // FIXME use a finer granularity. - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - - if (log) - log->Printf ("GDBRemoteCommunicationServer::%s launched application has hit first stop", __FUNCTION__); - + Mutex::Locker locker (m_spawned_pids_mutex); + // On an lldb-gdbserver, we would expect there to be only one. + assert (m_spawned_pids.empty () && "lldb-gdbserver adding tracked process but one already existed"); + m_spawned_pids.insert (pid); } return error; @@ -699,12 +719,18 @@ GDBRemoteCommunicationServer::SendWResponse (lldb_private::NativeProcessProtocol char return_type_code; switch (exit_type) { - case ExitType::eExitTypeExit: return_type_code = 'W'; break; - case ExitType::eExitTypeSignal: return_type_code = 'X'; break; - case ExitType::eExitTypeStop: return_type_code = 'S'; break; - + case ExitType::eExitTypeExit: + return_type_code = 'W'; + break; + case ExitType::eExitTypeSignal: + return_type_code = 'X'; + break; + case ExitType::eExitTypeStop: + return_type_code = 'S'; + break; case ExitType::eExitTypeInvalid: - default: return_type_code = 'E'; break; + return_type_code = 'E'; + break; } response.PutChar (return_type_code); @@ -861,21 +887,21 @@ GDBRemoteCommunicationServer::SendStopReplyPacketForThread (lldb::tid_t tid) response.Printf ("thread:%" PRIx64 ";", tid); // Include the thread name if there is one. - const char *thread_name = thread_sp->GetName (); - if (thread_name && thread_name[0]) + const std::string thread_name = thread_sp->GetName (); + if (!thread_name.empty ()) { - size_t thread_name_len = strlen(thread_name); + size_t thread_name_len = thread_name.length (); - if (::strcspn (thread_name, "$#+-;:") == thread_name_len) + if (::strcspn (thread_name.c_str (), "$#+-;:") == thread_name_len) { response.PutCString ("name:"); - response.PutCString (thread_name); + response.PutCString (thread_name.c_str ()); } else { // The thread name contains special chars, send as hex bytes. response.PutCString ("hexname:"); - response.PutCStringAsRawHex8 (thread_name); + response.PutCStringAsRawHex8 (thread_name.c_str ()); } response.PutChar (';'); } @@ -1197,7 +1223,7 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet ArchSpec host_arch(HostInfo::GetArchitecture()); const llvm::Triple &host_triple = host_arch.GetTriple(); response.PutCString("triple:"); - response.PutCString(host_triple.getTriple().c_str()); + response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); const char* distribution_id = host_arch.GetDistributionId ().AsCString (); @@ -1252,7 +1278,6 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet } std::string s; -#if !defined(__linux__) if (HostInfo::GetOSBuildString(s)) { response.PutCString ("os_build:"); @@ -1265,7 +1290,6 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet response.PutCStringAsRawHex8(s.c_str()); response.PutChar(';'); } -#endif #if defined(__APPLE__) @@ -1315,7 +1339,7 @@ CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &r { const llvm::Triple &proc_triple = proc_arch.GetTriple(); response.PutCString("triple:"); - response.PutCString(proc_triple.getTriple().c_str()); + response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); response.PutChar(';'); } } @@ -1351,7 +1375,10 @@ CreateProcessInfoResponse_DebugServerStyle (const ProcessInstanceInfo &proc_info response.Printf ("vendor:%s;", vendor.c_str ()); #else // We'll send the triple. - response.Printf ("triple:%s;", proc_triple.getTriple().c_str ()); + response.PutCString("triple:"); + response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); + response.PutChar(';'); + #endif std::string ostype = proc_triple.getOSName (); // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. @@ -2372,8 +2399,6 @@ GDBRemoteCommunicationServer::Handle_vCont_actions (StringExtractorGDBRemote &pa return SendUnimplementedResponse (packet.GetStringRef().c_str()); } - // We handle $vCont messages for c. - // TODO add C, s and S. StreamString response; response.Printf("vCont;c;C;s;S"); @@ -3388,10 +3413,8 @@ GDBRemoteCommunicationServer::Handle_interrupt (StringExtractorGDBRemote &packet return SendErrorResponse (0x15); } - // Build the ResumeActionList - stop everything. - lldb_private::ResumeActionList actions (StateType::eStateStopped, 0); - - Error error = m_debugged_process_sp->Resume (actions); + // Interrupt the process. + Error error = m_debugged_process_sp->Interrupt (); if (error.Fail ()) { if (log) @@ -3771,7 +3794,7 @@ GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet) } // Parse out software or hardware breakpoint requested. - packet.SetFilePos (strlen("Z")); + packet.SetFilePos (strlen("z")); if (packet.GetBytesLeft() < 1) return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier"); @@ -3811,7 +3834,7 @@ GDBRemoteCommunicationServer::Handle_z (StringExtractorGDBRemote &packet) if (want_breakpoint) { - // Try to set the breakpoint. + // Try to clear the breakpoint. const Error error = m_debugged_process_sp->RemoveBreakpoint (breakpoint_addr); if (error.Success ()) return SendOKResponse (); @@ -4171,8 +4194,93 @@ GDBRemoteCommunicationServer::Handle_vAttach (StringExtractorGDBRemote &packet) // Notify we attached by sending a stop packet. return SendStopReasonForState (m_debugged_process_sp->GetState (), true); +} - return PacketResult::Success; +GDBRemoteCommunicationServer::PacketResult +GDBRemoteCommunicationServer::Handle_D (StringExtractorGDBRemote &packet) +{ + Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS)); + + // We don't support if we're not llgs. + if (!IsGdbServer()) + return SendUnimplementedResponse ("only supported for lldb-gdbserver"); + + // Scope for mutex locker. + Mutex::Locker locker (m_spawned_pids_mutex); + + // Fail if we don't have a current process. + if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)) + { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s failed, no process available", __FUNCTION__); + return SendErrorResponse (0x15); + } + + if (m_spawned_pids.find(m_debugged_process_sp->GetID ()) == m_spawned_pids.end()) + { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s failed to find PID %" PRIu64 " in spawned pids list", + __FUNCTION__, m_debugged_process_sp->GetID ()); + return SendErrorResponse (0x1); + } + + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + + // Consume the ';' after D. + packet.SetFilePos (1); + if (packet.GetBytesLeft ()) + { + if (packet.GetChar () != ';') + return SendIllFormedResponse (packet, "D missing expected ';'"); + + // Grab the PID from which we will detach (assume hex encoding). + pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16); + if (pid == LLDB_INVALID_PROCESS_ID) + return SendIllFormedResponse (packet, "D failed to parse the process id"); + } + + if (pid != LLDB_INVALID_PROCESS_ID && + m_debugged_process_sp->GetID () != pid) + { + return SendIllFormedResponse (packet, "Invalid pid"); + } + + if (m_stdio_communication.IsConnected ()) + { + m_stdio_communication.StopReadThread (); + } + + const Error error = m_debugged_process_sp->Detach (); + if (error.Fail ()) + { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s failed to detach from pid %" PRIu64 ": %s\n", + __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ()); + return SendErrorResponse (0x01); + } + + m_spawned_pids.erase (m_debugged_process_sp->GetID ()); + return SendOKResponse (); +} + +GDBRemoteCommunicationServer::PacketResult +GDBRemoteCommunicationServer::Handle_qThreadStopInfo (StringExtractorGDBRemote &packet) +{ + Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); + + // We don't support if we're not llgs. + if (!IsGdbServer()) + return SendUnimplementedResponse ("only supported for lldb-gdbserver"); + + packet.SetFilePos (strlen("qThreadStopInfo")); + const lldb::tid_t tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID); + if (tid == LLDB_INVALID_THREAD_ID) + { + if (log) + log->Printf ("GDBRemoteCommunicationServer::%s failed, could not parse thread id from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ()); + return SendErrorResponse (0x15); + } + return SendStopReplyPacketForThread (tid); } void diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 13c037c..07ce98e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -58,7 +58,7 @@ public: bool &quit); virtual bool - GetThreadSuffixSupported () + GetThreadSuffixSupported () override { return true; } @@ -152,8 +152,6 @@ public: //------------------------------------------------------------------ /// Specify the program to launch and its arguments. /// - /// The LaunchProcess () command can be executed to do the lauching. - /// /// @param[in] args /// The command line to launch. /// @@ -170,8 +168,6 @@ public: //------------------------------------------------------------------ /// Specify the launch flags for the process. /// - /// The LaunchProcess () command can be executed to do the lauching. - /// /// @param[in] launch_flags /// The launch flags to use when launching this process. /// @@ -463,6 +459,12 @@ protected: PacketResult Handle_vAttach (StringExtractorGDBRemote &packet); + PacketResult + Handle_D (StringExtractorGDBRemote &packet); + + PacketResult + Handle_qThreadStopInfo (StringExtractorGDBRemote &packet); + void SetCurrentThreadID (lldb::tid_t tid); @@ -511,9 +513,9 @@ private: return !m_is_platform; } - /// Launch a process from lldb-gdbserver + /// Launch an inferior process from lldb-gdbserver lldb_private::Error - LaunchDebugServerProcess (); + LaunchProcessForDebugging (); /// Launch a process from lldb-platform lldb_private::Error @@ -540,6 +542,9 @@ private: void ClearProcessSpecificData (); + bool + ShouldRedirectInferiorOutputOverGdbRemote (const lldb_private::ProcessLaunchInfo &launch_info) const; + //------------------------------------------------------------------ // For GDBRemoteCommunicationServer only //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 46d0540..461f2a2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -14,7 +14,6 @@ #include <errno.h> #include <stdlib.h> #ifndef LLDB_DISABLE_POSIX -#include <spawn.h> #include <netinet/in.h> #include <sys/mman.h> // for mmap #endif @@ -32,7 +31,7 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/ConnectionFileDescriptor.h" +#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" @@ -42,7 +41,9 @@ #include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Core/Value.h" +#include "lldb/Host/HostThread.h" #include "lldb/Host/Symbols.h" +#include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/TimeValue.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" @@ -271,8 +272,6 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : m_last_stop_packet_mutex (Mutex::eMutexTypeNormal), m_register_info (), m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"), - m_async_thread (LLDB_INVALID_HOST_THREAD), - m_async_thread_state(eAsyncThreadNotStarted), m_async_thread_state_mutex(Mutex::eMutexTypeRecursive), m_thread_ids (), m_continue_c_tids (), @@ -748,8 +747,12 @@ ProcessGDBRemote::WillLaunchOrAttach () Error ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) { + Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); Error error; + if (log) + log->Printf ("ProcessGDBRemote::%s() entered", __FUNCTION__); + uint32_t launch_flags = launch_info.GetFlags().Get(); const char *stdin_path = NULL; const char *stdout_path = NULL; @@ -776,10 +779,21 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) stderr_path = file_action->GetPath(); } + if (log) + { + if (stdin_path || stdout_path || stderr_path) + log->Printf ("ProcessGDBRemote::%s provided with STDIO paths via launch_info: stdin=%s, stdout=%s, stdout=%s", + __FUNCTION__, + stdin_path ? stdin_path : "<null>", + stdout_path ? stdout_path : "<null>", + stderr_path ? stderr_path : "<null>"); + else + log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__); + } + // ::LogSetBitMask (GDBR_LOG_DEFAULT); // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); // ::LogSetLogFile ("/dev/stdout"); - Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); ObjectFile * object_file = exe_module->GetObjectFile(); if (object_file) @@ -816,6 +830,13 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) if (stderr_path == NULL) stderr_path = slave_name; + + if (log) + log->Printf ("ProcessGDBRemote::%s adjusted STDIO paths for local platform (IsHost() is true) using slave: stdin=%s, stdout=%s, stdout=%s", + __FUNCTION__, + stdin_path ? stdin_path : "<null>", + stdout_path ? stdout_path : "<null>", + stderr_path ? stderr_path : "<null>"); } // Set STDIN to /dev/null if we want STDIO disabled or if either @@ -833,7 +854,14 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) if (disable_stdio || (stderr_path == NULL && (stdin_path || stdout_path))) stderr_path = "/dev/null"; - if (stdin_path) + if (log) + log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stdout=%s", + __FUNCTION__, + stdin_path ? stdin_path : "<null>", + stdout_path ? stdout_path : "<null>", + stderr_path ? stderr_path : "<null>"); + + if (stdin_path) m_gdb_comm.SetSTDIN (stdin_path); if (stdout_path) m_gdb_comm.SetSTDOUT (stdout_path); @@ -1025,18 +1053,38 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch) // prefer that over the Host information as it will be more specific // to our process. - if (m_gdb_comm.GetProcessArchitecture().IsValid()) - process_arch = m_gdb_comm.GetProcessArchitecture(); + const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture(); + if (remote_process_arch.IsValid()) + { + process_arch = remote_process_arch; + if (log) + log->Printf ("ProcessGDBRemote::%s gdb-remote had process architecture, using %s %s", + __FUNCTION__, + process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>", + process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>"); + } else + { process_arch = m_gdb_comm.GetHostArchitecture(); + if (log) + log->Printf ("ProcessGDBRemote::%s gdb-remote did not have process architecture, using gdb-remote host architecture %s %s", + __FUNCTION__, + process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>", + process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>"); + } if (process_arch.IsValid()) { ArchSpec &target_arch = GetTarget().GetArchitecture(); - if (target_arch.IsValid()) { - // If the remote host is ARM and we have apple as the vendor, then + if (log) + log->Printf ("ProcessGDBRemote::%s analyzing target arch, currently %s %s", + __FUNCTION__, + target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>", + target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>"); + + // If the remote host is ARM and we have apple as the vendor, then // ARM executables and shared libraries can have mixed ARM architectures. // You can have an armv6 executable, and if the host is armv7, then the // system will load the best possible architecture for all shared libraries @@ -1047,6 +1095,11 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch) process_arch.GetTriple().getVendor() == llvm::Triple::Apple) { GetTarget().SetArchitecture (process_arch); + if (log) + log->Printf ("ProcessGDBRemote::%s remote process is ARM/Apple, setting target arch to %s %s", + __FUNCTION__, + process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>", + process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>"); } else { @@ -1065,7 +1118,14 @@ ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch) target_triple.setEnvironment (remote_triple.getEnvironment()); } } + } + + if (log) + log->Printf ("ProcessGDBRemote::%s final target arch after adjustments for remote architecture: %s %s", + __FUNCTION__, + target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>", + target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>"); } else { @@ -1094,7 +1154,12 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) Error ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) { + Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); Error error; + + if (log) + log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__); + // Clear out and clean up from any current state Clear(); if (attach_pid != LLDB_INVALID_PROCESS_ID) @@ -1117,13 +1182,14 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const Process if (error.Success()) { m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError()); - + char packet[64]; const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid); SetID (attach_pid); m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len)); } } + return error; } @@ -1431,7 +1497,7 @@ ProcessGDBRemote::DoResume () TimeValue timeout; timeout = TimeValue::Now(); timeout.OffsetWithSeconds (5); - if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread)) + if (!m_async_thread.IsJoinable()) { error.SetErrorString ("Trying to resume but the async thread is dead."); if (log) @@ -2892,30 +2958,17 @@ ProcessGDBRemote::StartAsyncThread () log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__); Mutex::Locker start_locker(m_async_thread_state_mutex); - if (m_async_thread_state == eAsyncThreadNotStarted) + if (!m_async_thread.IsJoinable()) { // Create a thread that watches our internal state and controls which // events make it to clients (into the DCProcess event queue). - m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL); - if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) - { - m_async_thread_state = eAsyncThreadRunning; - return true; - } - else - return false; - } - else - { - // Somebody tried to start the async thread while it was either being started or stopped. If the former, and - // it started up successfully, then say all's well. Otherwise it is an error, since we aren't going to restart it. - if (log) - log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state); - if (m_async_thread_state == eAsyncThreadRunning) - return true; - else - return false; + + m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL); } + else if (log) + log->Printf("ProcessGDBRemote::%s () - Called when Async thread was already running.", __FUNCTION__); + + return m_async_thread.IsJoinable(); } void @@ -2927,7 +2980,7 @@ ProcessGDBRemote::StopAsyncThread () log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__); Mutex::Locker start_locker(m_async_thread_state_mutex); - if (m_async_thread_state == eAsyncThreadRunning) + if (m_async_thread.IsJoinable()) { m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); @@ -2935,17 +2988,10 @@ ProcessGDBRemote::StopAsyncThread () m_gdb_comm.Disconnect(); // Disconnect from the debug server. // Stop the stdio thread - if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) - { - Host::ThreadJoin (m_async_thread, NULL, NULL); - } - m_async_thread_state = eAsyncThreadDone; - } - else - { - if (log) - log->Printf ("ProcessGDBRemote::%s () - Called when Async thread was in state: %d.", __FUNCTION__, m_async_thread_state); + m_async_thread.Join(nullptr); } + else if (log) + log->Printf("ProcessGDBRemote::%s () - Called when Async thread was not running.", __FUNCTION__); } @@ -3087,7 +3133,7 @@ ProcessGDBRemote::AsyncThread (void *arg) if (log) log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID()); - process->m_async_thread = LLDB_INVALID_HOST_THREAD; + process->m_async_thread.Reset(); return NULL; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 942b31c..e0c460a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -25,6 +25,7 @@ #include "lldb/Core/StringList.h" #include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" +#include "lldb/Host/HostThread.h" #include "lldb/lldb-private-forward.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" @@ -74,148 +75,148 @@ public: //------------------------------------------------------------------ virtual bool CanDebug (lldb_private::Target &target, - bool plugin_specified_by_name); + bool plugin_specified_by_name) override; virtual lldb_private::CommandObject * - GetPluginCommandObject(); + GetPluginCommandObject() override; //------------------------------------------------------------------ // Creating a new process, or attaching to an existing one //------------------------------------------------------------------ virtual lldb_private::Error - WillLaunch (lldb_private::Module* module); + WillLaunch (lldb_private::Module* module) override; virtual lldb_private::Error DoLaunch (lldb_private::Module *exe_module, - lldb_private::ProcessLaunchInfo &launch_info); + lldb_private::ProcessLaunchInfo &launch_info) override; virtual void - DidLaunch (); + DidLaunch () override; virtual lldb_private::Error - WillAttachToProcessWithID (lldb::pid_t pid); + WillAttachToProcessWithID (lldb::pid_t pid) override; virtual lldb_private::Error - WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); + WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) override; virtual lldb_private::Error - DoConnectRemote (lldb_private::Stream *strm, const char *remote_url); + DoConnectRemote (lldb_private::Stream *strm, const char *remote_url) override; lldb_private::Error WillLaunchOrAttach (); virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid); + DoAttachToProcessWithID (lldb::pid_t pid) override; virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info); + DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override; virtual lldb_private::Error DoAttachToProcessWithName (const char *process_name, - const lldb_private::ProcessAttachInfo &attach_info); + const lldb_private::ProcessAttachInfo &attach_info) override; virtual void - DidAttach (lldb_private::ArchSpec &process_arch); + DidAttach (lldb_private::ArchSpec &process_arch) override; //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ virtual lldb_private::ConstString - GetPluginName(); + GetPluginName() override; virtual uint32_t - GetPluginVersion(); + GetPluginVersion() override; //------------------------------------------------------------------ // Process Control //------------------------------------------------------------------ virtual lldb_private::Error - WillResume (); + WillResume () override; virtual lldb_private::Error - DoResume (); + DoResume () override; virtual lldb_private::Error - DoHalt (bool &caused_stop); + DoHalt (bool &caused_stop) override; virtual lldb_private::Error - DoDetach (bool keep_stopped); + DoDetach (bool keep_stopped) override; virtual bool - DetachRequiresHalt() { return true; } + DetachRequiresHalt() override { return true; } virtual lldb_private::Error - DoSignal (int signal); + DoSignal (int signal) override; virtual lldb_private::Error - DoDestroy (); + DoDestroy () override; virtual void - RefreshStateAfterStop(); + RefreshStateAfterStop() override; //------------------------------------------------------------------ // Process Queries //------------------------------------------------------------------ virtual bool - IsAlive (); + IsAlive () override; virtual lldb::addr_t - GetImageInfoAddress(); + GetImageInfoAddress() override; //------------------------------------------------------------------ // Process Memory //------------------------------------------------------------------ virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); + DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override; virtual size_t - DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error); + DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error) override; virtual lldb::addr_t - DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error); + DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error) override; virtual lldb_private::Error GetMemoryRegionInfo (lldb::addr_t load_addr, - lldb_private::MemoryRegionInfo ®ion_info); + lldb_private::MemoryRegionInfo ®ion_info) override; virtual lldb_private::Error - DoDeallocateMemory (lldb::addr_t ptr); + DoDeallocateMemory (lldb::addr_t ptr) override; //------------------------------------------------------------------ // Process STDIO //------------------------------------------------------------------ virtual size_t - PutSTDIN (const char *buf, size_t buf_size, lldb_private::Error &error); + PutSTDIN (const char *buf, size_t buf_size, lldb_private::Error &error) override; //---------------------------------------------------------------------- // Process Breakpoints //---------------------------------------------------------------------- virtual lldb_private::Error - EnableBreakpointSite (lldb_private::BreakpointSite *bp_site); + EnableBreakpointSite (lldb_private::BreakpointSite *bp_site) override; virtual lldb_private::Error - DisableBreakpointSite (lldb_private::BreakpointSite *bp_site); + DisableBreakpointSite (lldb_private::BreakpointSite *bp_site) override; //---------------------------------------------------------------------- // Process Watchpoints //---------------------------------------------------------------------- virtual lldb_private::Error - EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true); + EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true) override; virtual lldb_private::Error - DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true); + DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true) override; virtual lldb_private::Error - GetWatchpointSupportInfo (uint32_t &num); + GetWatchpointSupportInfo (uint32_t &num) override; virtual lldb_private::Error - GetWatchpointSupportInfo (uint32_t &num, bool& after); + GetWatchpointSupportInfo (uint32_t &num, bool& after) override; virtual bool - StartNoticingNewThreads(); + StartNoticingNewThreads() override; virtual bool - StopNoticingNewThreads(); + StopNoticingNewThreads() override; GDBRemoteCommunicationClient & GetGDBRemote() @@ -224,13 +225,13 @@ public: } virtual lldb_private::Error - SendEventData(const char *data); + SendEventData(const char *data) override; //---------------------------------------------------------------------- // Override SetExitStatus so we can disconnect from the remote GDB server //---------------------------------------------------------------------- virtual bool - SetExitStatus (int exit_status, const char *cstr); + SetExitStatus (int exit_status, const char *cstr) override; void SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max); @@ -286,7 +287,7 @@ protected: virtual bool UpdateThreadList (lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); + lldb_private::ThreadList &new_thread_list) override; lldb_private::Error LaunchAndConnectToDebugserver (const lldb_private::ProcessInfo &process_info); @@ -324,23 +325,15 @@ protected: eBroadcastBitAsyncThreadShouldExit = (1 << 1), eBroadcastBitAsyncThreadDidExit = (1 << 2) }; - - typedef enum AsyncThreadState - { - eAsyncThreadNotStarted, - eAsyncThreadRunning, - eAsyncThreadDone - } AsyncThreadState; lldb_private::Flags m_flags; // Process specific flags (see eFlags enums) GDBRemoteCommunicationClient m_gdb_comm; - lldb::pid_t m_debugserver_pid; + std::atomic<lldb::pid_t> m_debugserver_pid; StringExtractorGDBRemote m_last_stop_packet; lldb_private::Mutex m_last_stop_packet_mutex; GDBRemoteDynamicRegisterInfo m_register_info; lldb_private::Broadcaster m_async_broadcaster; - lldb::thread_t m_async_thread; - AsyncThreadState m_async_thread_state; + lldb_private::HostThread m_async_thread; lldb_private::Mutex m_async_thread_state_mutex; typedef std::vector<lldb::tid_t> tid_collection; typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection; @@ -395,7 +388,7 @@ protected: std::string &dispatch_queue_name); lldb_private::DynamicLoader * - GetDynamicLoader (); + GetDynamicLoader () override; private: //------------------------------------------------------------------ |