[Lldb-commits] [lldb] r202428 - Fix linux x86 debugging on a linux x86 host (32-bit on 32-bit).

Todd Fiala tfiala at google.com
Thu Feb 27 12:46:12 PST 2014


Author: tfiala
Date: Thu Feb 27 14:46:12 2014
New Revision: 202428

URL: http://llvm.org/viewvc/llvm-project?rev=202428&view=rev
Log:
Fix linux x86 debugging on a linux x86 host (32-bit on 32-bit).

This change fixes up issues with specifying the size of the i386
register infos for FPU registers.  The bug was that for the i386
register context, the size of the FPU registers were still being
computed based on the x86_64 FXSAVE structure.

This change permits the FPR_SIZE macro to optionally be defined
outside of RegisterInfos_i386.h, which RegisterContextLinux_i386.cpp
does properly. It redefines the FPR_i386 structure with all the
accessible parts that RegisterInfos_i386.h wants to see, which we had
not done before when we made the overall size of the structure
properly sized a recently.

This change also modifies POSIXThread to create a
RegisterContextLinux_i386 only when the host is 32-bit; otherwise, it
uses the RegisterContextLinux_x86_64, which works properly for 32-bit
and 64-bit inferiors on a 64-bit host.

I tested this debugging a Linux x86 exe on an x86 host (Ubuntu 13.10
x86), and debugging a Linux x86 exe and a Linux x86-64 exe on an
x86-64 host (Ubuntu 12.04 LTS).  Those cases all worked.

Thanks to Matthew Gardiner who discoverd may key insights into
tracking down the issue. The motivation for this change and some of
the code originates from him via this thread:

http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20140224/010554.html


Modified:
    lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
    lldb/trunk/source/Plugins/Process/POSIX/RegisterInfos_i386.h

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=202428&r1=202427&r2=202428&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessMonitor.cpp Thu Feb 27 14:46:12 2014
@@ -168,9 +168,9 @@ PtraceWrapper(int req, lldb::pid_t pid,
 
     errno = 0;
     if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
-        result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data);
+        result = ptrace(static_cast<__ptrace_request>(req), static_cast<pid_t>(pid), *(unsigned int *)addr, data);
     else
-        result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data);
+        result = ptrace(static_cast<__ptrace_request>(req), static_cast<pid_t>(pid), addr, data);
 
     if (log)
         log->Printf("ptrace(%s, %" PRIu64 ", %p, %p, %zu)=%lX called from file %s line %d",

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=202428&r1=202427&r2=202428&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Thu Feb 27 14:46:12 2014
@@ -190,7 +190,17 @@ POSIXThread::GetRegisterContext()
                         reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
                         break;
                     case llvm::Triple::Linux:
-                        reg_interface = new RegisterContextLinux_x86_64(target_arch);
+                        if (Host::GetArchitecture().GetAddressByteSize() == 4)
+                        {
+                            // 32-bit hosts run with a RegisterContextLinux_i386 context.
+                            reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
+                        }
+                        else
+                        {
+                            assert((Host::GetArchitecture().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
+                            // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
+                            reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_x86_64(target_arch));
+                        }
                         break;
                     default:
                         assert(false && "OS not supported");

Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp?rev=202428&r1=202427&r2=202428&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp Thu Feb 27 14:46:12 2014
@@ -36,14 +36,30 @@ struct GPR
 
 struct FPR_i386
 {
-    int32_t cwd;
-    int32_t swd;
-    int32_t twd;
-    int32_t fip;
-    int32_t fcs;
-    int32_t foo;
-    int32_t fos;
-    int32_t st_space [20];
+    uint16_t fctrl;         // FPU Control Word (fcw)
+    uint16_t fstat;         // FPU Status Word (fsw)
+    uint16_t ftag;          // FPU Tag Word (ftw)
+    uint16_t fop;           // Last Instruction Opcode (fop)
+    union
+    {
+        struct
+        {
+            uint64_t fip;   // Instruction Pointer
+            uint64_t fdp;   // Data Pointer
+        } x86_64;
+        struct
+        {
+            uint32_t fioff;   // FPU IP Offset (fip)
+            uint32_t fiseg;   // FPU IP Selector (fcs)
+            uint32_t fooff;   // FPU Operand Pointer Offset (foo)
+            uint32_t foseg;   // FPU Operand Pointer Selector (fos)
+        } i386;
+    } ptr;
+    uint32_t mxcsr;         // MXCSR Register State
+    uint32_t mxcsrmask;     // MXCSR Mask
+    MMSReg   stmm[8];       // 8*16 bytes for each FP-reg = 128 bytes
+    XMMReg   xmm[8];        // 8*16 bytes for each XMM-reg = 128 bytes
+    uint32_t padding[56];
 };
 
 struct UserArea
@@ -69,6 +85,7 @@ struct UserArea
 #define DR_SIZE sizeof(UserArea::u_debugreg[0])
 #define DR_OFFSET(reg_index) \
     (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
+#define FPR_SIZE(reg) sizeof(((FPR_i386*)NULL)->reg)
 
 //---------------------------------------------------------------------------
 // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.

Modified: lldb/trunk/source/Plugins/Process/POSIX/RegisterInfos_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/RegisterInfos_i386.h?rev=202428&r1=202427&r2=202428&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/RegisterInfos_i386.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/RegisterInfos_i386.h Thu Feb 27 14:46:12 2014
@@ -24,7 +24,9 @@
     (LLVM_EXTENSION offsetof(YMM, regname))
 
 // Number of bytes needed to represent a FPR.
+#if !defined(FPR_SIZE)
 #define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+#endif
 
 // Number of bytes needed to represent the i'th FP register.
 #define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)





More information about the lldb-commits mailing list