[Lldb-commits] [lldb] r252298 - Fix for AArch64 watchpoint cache corruption in case of ptrace failure

Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Fri Nov 6 04:56:34 PST 2015


Author: omjavaid
Date: Fri Nov  6 06:56:34 2015
New Revision: 252298

URL: http://llvm.org/viewvc/llvm-project?rev=252298&view=rev
Log:
Fix for AArch64 watchpoint cache corruption in case of ptrace failure

Same fix has been submitted for Arm.

Review can be found here:

Differential revision: http://reviews.llvm.org/D14051


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

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp?rev=252298&r1=252297&r2=252298&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp Fri Nov  6 06:56:34 2015
@@ -435,7 +435,7 @@ NativeRegisterContextLinux_arm64::SetHar
      if (bp_index == LLDB_INVALID_INDEX32)
         return LLDB_INVALID_INDEX32;
 
-    // Add new or update existing watchpoint
+    // Add new or update existing breakpoint
     if ((m_hbr_regs[bp_index].control & 1) == 0)
     {
         m_hbr_regs[bp_index].address = addr;
@@ -446,7 +446,13 @@ NativeRegisterContextLinux_arm64::SetHar
         error = WriteHardwareDebugRegs(eDREGTypeBREAK);
 
         if (error.Fail())
+        {
+            m_hbr_regs[bp_index].address = 0;
+            m_hbr_regs[bp_index].control &= ~1;
+            m_hbr_regs[bp_index].refcount = 0;
+
             return LLDB_INVALID_INDEX32;
+        }
     }
     else
         m_hbr_regs[bp_index].refcount++;
@@ -481,6 +487,11 @@ NativeRegisterContextLinux_arm64::ClearH
     }
     else if (m_hbr_regs[hw_idx].refcount == 1)
     {
+        // Create a backup we can revert to in case of failure.
+        lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
+        uint32_t tempControl = m_hbr_regs[hw_idx].control;
+        uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount;
+
         m_hbr_regs[hw_idx].control &= ~1;
         m_hbr_regs[hw_idx].address = 0;
         m_hbr_regs[hw_idx].refcount = 0;
@@ -489,7 +500,13 @@ NativeRegisterContextLinux_arm64::ClearH
         WriteHardwareDebugRegs(eDREGTypeBREAK);
 
         if (error.Fail())
+        {
+            m_hbr_regs[hw_idx].control = tempControl;
+            m_hbr_regs[hw_idx].address = tempAddr;
+            m_hbr_regs[hw_idx].refcount = tempRefCount;
+
             return false;
+        }
 
         return true;
     }
@@ -595,7 +612,13 @@ NativeRegisterContextLinux_arm64::SetHar
         error = WriteHardwareDebugRegs(eDREGTypeWATCH);
 
         if (error.Fail())
+        {
+            m_hwp_regs[wp_index].address = 0;
+            m_hwp_regs[wp_index].control &= ~1;
+            m_hwp_regs[wp_index].refcount = 0;
+
             return LLDB_INVALID_INDEX32;
+        }
     }
     else
         m_hwp_regs[wp_index].refcount++;
@@ -630,6 +653,11 @@ NativeRegisterContextLinux_arm64::ClearH
     }
     else if (m_hwp_regs[wp_index].refcount == 1)
     {
+        // Create a backup we can revert to in case of failure.
+        lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
+        uint32_t tempControl = m_hwp_regs[wp_index].control;
+        uint32_t tempRefCount = m_hwp_regs[wp_index].refcount;
+
         // Update watchpoint in local cache
         m_hwp_regs[wp_index].control &= ~1;
         m_hwp_regs[wp_index].address = 0;
@@ -639,7 +667,13 @@ NativeRegisterContextLinux_arm64::ClearH
         error = WriteHardwareDebugRegs(eDREGTypeWATCH);
 
         if (error.Fail())
+        {
+            m_hwp_regs[wp_index].control = tempControl;
+            m_hwp_regs[wp_index].address = tempAddr;
+            m_hwp_regs[wp_index].refcount = tempRefCount;
+
             return false;
+        }
 
         return true;
     }
@@ -663,10 +697,18 @@ NativeRegisterContextLinux_arm64::ClearA
     if (error.Fail())
         return error;
 
+    lldb::addr_t tempAddr = 0;
+    uint32_t tempControl = 0, tempRefCount = 0;
+
     for (uint32_t i = 0; i < m_max_hwp_supported; i++)
     {
         if (m_hwp_regs[i].control & 0x01)
         {
+            // Create a backup we can revert to in case of failure.
+            tempAddr = m_hwp_regs[i].address;
+            tempControl = m_hwp_regs[i].control;
+            tempRefCount = m_hwp_regs[i].refcount;
+
             // Clear watchpoints in local cache
             m_hwp_regs[i].control &= ~1;
             m_hwp_regs[i].address = 0;
@@ -676,7 +718,13 @@ NativeRegisterContextLinux_arm64::ClearA
             error = WriteHardwareDebugRegs(eDREGTypeWATCH);
 
             if (error.Fail())
+            {
+                m_hwp_regs[i].control = tempControl;
+                m_hwp_regs[i].address = tempAddr;
+                m_hwp_regs[i].refcount = tempRefCount;
+
                 return error;
+            }
         }
     }
 




More information about the lldb-commits mailing list