uweigand retitled this revision from "Add new ABI callback to return CFA 
offset" to "Add new ABI callback to provide fallback unwind register locations".
uweigand updated the summary for this revision.
uweigand updated this revision to Diff 53502.

http://reviews.llvm.org/D18977

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

Index: source/Target/ABI.cpp
===================================================================
--- source/Target/ABI.cpp
+++ 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: source/Plugins/Process/Utility/RegisterContextLLDB.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ 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;
Index: include/lldb/Target/ABI.h
===================================================================
--- include/lldb/Target/ABI.h
+++ 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: include/lldb/Symbol/UnwindPlan.h
===================================================================
--- include/lldb/Symbol/UnwindPlan.h
+++ include/lldb/Symbol/UnwindPlan.h
@@ -116,6 +116,12 @@
                 return m_type == unspecified; 
             }
 
+            bool
+            IsUndefined () const
+            {
+                return m_type == undefined;
+            }
+
             bool 
             IsCFAPlusOffset () const
             {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to