[Lldb-commits] [lldb] r254499 - PTRACE ABI to read FXSAVE area for 32-bit inferior

Abhishek Aggarwal via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 2 01:40:17 PST 2015


Author: abhishek
Date: Wed Dec  2 03:40:17 2015
New Revision: 254499

URL: http://llvm.org/viewvc/llvm-project?rev=254499&view=rev
Log:
PTRACE ABI to read FXSAVE area for 32-bit inferior

Summary:
 - Problem occurs when:
    -- 32-bit inferiors run on x86_32 machine and
       the architecture doesn't have AVX feature

    -- This causes FPRType to be set to eFPRTypeFXSAVE

    -- PTRACE_GETFPREGS was being used to read FXSAVE area

    -- For 32-bit inferiors running on x86_32 machine,
       PTRACE_GETFPREGS reads FSAVE area and not FXSAVE area

 - Changed ptrace API to PTRACE_GETREGSET for 32-bit inferiors
    -- This reads FPR data in FXSAVE format.
    -- For 64-bit inferiors, no change has been made.

 - Modified XFAIL for TestReturnValue.py
    -- Earlier, this test was passing for Linux OS
    -- Now, it passes for Android OS as well

Change-Id: Ieed72bc969b79516fc7b263b32493aa1e7a1a2ac
Signed-off-by: Abhishek Aggarwal <abhishek.a.aggarwal at intel.com>

Reviewers: ovyalov, jingham, lldb-commits, tberghammer, labath

Subscribers: jevinskie, labath, tberghammer, danalbert

Differential Revision: http://reviews.llvm.org/D15042

Modified:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py?rev=254499&r1=254498&r2=254499&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/return-value/TestReturnValue.py Wed Dec  2 03:40:17 2015
@@ -16,7 +16,7 @@ class ReturnValueTestCase(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
 
-    @expectedFailurei386
+    @expectedFailureAll(oslist=["macosx","freebsd"], archs=["i386"])
     @expectedFailureWindows("llvm.org/pr24778")
     @add_test_categories(['pyapi'])
     def test_with_python(self):

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp?rev=254499&r1=254498&r2=254499&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp Wed Dec  2 03:40:17 2015
@@ -327,6 +327,9 @@ namespace
 #ifndef NT_X86_XSTATE
 #define NT_X86_XSTATE 0x202
 #endif
+#ifndef NT_PRXFPREG
+#define NT_PRXFPREG 0x46e62b7f
+#endif
 
 NativeRegisterContextLinux*
 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,
@@ -832,6 +835,7 @@ NativeRegisterContextLinux_x86_64::IsGPR
 NativeRegisterContextLinux_x86_64::FPRType
 NativeRegisterContextLinux_x86_64::GetFPRType () const
 {
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
     if (m_fpr_type == eFPRTypeNotValid)
     {
         // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx.
@@ -842,9 +846,15 @@ NativeRegisterContextLinux_x86_64::GetFP
         {
             // Fall back to general floating point with no AVX support.
             m_fpr_type = eFPRTypeFXSAVE;
+
+            // Check if FXSAVE area can be read.
+            if (const_cast<NativeRegisterContextLinux_x86_64*>(this)->ReadFPR().Fail())
+            {
+                if (log)
+                    log->Printf("NativeRegisterContextLinux_x86_64::%s ptrace APIs failed to read XSAVE/FXSAVE area", __FUNCTION__);
+            }
         }
     }
-
     return m_fpr_type;
 }
 
@@ -868,10 +878,24 @@ Error
 NativeRegisterContextLinux_x86_64::WriteFPR()
 {
     const FPRType fpr_type = GetFPRType ();
+    const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();
     switch (fpr_type)
     {
     case FPRType::eFPRTypeFXSAVE:
-        return NativeRegisterContextLinux::WriteFPR();
+        // For 32-bit inferiors on x86_32/x86_64 architectures,
+        // FXSAVE area can be written using PTRACE_SETREGSET ptrace api
+        // For 64-bit inferiors on x86_64 architectures,
+        // FXSAVE area can be written using PTRACE_SETFPREGS ptrace api
+        switch (target_arch.GetMachine ())
+        {
+            case llvm::Triple::x86:
+                return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
+            case llvm::Triple::x86_64:
+                return NativeRegisterContextLinux::WriteFPR();
+            default:
+                assert(false && "Unhandled target architecture.");
+                break;
+        }
     case FPRType::eFPRTypeXSAVE:
         return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
     default:
@@ -980,10 +1004,24 @@ Error
 NativeRegisterContextLinux_x86_64::ReadFPR ()
 {
     const FPRType fpr_type = GetFPRType ();
+    const lldb_private::ArchSpec& target_arch = GetRegisterInfoInterface().GetTargetArchitecture();
     switch (fpr_type)
     {
     case FPRType::eFPRTypeFXSAVE:
-        return NativeRegisterContextLinux::ReadFPR();
+        // For 32-bit inferiors on x86_32/x86_64 architectures,
+        // FXSAVE area can be read using PTRACE_GETREGSET ptrace api
+        // For 64-bit inferiors on x86_64 architectures,
+        // FXSAVE area can be read using PTRACE_GETFPREGS ptrace api
+        switch (target_arch.GetMachine ())
+        {
+            case llvm::Triple::x86:
+                return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_PRXFPREG);
+            case llvm::Triple::x86_64:
+                return NativeRegisterContextLinux::ReadFPR();
+            default:
+                assert(false && "Unhandled target architecture.");
+                break;
+        }
     case FPRType::eFPRTypeXSAVE:
         return ReadRegisterSet(&m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
     default:




More information about the lldb-commits mailing list