This revision was automatically updated to reflect the committed changes.
Closed by commit rL266307: Add new ABI callback to provide fallback unwind 
register locations (authored by uweigand).

Changed prior to commit:
  http://reviews.llvm.org/D18977?vs=53502&id=53706#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D18977

Files:
  lldb/trunk/include/lldb/Symbol/UnwindPlan.h
  lldb/trunk/include/lldb/Target/ABI.h
  lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
  lldb/trunk/source/Target/ABI.cpp

Index: lldb/trunk/include/lldb/Target/ABI.h
===================================================================
--- lldb/trunk/include/lldb/Target/ABI.h
+++ lldb/trunk/include/lldb/Target/ABI.h
@@ -16,6 +16,7 @@
 // Project includes
 #include "lldb/Core/Error.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Symbol/UnwindPlan.h"
 #include "lldb/lldb-private.h"
 
 #include "llvm/ADT/ArrayRef.h"
@@ -110,6 +111,10 @@
     virtual bool
     RegisterIsVolatile (const RegisterInfo *reg_info) = 0;
 
+    virtual bool
+    GetFallbackRegisterLocation (const RegisterInfo *reg_info,
+                                 UnwindPlan::Row::RegisterLocation &unwind_regloc);
+
     // Should take a look at a call frame address (CFA) which is just the stack
     // pointer value upon entry to a function. ABIs usually impose alignment
     // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
Index: lldb/trunk/include/lldb/Symbol/UnwindPlan.h
===================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindPlan.h
+++ lldb/trunk/include/lldb/Symbol/UnwindPlan.h
@@ -116,6 +116,12 @@
                 return m_type == unspecified; 
             }
 
+            bool
+            IsUndefined () const
+            {
+                return m_type == undefined;
+            }
+
             bool 
             IsCFAPlusOffset () const
             {
Index: lldb/trunk/source/Target/ABI.cpp
===================================================================
--- lldb/trunk/source/Target/ABI.cpp
+++ lldb/trunk/source/Target/ABI.cpp
@@ -205,3 +205,27 @@
     assert( !"Should never get here!" );
     return false;
 }
+
+bool
+ABI::GetFallbackRegisterLocation (const RegisterInfo *reg_info,
+                                  UnwindPlan::Row::RegisterLocation &unwind_regloc)
+{
+    // Did the UnwindPlan fail to give us the caller's stack pointer?
+    // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as
+    // the caller's stack pointer.  This is true on x86-32/x86-64 at least.
+    if (reg_info->kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP)
+    {
+        unwind_regloc.SetIsCFAPlusOffset(0);
+        return true;
+    }
+
+    // If a volatile register is being requested, we don't want to forward the next frame's register contents
+    // up the stack -- the register is not retrievable at this frame.
+    if (RegisterIsVolatile(reg_info))
+    {
+        unwind_regloc.SetUndefined();
+        return true;
+    }
+
+    return false;
+}
Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
===================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -1390,45 +1390,28 @@
         }
     }
 
-    if (have_unwindplan_regloc == false)
-    {
-        // Did the UnwindPlan fail to give us the caller's stack pointer?  
-        // The stack pointer is defined to be the same as THIS frame's CFA, so return the CFA value as
-        // the caller's stack pointer.  This is true on x86-32/x86-64 at least.
-
-        RegisterNumber sp_regnum (m_thread, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
-        if (sp_regnum.GetAsKind (eRegisterKindLLDB) != LLDB_INVALID_REGNUM 
-            && sp_regnum.GetAsKind (eRegisterKindLLDB) == regnum.GetAsKind (eRegisterKindLLDB))
-        {
-            // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value)
-            assert (sizeof (addr_t) <= sizeof (uint64_t));
-            regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
-            regloc.location.inferred_value = m_cfa;
-            m_registers[regnum.GetAsKind (eRegisterKindLLDB)] = regloc;
-            UnwindLogMsg ("supplying caller's stack pointer %s (%d) value, computed from CFA", 
-                        regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
-            return UnwindLLDB::RegisterSearchResult::eRegisterFound;
-        }
-    }
-
     ExecutionContext exe_ctx(m_thread.shared_from_this());
     Process *process = exe_ctx.GetProcessPtr();
     if (have_unwindplan_regloc == false)
     {
-        // If a volatile register is being requested, we don't want to forward the next frame's register contents
-        // up the stack -- the register is not retrievable at this frame.
+        // If the UnwindPlan failed to give us an unwind location for this register, we may be able to fall back
+        // to some ABI-defined default.  For example, some ABIs allow to determine the caller's SP via the CFA.
+        // Also, the ABI may set volatile registers to the undefined state.
         ABI *abi = process ? process->GetABI().get() : NULL;
         if (abi)
         {
             const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB));
-            if (reg_info && abi->RegisterIsVolatile (reg_info))
+            if (reg_info && abi->GetFallbackRegisterLocation (reg_info, unwindplan_regloc))
             {
-                UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
+                UnwindLogMsg ("supplying caller's saved %s (%d)'s location using ABI default",
                               regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
-                return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
+                have_unwindplan_regloc = true;
             }
         }
+    }
 
+    if (have_unwindplan_regloc == false)
+    {
         if (IsFrameZero ())
         {
             // This is frame 0 - we should return the actual live register context value
@@ -1468,6 +1451,13 @@
         return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
     }
 
+    if (unwindplan_regloc.IsUndefined())
+    {
+         UnwindLogMsg ("did not supply reg location for %s (%d) because it is volatile",
+                       regnum.GetName(), regnum.GetAsKind (eRegisterKindLLDB));
+         return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
+    }
+
     if (unwindplan_regloc.IsSame())
     {
         regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to