[Lldb-commits] [lldb] r163398 - in /lldb/trunk/source: Host/common/Host.cpp Plugins/Platform/Linux/PlatformLinux.cpp Plugins/Process/Linux/ProcessMonitor.cpp

Greg Clayton gclayton at apple.com
Fri Sep 7 10:49:30 PDT 2012


Author: gclayton
Date: Fri Sep  7 12:49:29 2012
New Revision: 163398

URL: http://llvm.org/viewvc/llvm-project?rev=163398&view=rev
Log:
Patch from Andrew Kaylor for linux:


The attached patch adds support for debugging 32-bit processes when running a 64-bit lldb on an x86_64 Linux system.
 
Making this work required two basic changes:
 
1)      Getting lldb to report that it could debug 32-bit processes
2)      Changing an assumption about how ptrace works when debugging cross-platform
 
For the first change, I took a conservative approach and only enabled this for x86_64 Linux platforms.  It may be that the change I made in Host.cpp could be extended to other 64-bit Linux platforms, but I'm not familiar enough with the other platforms to know for sure.
 
For the second change, the Linux ProcessMonitor class was assuming that ptrace(PTRACE_[PEEK|POKE]DATA...) would read/write a "word" based on the child process word size.  However, the ptrace documentation says that the "word" size read or written is "determined by the OS variant."  I verified experimentally that when ptracing a 32-bit child from a 64-bit parent a 64-bit word is read or written.


Modified:
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
    lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=163398&r1=163397&r2=163398&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Fri Sep  7 12:49:29 2012
@@ -339,6 +339,12 @@
             break;
 
         case llvm::Triple::x86_64:
+            g_host_arch_64.SetTriple(triple);
+            g_supports_64 = true;
+            g_host_arch_32.SetTriple(triple.get32BitArchVariant());
+            g_supports_32 = true;
+            break;
+
         case llvm::Triple::sparcv9:
         case llvm::Triple::ppc64:
         case llvm::Triple::cellspu:

Modified: lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp?rev=163398&r1=163397&r2=163398&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp Fri Sep  7 12:49:29 2012
@@ -312,6 +312,17 @@
         arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
         return arch.IsValid();
     }
+    else if (idx == 1)
+    {
+        // If the default host architecture is 64-bit, look for a 32-bit variant
+        ArchSpec hostArch
+                      = Host::GetArchitecture(Host::eSystemDefaultArchitecture);
+        if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit())
+        {
+            arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
+            return arch.IsValid();
+        }
+    }
     return false;
 }
 

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=163398&r1=163397&r2=163398&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp Fri Sep  7 12:49:29 2012
@@ -77,19 +77,19 @@
                 verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
                 break;
             }
-        case PTRACE_POKEDATA: 
+        case PTRACE_POKEDATA:
             {
                 DisplayBytes(buf, &data, 8);
                 verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
                 break;
             }
-        case PTRACE_POKEUSER: 
+        case PTRACE_POKEUSER:
             {
                 DisplayBytes(buf, &data, 8);
                 verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
                 break;
             }
-        case PTRACE_SETREGS: 
+        case PTRACE_SETREGS:
             {
                 DisplayBytes(buf, data, sizeof(user_regs_struct));
                 verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
@@ -101,7 +101,7 @@
                 verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
                 break;
             }
