diff options
author | Todd Fiala <todd.fiala@gmail.com> | 2014-09-12 16:57:28 +0000 |
---|---|---|
committer | Todd Fiala <todd.fiala@gmail.com> | 2014-09-12 16:57:28 +0000 |
commit | 49131cfd2ec6b09ee3687e4fcd6db1344fa97a31 (patch) | |
tree | d7202588154ac3ccf5f7e9217d84ac173d44b790 | |
parent | 4689647dbb52bc68d671a390c8929b33e1c674a1 (diff) | |
download | bcm5719-llvm-49131cfd2ec6b09ee3687e4fcd6db1344fa97a31.tar.gz bcm5719-llvm-49131cfd2ec6b09ee3687e4fcd6db1344fa97a31.zip |
lldb fix ARM64 register access
Apparently, PEEKUSER/POKEUSER is something x86 specific, so I had to rework it for AArch64. This fixes assertion that occurs whenever lldb started on AArch64 device tried to read PC register (or any other register)
See http://reviews.llvm.org/D5232 for more details.
Change by Paul Osmialowski.
llvm-svn: 217691
-rw-r--r-- | lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index c830124fe91..ac0ffcbe5ab 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -17,6 +17,7 @@ #include <unistd.h> #include <elf.h> #include <sys/personality.h> +#include <sys/procfs.h> #include <sys/ptrace.h> #include <sys/uio.h> #include <sys/socket.h> @@ -497,6 +498,48 @@ private: void ReadRegOperation::Execute(ProcessMonitor *monitor) { +#if defined (__arm64__) || defined (__aarch64__) + if (m_offset > sizeof(struct user_pt_regs)) + { + uintptr_t offset = m_offset - sizeof(struct user_pt_regs); + if (offset > sizeof(struct user_fpsimd_state)) + { + m_result = false; + } + else + { + elf_fpregset_t regs; + int regset = NT_FPREGSET; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs) < 0) + m_result = false; + else + { + m_result = true; + m_value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, monitor->GetProcess().GetByteOrder()); + } + } + } + else + { + elf_gregset_t regs; + int regset = NT_PRSTATUS; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs) < 0) + m_result = false; + else + { + m_result = true; + m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, monitor->GetProcess().GetByteOrder()); + } + } +#else Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); // Set errno to zero so that we can detect a failed peek. @@ -512,6 +555,7 @@ ReadRegOperation::Execute(ProcessMonitor *monitor) if (log) log->Printf ("ProcessMonitor::%s() reg %s: 0x%" PRIx64, __FUNCTION__, m_reg_name, data); +#endif } //------------------------------------------------------------------------------ @@ -539,6 +583,54 @@ private: void WriteRegOperation::Execute(ProcessMonitor *monitor) { +#if defined (__arm64__) || defined (__aarch64__) + if (m_offset > sizeof(struct user_pt_regs)) + { + uintptr_t offset = m_offset - sizeof(struct user_pt_regs); + if (offset > sizeof(struct user_fpsimd_state)) + { + m_result = false; + } + else + { + elf_fpregset_t regs; + int regset = NT_FPREGSET; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs) < 0) + m_result = false; + else + { + ::memcpy((void *)(((unsigned char *)(®s)) + offset), m_value.GetBytes(), 16); + if (PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs) < 0) + m_result = false; + else + m_result = true; + } + } + } + else + { + elf_gregset_t regs; + int regset = NT_PRSTATUS; + struct iovec ioVec; + + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + if (PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs) < 0) + m_result = false; + else + { + ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); + if (PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs) < 0) + m_result = false; + else + m_result = true; + } + } +#else void* buf; Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); @@ -550,6 +642,7 @@ WriteRegOperation::Execute(ProcessMonitor *monitor) m_result = false; else m_result = true; +#endif } //------------------------------------------------------------------------------ |