[Lldb-commits] [lldb] r153300 - in /lldb/trunk/tools/debugserver/source/MacOSX/arm: DNBArchImpl.cpp DNBArchImpl.h

Johnny Chen johnny.chen at apple.com
Thu Mar 22 18:24:53 PDT 2012


Author: johnny
Date: Thu Mar 22 20:24:52 2012
New Revision: 153300

URL: http://llvm.org/viewvc/llvm-project?rev=153300&view=rev
Log:
Make arm debugserver handle setting a watchpoint on, for example, (uint64_t)variable.
We do this by delegating to two available Watchpoint Register Pairs (wvr, wcr).  With
each pair handling the 4 bytes of (uint64_t)variable.

Modified:
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp?rev=153300&r1=153299&r2=153300&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp Thu Mar 22 20:24:52 2012
@@ -366,7 +366,16 @@
     {
         if (m_watchpoint_hw_index >= 0)
         {
-            DisableHardwareWatchpoint(m_watchpoint_hw_index);
+            kern_return_t kret = GetDBGState(false);
+            if (kret == KERN_SUCCESS && !IsWatchpointEnabled(m_state.dbg, m_watchpoint_hw_index)) {
+                // The watchpoint might have been disabled by the user.  We don't need to do anything at all
+                // to enable hardware single stepping.
+                m_watchpoint_did_occur = false;
+                m_watchpoint_hw_index = -1;
+                return;
+            }
+
+            DisableHardwareWatchpoint0(m_watchpoint_hw_index, true);
             DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called",
                              m_watchpoint_hw_index);
 
@@ -403,7 +412,7 @@
         {
             if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0)
             {
-                EnableHardwareWatchpoint(m_watchpoint_hw_index);
+                EnableHardwareWatchpoint0(m_watchpoint_hw_index, true);
                 m_watchpoint_resume_single_step_enabled = false;
                 m_watchpoint_did_occur = false;
                 m_watchpoint_hw_index = -1;
@@ -2383,6 +2392,10 @@
     return false;
 }
 
+// This stores the lo->hi mappings.  It's safe to initialize to all 0's
+// since hi > lo and therefore LoHi[i] cannot be 0.
+static uint32_t LoHi[16] = { 0 };
+
 uint32_t
 DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
 {
@@ -2398,7 +2411,24 @@
     if (read == false && write == false)
         return INVALID_NUB_HW_INDEX;
 
-    // Can't watch more than 4 bytes per WVR/WCR pair
+    // Divide-and-conquer for size == 8.
+    if (size == 8)
+    {
+        uint32_t lo = EnableHardwareWatchpoint(addr, 4, read, write);
+        if (lo == INVALID_NUB_HW_INDEX)
+            return INVALID_NUB_HW_INDEX;
+        uint32_t hi = EnableHardwareWatchpoint(addr+4, 4, read, write);
+        if (hi == INVALID_NUB_HW_INDEX)
+        {
+            DisableHardwareWatchpoint(lo);
+            return INVALID_NUB_HW_INDEX;
+        }
+        // Tag thsi lo->hi mapping in our database.
+        LoHi[lo] = hi;
+        return lo;
+    }
+
+    // Otherwise, can't watch more than 4 bytes per WVR/WCR pair
     if (size > 4)
         return INVALID_NUB_HW_INDEX;
 
@@ -2475,57 +2505,68 @@
 }
 
 bool
-DNBArchMachARM::EnableHardwareWatchpoint (uint32_t hw_index)
+DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate)
 {
     kern_return_t kret = GetDBGState(false);
+    if (kret != KERN_SUCCESS)
+        return false;
 
     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
-    if (kret == KERN_SUCCESS)
-    {
-        if (hw_index < num_hw_points)
-        {
-            m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE;
-            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
-                    hw_index,
-                    hw_index,
-                    m_state.dbg.__wvr[hw_index],
-                    hw_index,
-                    m_state.dbg.__wcr[hw_index]);
+    if (hw_index >= num_hw_points)
+        return false;
 
-            kret = SetDBGState();
+    if (Delegate && LoHi[hw_index]) {
+        // Enable lo and hi watchpoint hardware indexes.
+        return EnableHardwareWatchpoint0(hw_index, false) &&
+            EnableHardwareWatchpoint0(LoHi[hw_index], false);
+    }
+
+    m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE;
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
+                     hw_index,
+                     hw_index,
+                     m_state.dbg.__wvr[hw_index],
+                     hw_index,
+                     m_state.dbg.__wcr[hw_index]);
 
-            if (kret == KERN_SUCCESS)
-                return true;
-        }
-    }
-    return false;
+    kret = SetDBGState();
+
+    return (kret == KERN_SUCCESS);
 }
 
 bool
 DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index)
 {
+    return DisableHardwareWatchpoint0(hw_index, true);
+}
+bool
+DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate)
+{
     kern_return_t kret = GetDBGState(false);
+    if (kret != KERN_SUCCESS)
+        return false;
 
     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
-    if (kret == KERN_SUCCESS)
-    {
-        if (hw_index < num_hw_points)
-        {
-            m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE);
-            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
-                    hw_index,
-                    hw_index,
-                    m_state.dbg.__wvr[hw_index],
-                    hw_index,
-                    m_state.dbg.__wcr[hw_index]);
+    if (hw_index >= num_hw_points)
+        return false;
 
-            kret = SetDBGState();
+    if (Delegate && LoHi[hw_index]) {
+        // Disable lo and hi watchpoint hardware indexes.
+        return DisableHardwareWatchpoint0(hw_index, false) &&
+            DisableHardwareWatchpoint0(LoHi[hw_index], false);
+    }
+
+    m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
+                     hw_index,
+                     hw_index,
+                     m_state.dbg.__wvr[hw_index],
+                     hw_index,
+                     m_state.dbg.__wcr[hw_index]);
 
-            if (kret == KERN_SUCCESS)
-                return true;
-        }
-    }
-    return false;
+    kret = SetDBGState();
+
+    return (kret == KERN_SUCCESS);
 }
 
 // {0} -> __bvr[16], {0} -> __bcr[16], {0} --> __wvr[16], {0} -> __wcr{16}

Modified: lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h?rev=153300&r1=153299&r2=153300&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/arm/DNBArchImpl.h Thu Mar 22 20:24:52 2012
@@ -81,8 +81,9 @@
     virtual uint32_t        EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size);
     virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write);
     virtual bool            DisableHardwareBreakpoint (uint32_t hw_break_index);
-    virtual bool            EnableHardwareWatchpoint (uint32_t hw_break_index);
     virtual bool            DisableHardwareWatchpoint (uint32_t hw_break_index);
+    virtual bool            EnableHardwareWatchpoint0 (uint32_t hw_break_index, bool Delegate);
+    virtual bool            DisableHardwareWatchpoint0 (uint32_t hw_break_index, bool Delegate);
     virtual bool            StepNotComplete ();
     virtual void            HardwareWatchpointStateChanged ();
     virtual uint32_t        GetHardwareWatchpointHit(nub_addr_t &addr);





More information about the lldb-commits mailing list