[Lldb-commits] [lldb] r217788 - lldb fix ARM64 register access - llgs side

Todd Fiala todd.fiala at gmail.com
Mon Sep 15 10:09:23 PDT 2014


Author: tfiala
Date: Mon Sep 15 12:09:23 2014
New Revision: 217788

URL: http://llvm.org/viewvc/llvm-project?rev=217788&view=rev
Log:
lldb fix ARM64 register access - llgs side

See http://reviews.llvm.org/D5341 for more details.

Change by Paul Osmialowski.

Modified:
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=217788&r1=217787&r2=217788&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Mon Sep 15 12:09:23 2014
@@ -19,6 +19,7 @@
 #include <unistd.h>
 #include <linux/unistd.h>
 #include <sys/personality.h>
+#include <sys/procfs.h>
 #include <sys/ptrace.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
@@ -592,6 +593,59 @@ namespace
     void
     ReadRegOperation::Execute(NativeProcessLinux *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, &regset, &ioVec, sizeof regs) < 0)
+                    m_result = false;
+                else
+                {
+                    lldb_private::ArchSpec arch;
+                    if (monitor->GetArchitecture(arch))
+                    {
+                        m_result = true;
+                        m_value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16, arch.GetByteOrder());
+                    }
+                    else
+                        m_result = false;
+                }
+            }
+        }
+        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, &regset, &ioVec, sizeof regs) < 0)
+                m_result = false;
+            else
+            {
+                lldb_private::ArchSpec arch;
+                if (monitor->GetArchitecture(arch))
+                {
+                    m_result = true;
+                    m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder());
+                } else
+                    m_result = false;
+            }
+        }
+#else
         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
 
         // Set errno to zero so that we can detect a failed peek.
@@ -607,6 +661,7 @@ namespace
         if (log)
             log->Printf ("NativeProcessLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__,
                     m_reg_name, data);
+#endif
     }
 
     //------------------------------------------------------------------------------
@@ -634,6 +689,54 @@ namespace
     void
     WriteRegOperation::Execute(NativeProcessLinux *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, &regset, &ioVec, sizeof regs) < 0)
+                    m_result = false;
+                else
+                {
+                    ::memcpy((void *)(((unsigned char *)(&regs)) + offset), m_value.GetBytes(), 16);
+                    if (PTRACE(PTRACE_SETREGSET, m_tid, &regset, &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, &regset, &ioVec, sizeof regs) < 0)
+                m_result = false;
+            else
+            {
+                ::memcpy((void *)(((unsigned char *)(&regs)) + m_offset), m_value.GetBytes(), 8);
+                if (PTRACE(PTRACE_SETREGSET, m_tid, &regset, &ioVec, sizeof regs) < 0)
+                    m_result = false;
+                else
+                    m_result = true;
+            }
+        }
+#else
         void* buf;
         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
 
@@ -645,6 +748,7 @@ namespace
             m_result = false;
         else
             m_result = true;
+#endif
     }
 
     //------------------------------------------------------------------------------





More information about the lldb-commits mailing list