-        case PTRACE_SETSIGINFO: 
+        case PTRACE_SETSIGINFO:
             {
                 DisplayBytes(buf, data, sizeof(siginfo_t));
                 verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
@@ -126,7 +126,7 @@
     if (log)
         log->Printf("ptrace(%s, %u, %p, %p) called from file %s line %d",
                     reqName, pid, addr, data, file, line);
-    
+
     PtraceDisplayBytes(req, data);
 
     errno = 0;
@@ -163,9 +163,11 @@
 // functions without needed to go thru the thread funnel.
 
 static size_t
-DoReadMemory(lldb::pid_t pid, unsigned word_size,
+DoReadMemory(lldb::pid_t pid,
              lldb::addr_t vm_addr, void *buf, size_t size, Error &error)
 {
+    // ptrace word size is determined by the host, not the child
+    static const unsigned word_size = sizeof(void*);
     unsigned char *dst = static_cast<unsigned char*>(buf);
     size_t bytes_read;
     size_t remainder;
@@ -179,7 +181,6 @@
                      pid, word_size, (void*)vm_addr, buf, size);
 
     assert(sizeof(data) >= word_size);
-    assert(sizeof(void*) == word_size);
     for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
     {
         errno = 0;
@@ -218,9 +219,11 @@
 }
 
 static size_t
-DoWriteMemory(lldb::pid_t pid, unsigned word_size,
+DoWriteMemory(lldb::pid_t pid,
               lldb::addr_t vm_addr, const void *buf, size_t size, Error &error)
 {
+    // ptrace word size is determined by the host, not the child
+    static const unsigned word_size = sizeof(void*);
     const unsigned char *src = static_cast<const unsigned char*>(buf);
     size_t bytes_written = 0;
     size_t remainder;
@@ -232,7 +235,6 @@
         log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__,
                      pid, word_size, (void*)vm_addr, buf, size);
 
-    assert(sizeof(void*) == word_size);
     for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
     {
         remainder = size - bytes_written;
@@ -263,7 +265,7 @@
         else
         {
             unsigned char buff[8];
-            if (DoReadMemory(pid, word_size, vm_addr,
+            if (DoReadMemory(pid, vm_addr,
                              buff, word_size, error) != word_size)
             {
                 if (log)
@@ -273,7 +275,7 @@
 
             memcpy(buff, src, remainder);
 
-            if (DoWriteMemory(pid, word_size, vm_addr,
+            if (DoWriteMemory(pid, vm_addr,
                               buff, word_size, error) != word_size)
             {
                 if (log)
@@ -361,10 +363,9 @@
 void
 ReadOperation::Execute(ProcessMonitor *monitor)
 {
-    const unsigned word_size = monitor->GetProcess().GetAddressByteSize();
     lldb::pid_t pid = monitor->GetPID();
 
-    m_result = DoReadMemory(pid, word_size, m_addr, m_buff, m_size, m_error);
+    m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
 }
 
 //------------------------------------------------------------------------------
@@ -392,10 +393,9 @@
 void
 WriteOperation::Execute(ProcessMonitor *monitor)
 {
-    const unsigned word_size = monitor->GetProcess().GetAddressByteSize();
     lldb::pid_t pid = monitor->GetPID();
 
-    m_result = DoWriteMemory(pid, word_size, m_addr, m_buff, m_size, m_error);
+    m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
 }
 
 
@@ -744,7 +744,7 @@
 
     if (ptrace(PT_DETACH, pid, NULL, 0) < 0)
         m_error.SetErrorToErrno();
-  
+
 }
 
 ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
@@ -1060,22 +1060,22 @@
         args->m_error.SetErrorToGenericError();
         switch (WEXITSTATUS(status))
         {
-            case ePtraceFailed: 
+            case ePtraceFailed:
                 args->m_error.SetErrorString("Child ptrace failed.");
                 break;
-            case eDupStdinFailed: 
+            case eDupStdinFailed:
                 args->m_error.SetErrorString("Child open stdin failed.");
                 break;
-            case eDupStdoutFailed: 
+            case eDupStdoutFailed:
                 args->m_error.SetErrorString("Child open stdout failed.");
                 break;
-            case eDupStderrFailed: 
+            case eDupStderrFailed:
                 args->m_error.SetErrorString("Child open stderr failed.");
                 break;
-            case eExecFailed: 
+            case eExecFailed:
                 args->m_error.SetErrorString("Child exec failed.");
                 break;
-            default: 
+            default:
                 args->m_error.SetErrorString("Child returned unknown exit status.");
                 break;
         }
@@ -1228,7 +1228,7 @@
         case SIGTRAP:
             message = MonitorSIGTRAP(monitor, &info, pid);
             break;
-            
+
         default:
             message = MonitorSignal(monitor, &info, pid);
             break;
@@ -1342,7 +1342,7 @@
 
     reason = ProcessMessage::eInvalidCrashReason;
 
-    switch (info->si_code) 
+    switch (info->si_code)
     {
     default:
         assert(false && "unexpected si_code for SIGSEGV");
@@ -1354,7 +1354,7 @@
         reason = ProcessMessage::ePrivilegedAddress;
         break;
     }
-        
+
     return reason;
 }
 
@@ -1675,7 +1675,7 @@
     DoOperation(&op);
     StopMonitor();
     return result;
-}    
+}
 
 bool
 ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)





More information about the lldb-commits mailing list