[Lldb-commits] [PATCH] D18977: Add new ABI callback to return CFA offset

Ulrich Weigand via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 11 11:28:48 PDT 2016

uweigand created this revision.
uweigand added reviewers: jasonmolenda, clayborg.
uweigand added a subscriber: lldb-commits.

If the UnwindPlan did not identify how to unwind the stack pointer
register, LLDB currently assumes it can determine to caller's SP
from the current frame's CFA.  This is true on most platforms
where CFA is by definition equal to the incoming SP at function

However, on the s390x target, we instead define the CFA to equal
the incoming SP plus an offset of 160 bytes.  This is because
our ABI defines that the caller has to provide a register save
area of size 160 bytes.  This area is allocated by the caller,
but is considered part of the callee's stack frame, and therefore
the CFA is defined as pointing to the top of this area.

In order to make stack unwinding work correctly on s390x in those
cases, LLDB common code needs to be aware of this CFA offset.
For this purpose, this patch adds a new ABI member function
CFAOffset, which defaults to always returning 0, and subtracts
that value from the CFA when unwinding the stack pointer value.

This patch in itself is a no-op for all existing platforms.
But it is a pre-requisite for adding s390x support.



Index: source/Plugins/Process/Utility/RegisterContextLLDB.cpp
--- source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -1390,34 +1390,36 @@
+    ExecutionContext exe_ctx(m_thread.shared_from_this());
+    Process *process = exe_ctx.GetProcessPtr();
+    ABI *abi = process ? process->GetABI().get() : NULL;
     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.
+        // On other platforms, there may be a constant offset.  Consult the abi->CFAOffset callback.
         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;
+            regloc.location.inferred_value = m_cfa - (abi ? abi->CFAOffset() : 0);
             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.
-        ABI *abi = process ? process->GetABI().get() : NULL;
         if (abi)
             const RegisterInfo *reg_info = GetRegisterInfoAtIndex(regnum.GetAsKind (eRegisterKindLLDB));
Index: include/lldb/Target/ABI.h
--- include/lldb/Target/ABI.h
+++ include/lldb/Target/ABI.h
@@ -107,6 +107,16 @@
     virtual bool
     CreateDefaultUnwindPlan (UnwindPlan &unwind_plan) = 0;
+    virtual int64_t
+    CFAOffset () const
+    {
+        // On most targets, the CFA equals the incoming stack pointer value.
+        // On some targets like SystemZ, however, the CFA is at a constant
+        // offset relative to the incoming stack pointer value.
+        // Return this offset.
+        return 0;
+    }
     virtual bool
     RegisterIsVolatile (const RegisterInfo *reg_info) = 0;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18977.53292.patch
Type: text/x-patch
Size: 3101 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160411/4b142928/attachment.bin>

More information about the lldb-commits mailing list