[Lldb-commits] [lldb] r177568 - Add Linux support for reading/writing extended register sets.

Matt Kopec Matt.Kopec at intel.com
Wed Mar 20 13:34:35 PDT 2013


Author: mkopec
Date: Wed Mar 20 15:34:35 2013
New Revision: 177568

URL: http://llvm.org/viewvc/llvm-project?rev=177568&view=rev
Log:
Add Linux support for reading/writing extended register sets.

Patch by Ashok Thirumurthi.

Modified:
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=177568&r1=177567&r2=177568&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Wed Mar 20 15:34:35 2013
@@ -61,7 +61,7 @@ Get_PT_IO_OP(int op)
 // Wrapper for ptrace to catch errors and log calls.
 // Note that ptrace sets errno on error because -1 is reserved as a valid result.
 extern long
-PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
+PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
               const char* reqName, const char* file, int line)
 {
     long int result;
@@ -117,7 +117,7 @@ PtraceWrapper(int req, ::pid_t pid, void
 // Wrapper for ptrace when logging is not required.
 // Sets errno to 0 prior to calling ptrace.
 extern long
-PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data)
+PtraceWrapper(__ptrace_request req, lldb::pid_t pid, void *addr, int data)
 {
     long result = 0;
     errno = 0;

Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp?rev=177568&r1=177567&r2=177568&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp Wed Mar 20 15:34:35 2013
@@ -39,6 +39,14 @@
 
 #define DEBUG_PTRACE_MAXBYTES 20
 
+// Support ptrace extensions even when compiled without required kernel support
+#ifndef PTRACE_GETREGSET
+  #define PTRACE_GETREGSET 0x4204
+#endif
+#ifndef PTRACE_SETREGSET
+  #define PTRACE_SETREGSET 0x4205
+#endif
+
 using namespace lldb_private;
 
 // FIXME: this code is host-dependent with respect to types and
@@ -63,7 +71,7 @@ DisplayBytes (lldb_private::StreamString
     }
 }
 
-static void PtraceDisplayBytes(__ptrace_request &req, void *data, size_t data_size)
+static void PtraceDisplayBytes(int &req, void *data, size_t data_size)
 {
     StreamString buf;
     LogSP verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
@@ -109,6 +117,13 @@ static void PtraceDisplayBytes(__ptrace_
                 verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
                 break;
             }
+        case PTRACE_SETREGSET:
+            {
+                // Extract iov_base from data, which is a pointer to the struct IOVEC
+                DisplayBytes(buf, *(void **)data, data_size);
+                verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
+                break;
+            }
         default:
             {
             }
@@ -119,7 +134,7 @@ static void PtraceDisplayBytes(__ptrace_
 // Wrapper for ptrace to catch errors and log calls.
 // Note that ptrace sets errno on error because -1 is a valid result for PTRACE_PEEK*
 extern long
-PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t data_size,
+PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size,
               const char* reqName, const char* file, int line)
 {
     long int result;
@@ -127,13 +142,16 @@ PtraceWrapper(__ptrace_request req, pid_
     LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
 
     if (log)
-        log->Printf("ptrace(%s, %u, %p, %p, %zu) called from file %s line %d",
+        log->Printf("ptrace(%s, %lu, %p, %p, %zu) called from file %s line %d",
                     reqName, pid, addr, data, data_size, file, line);
 
     PtraceDisplayBytes(req, data, data_size);
 
     errno = 0;
-    result = ptrace(req, pid, addr, data);
+    if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+        result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data);
+    else
+        result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data);
 
     PtraceDisplayBytes(req, data, data_size);
 
@@ -157,10 +175,14 @@ PtraceWrapper(__ptrace_request req, pid_
 // Wrapper for ptrace when logging is not required.
 // Sets errno to 0 prior to calling ptrace.
 extern long
-PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, size_t data_size)
+PtraceWrapper(int req, pid_t pid, void *addr, void *data, size_t data_size)
 {
+    long result = 0;
     errno = 0;
-    long result = ptrace(req, pid, addr, data);
+    if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+        result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data);
+    else
+        result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data);
     return result;
 }
 
@@ -556,6 +578,35 @@ ReadFPROperation::Execute(ProcessMonitor
 }
 
 //------------------------------------------------------------------------------
+/// @class ReadRegisterSetOperation
+/// @brief Implements ProcessMonitor::ReadRegisterSet.
+class ReadRegisterSetOperation : public Operation
+{
+public:
+    ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
+        : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
+        { }
+
+    void Execute(ProcessMonitor *monitor);
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+    const unsigned int m_regset;
+    bool &m_result;
+};
+
+void
+ReadRegisterSetOperation::Execute(ProcessMonitor *monitor)
+{
+    if (PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
+        m_result = false;
+    else
+        m_result = true;
+}
+
+//------------------------------------------------------------------------------
 /// @class WriteGPROperation
 /// @brief Implements ProcessMonitor::WriteGPR.
 class WriteGPROperation : public Operation
@@ -612,6 +663,35 @@ WriteFPROperation::Execute(ProcessMonito
 }
 
 //------------------------------------------------------------------------------
+/// @class WriteRegisterSetOperation
+/// @brief Implements ProcessMonitor::WriteRegisterSet.
+class WriteRegisterSetOperation : public Operation
+{
+public:
+    WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
+        : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
+        { }
+
+    void Execute(ProcessMonitor *monitor);
+
+private:
+    lldb::tid_t m_tid;
+    void *m_buf;
+    size_t m_buf_size;
+    const unsigned int m_regset;
+    bool &m_result;
+};
+
+void
+WriteRegisterSetOperation::Execute(ProcessMonitor *monitor)
+{
+    if (PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
+        m_result = false;
+    else
+        m_result = true;
+}
+
+//------------------------------------------------------------------------------
 /// @class ResumeOperation
 /// @brief Implements ProcessMonitor::Resume.
 class ResumeOperation : public Operation
@@ -1664,6 +1744,15 @@ ProcessMonitor::ReadFPR(lldb::tid_t tid,
 }
 
 bool
+ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
+{
+    bool result;
+    ReadRegisterSetOperation op(tid, buf, buf_size, regset, result);
+    DoOperation(&op);
+    return result;
+}
+
+bool
 ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
 {
     bool result;
@@ -1680,6 +1769,15 @@ ProcessMonitor::WriteFPR(lldb::tid_t tid
     DoOperation(&op);
     return result;
 }
+
+bool
+ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
+{
+    bool result;
+    WriteRegisterSetOperation op(tid, buf, buf_size, regset, result);
+    DoOperation(&op);
+    return result;
+}
 
 bool
 ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo)

Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h?rev=177568&r1=177567&r2=177568&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.h Wed Mar 20 15:34:35 2013
@@ -122,18 +122,28 @@ public:
     bool
     ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
 
-    /// Reads all floating point registers into the specified buffer.
+    /// Reads generic floating point registers into the specified buffer.
     bool
     ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
 
+    /// Reads the specified register set into the specified buffer.
+    /// For instance, the extended floating-point register set.
+    bool
+    ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
+
     /// Writes all general purpose registers into the specified buffer.
     bool
     WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
 
-    /// Writes all floating point registers into the specified buffer.
+    /// Writes generic floating point registers into the specified buffer.
     bool
     WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
 
+    /// Writes the specified register set into the specified buffer.
+    /// For instance, the extended floating-point register set.
+    bool
+    WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
+
     /// Writes a siginfo_t structure corresponding to the given thread ID to the
     /// memory region pointed to by @p siginfo.
     bool





More information about the lldb-commits mailing list