[Lldb-commits] [lldb] r143423 - in /lldb/trunk/source/Plugins/Process/Utility: RegisterContextLLDB.cpp RegisterContextLLDB.h UnwindLLDB.cpp UnwindLLDB.h

Jason Molenda jmolenda at apple.com
Mon Oct 31 20:21:25 PDT 2011


Author: jmolenda
Date: Mon Oct 31 22:21:25 2011
New Revision: 143423

URL: http://llvm.org/viewvc/llvm-project?rev=143423&view=rev
Log:
Restructure the relationship between UnwindLLDB and the
RegisterContextLLDBs it contains.

Previously RegisterContextLLDB objects had a pointer to their "next"
frame down the stack.  e.g. stack starts at frame 0; frame 3 has a
pointer to frame 2.  This is used to retreive callee saved register
values.  When debugging an inferior that has blown out its own stack,
however, this could result in lldb blowing out its own stack while
recursing down to retrieve register values.

RegisterContextLLDB no longer has a pointer to its next frame; it 
has a reference to the UnwindLLDB which contains it.  When it needs
to retrieve a reg value, it asks the UnwindLLDB for that reg value
and UnwindLLDB iterates through the frames until it finds a location.



Modified:
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=143423&r1=143422&r2=143423&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Mon Oct 31 22:21:25 2011
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "RegisterContextLLDB.h"
 
 #include "lldb/lldb-private.h"
 #include "lldb/Core/Address.h"
@@ -28,20 +27,21 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 
+#include "RegisterContextLLDB.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
-
 RegisterContextLLDB::RegisterContextLLDB 
 (
     Thread& thread, 
     const SharedPtr &next_frame,
     SymbolContext& sym_ctx,
-    uint32_t frame_number
+    uint32_t frame_number,
+    UnwindLLDB& unwind_lldb
 ) :
     RegisterContext (thread, frame_number), 
     m_thread(thread), 
-    m_next_frame(next_frame),
     m_fast_unwind_plan_sp (),
     m_full_unwind_plan_sp (),
     m_all_registers_available(false),
@@ -54,7 +54,8 @@
     m_sym_ctx(sym_ctx),
     m_sym_ctx_valid (false),
     m_frame_number (frame_number),
-    m_registers()
+    m_registers(),
+    m_parent_unwind (unwind_lldb)
 {
     m_sym_ctx.Clear();
     m_sym_ctx_valid = false;
@@ -70,8 +71,8 @@
 
     // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
     if (IsFrameZero() 
-        || m_next_frame->m_frame_type == eSigtrampFrame 
-        || m_next_frame->m_frame_type == eDebuggerFrame)
+        || next_frame->m_frame_type == eSigtrampFrame 
+        || next_frame->m_frame_type == eDebuggerFrame)
     {
         m_all_registers_available = true;
     }
@@ -207,7 +208,7 @@
         return;
     }
     
-    if (!m_next_frame->IsValid())
+    if (!GetNextFrame().get() || !GetNextFrame()->IsValid())
     {
         m_frame_type = eNotAValidFrame;
         return;
@@ -331,8 +332,8 @@
     // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp),
     // and our "current" pc is the start of a function...
     if (m_sym_ctx_valid
-        && m_next_frame->m_frame_type != eSigtrampFrame
-        && m_next_frame->m_frame_type != eDebuggerFrame
+        && GetNextFrame()->m_frame_type != eSigtrampFrame
+        && GetNextFrame()->m_frame_type != eDebuggerFrame
         && addr_range.GetBaseAddress().IsValid()
         && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()
         && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset())
@@ -453,7 +454,7 @@
     // break out to avoid a possible infinite loop in lldb trying to unwind the stack.
     addr_t next_frame_cfa;
     addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS;
-    if (m_next_frame.get() && m_next_frame->GetCFA(next_frame_cfa))
+    if (GetNextFrame().get() && GetNextFrame()->GetCFA(next_frame_cfa))
     {
         bool repeating_frames = false;
         if (next_frame_cfa == m_cfa)
@@ -462,7 +463,7 @@
         }
         else
         {
-            if (m_next_frame->GetNextFrame() && m_next_frame->GetNextFrame()->GetCFA(next_next_frame_cfa)
+            if (GetNextFrame()->GetNextFrame() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa)
                 && next_next_frame_cfa == m_cfa)
             {
                 repeating_frames = true;
@@ -492,10 +493,7 @@
 bool
 RegisterContextLLDB::IsFrameZero () const
 {
-    if (m_next_frame.get () == NULL)
-        return true;
-    else
-        return false;
+    return m_frame_number == 0;
 }
 
 
@@ -575,8 +573,8 @@
 
     bool behaves_like_zeroth_frame = false;
     if (IsFrameZero () 
-        || m_next_frame->m_frame_type == eSigtrampFrame
-        || m_next_frame->m_frame_type == eDebuggerFrame)
+        || GetNextFrame()->m_frame_type == eSigtrampFrame
+        || GetNextFrame()->m_frame_type == eDebuggerFrame)
     {
         behaves_like_zeroth_frame = true;
         // If this frame behaves like a 0th frame (currently executing or 
@@ -720,7 +718,7 @@
 }
 
 bool
-RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (RegisterLocation regloc, 
+RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, 
                                                             const RegisterInfo *reg_info,
                                                             RegisterValue &value)
 {
@@ -730,7 +728,7 @@
 
     switch (regloc.type)
     {
-    case eRegisterInRegister:
+    case UnwindLLDB::RegisterLocation::eRegisterInRegister:
         {
             const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
             if (IsFrameZero ()) 
@@ -739,20 +737,20 @@
             }
             else
             {
-                success = m_next_frame->ReadRegister (other_reg_info, value);
+                success = GetNextFrame()->ReadRegister (other_reg_info, value);
             }
         }
         break;
-    case eRegisterValueInferred:
+    case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
         success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size);
         break;
             
-    case eRegisterNotSaved:
+    case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
         break;
-    case eRegisterSavedAtHostMemoryLocation:
+    case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
         assert ("FIXME debugger inferior function call unwind");
         break;
-    case eRegisterSavedAtMemoryLocation:
+    case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
         {
             Error error (ReadRegisterValueFromMemory(reg_info, 
                                                      regloc.location.target_memory_location, 
@@ -769,7 +767,7 @@
 }
 
 bool
-RegisterContextLLDB::WriteRegisterValueToRegisterLocation (RegisterLocation regloc, 
+RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, 
                                                            const RegisterInfo *reg_info,
                                                            const RegisterValue &value)
 {
@@ -780,7 +778,7 @@
     
     switch (regloc.type)
     {
-        case eRegisterInRegister:
+        case UnwindLLDB::RegisterLocation::eRegisterInRegister:
             {
                 const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number);
                 if (IsFrameZero ()) 
@@ -789,17 +787,17 @@
                 }
                 else
                 {
-                    success = m_next_frame->WriteRegister (other_reg_info, value);
+                    success = GetNextFrame()->WriteRegister (other_reg_info, value);
                 }
             }
             break;
-        case eRegisterValueInferred:
-        case eRegisterNotSaved:
+        case UnwindLLDB::RegisterLocation::eRegisterValueInferred:
+        case UnwindLLDB::RegisterLocation::eRegisterNotSaved:
             break;
-        case eRegisterSavedAtHostMemoryLocation:
+        case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation:
             assert ("FIXME debugger inferior function call unwind");
             break;
-        case eRegisterSavedAtMemoryLocation:
+        case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation:
             {
                 Error error (WriteRegisterValueToMemory (reg_info, 
                                                          regloc.location.target_memory_location, 
@@ -825,14 +823,14 @@
 // Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
 
 bool
-RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLocation &regloc)
+RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, bool check_next_frame)
 {
     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
 
     // Have we already found this register location?
     if (!m_registers.empty())
     {
-        std::map<uint32_t, RegisterLocation>::const_iterator iterator;
+        std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator;
         iterator = m_registers.find (lldb_regnum);
         if (iterator != m_registers.end())
         {
@@ -849,7 +847,7 @@
     {
         // 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 = eRegisterValueInferred;
+        regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
         regloc.location.inferred_value = m_cfa;
         m_registers[lldb_regnum] = regloc;
         return true;
@@ -930,7 +928,7 @@
 
     if (have_unwindplan_regloc == false)
     {
-        // If a volatile register is being requested, we don't want to forward m_next_frame's register contents 
+        // 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 = m_thread.GetProcess().GetABI().get();
         if (abi)
@@ -951,8 +949,8 @@
         if (IsFrameZero ())
         {
             // This is frame 0 - we should return the actual live register context value
-            RegisterLocation new_regloc;
-            new_regloc.type = eRegisterInRegister;
+            lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+            new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
             new_regloc.location.register_number = lldb_regnum;
             m_registers[lldb_regnum] = new_regloc;
             regloc = new_regloc;
@@ -960,7 +958,8 @@
         }
         else
         {
-            return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc);
+            if (check_next_frame)
+                return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1);
         }
         if (log)
         {
@@ -974,8 +973,8 @@
     // unwindplan_regloc has valid contents about where to retrieve the register
     if (unwindplan_regloc.IsUnspecified())
     {
-        RegisterLocation new_regloc;
-        new_regloc.type = eRegisterNotSaved;
+        lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+        new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
         m_registers[lldb_regnum] = new_regloc;
         if (log)
         {
@@ -1000,14 +999,17 @@
         }
         else
         {
-            return m_next_frame->SavedLocationForRegister (lldb_regnum, regloc);
+            if (check_next_frame)
+                return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1);
+            else
+                return false;
         }
     }
 
     if (unwindplan_regloc.IsCFAPlusOffset())
     {
         int offset = unwindplan_regloc.GetOffset();
-        regloc.type = eRegisterValueInferred;
+        regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
         regloc.location.inferred_value = m_cfa + offset;
         m_registers[lldb_regnum] = regloc;
         return true;
@@ -1016,7 +1018,7 @@
     if (unwindplan_regloc.IsAtCFAPlusOffset())
     {
         int offset = unwindplan_regloc.GetOffset();
-        regloc.type = eRegisterSavedAtMemoryLocation;
+        regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
         regloc.location.target_memory_location = m_cfa + offset;
         m_registers[lldb_regnum] = regloc;
         return true;
@@ -1036,7 +1038,7 @@
             }
             return false;
         }
-        regloc.type = eRegisterInRegister;
+        regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
         regloc.location.register_number = row_regnum_in_lldb;
         m_registers[lldb_regnum] = regloc;
         return true;
@@ -1058,14 +1060,14 @@
             val = result.GetScalar().ULongLong();
             if (unwindplan_regloc.IsDWARFExpression())
              {
-                regloc.type = eRegisterValueInferred;
+                regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
                 regloc.location.inferred_value = val;
                 m_registers[lldb_regnum] = regloc;
                 return true;
             }
             else
             {
-               regloc.type = eRegisterSavedAtMemoryLocation;
+               regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
                regloc.location.target_memory_location = val;
                m_registers[lldb_regnum] = regloc;
                return true;
@@ -1135,8 +1137,8 @@
         return false;
     }
 
-    RegisterLocation regloc;
-    if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
+    lldb_private::UnwindLLDB::RegisterLocation regloc;
+    if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
     {
         return false;
     }
@@ -1177,9 +1179,9 @@
         return m_thread.GetRegisterContext()->ReadRegister (reg_info, value);
     }
 
-    RegisterLocation regloc;
+    lldb_private::UnwindLLDB::RegisterLocation regloc;
     // Find out where the NEXT frame saved THIS frame's register contents
-    if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
+    if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
         return false;
 
     return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value);
@@ -1212,9 +1214,9 @@
         return m_thread.GetRegisterContext()->WriteRegister (reg_info, value);
     }
 
-    RegisterLocation regloc;
+    lldb_private::UnwindLLDB::RegisterLocation regloc;
     // Find out where the NEXT frame saved THIS frame's register contents
-    if (!m_next_frame->SavedLocationForRegister (lldb_regnum, regloc))
+    if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1))
         return false;
 
     return WriteRegisterValueToRegisterLocation (regloc, reg_info, value);
@@ -1253,9 +1255,12 @@
 
 
 RegisterContextLLDB::SharedPtr
-RegisterContextLLDB::GetNextFrame ()
+RegisterContextLLDB::GetNextFrame () const
 {
-    return m_next_frame;
+    RegisterContextLLDB::SharedPtr regctx;
+    if (m_frame_number == 0)
+      return regctx;
+    return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number - 1);
 }
 
 // Retrieve the address of the start of the function of THIS frame
@@ -1302,3 +1307,4 @@
         return false;
     }
 }
+

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=143423&r1=143422&r2=143423&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Mon Oct 31 22:21:25 2011
@@ -16,6 +16,11 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Symbol/UnwindPlan.h"
 #include "lldb/Symbol/SymbolContext.h"
+#include "UnwindLLDB.h"
+
+namespace lldb_private {
+
+class UnwindLLDB;
 
 class RegisterContextLLDB : public lldb_private::RegisterContext
 {
@@ -25,7 +30,7 @@
     RegisterContextLLDB (lldb_private::Thread &thread,
                          const SharedPtr& next_frame,
                          lldb_private::SymbolContext& sym_ctx,
-                         uint32_t frame_number);
+                         uint32_t frame_number, lldb_private::UnwindLLDB& unwind_lldb);
 
     ///
     // pure virtual functions from the base class that we must implement
@@ -86,33 +91,11 @@
         eNotAValidFrame  // this frame is invalid for some reason - most likely it is past the top (end) of the stack
     };
 
-    enum RegisterLocationTypes
-    {
-        eRegisterNotSaved = 0,          // register was not preserved by callee.  If volatile reg, is unavailable
-        eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location)
-        eRegisterInRegister,            // register is available in a (possible other) register (register_number)
-        eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
-        eRegisterValueInferred          // register val was computed (and is in inferred_value)
-    };
-
-    struct RegisterLocation
-    {
-        int type;
-        union
-        {
-            lldb::addr_t target_memory_location;
-            uint32_t     register_number;       // in eRegisterKindLLDB register numbering system
-            void*        host_memory_location;
-            uint64_t     inferred_value;        // eRegisterValueInferred - e.g. stack pointer == cfa + offset
-        } location;
-    };
-
+    // UnwindLLDB needs to pass around references to RegisterLocations
+    friend class UnwindLLDB;
 
     // Indicates whether this frame is frame zero -- the currently
-    // executing frame -- or not.  If it is not frame zero, m_next_frame's
-    // shared pointer holds a pointer to the RegisterContextLLDB
-    // object "below" this frame, i.e. this frame called m_next_frame's
-    // function.
+    // executing frame -- or not.  
     bool
     IsFrameZero () const;
 
@@ -123,7 +106,7 @@
     InitializeNonZerothFrame();
 
     SharedPtr
-    GetNextFrame ();
+    GetNextFrame () const;
 
     // Provide a location for where THIS function saved the CALLER's register value
     // Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
@@ -137,22 +120,25 @@
     // stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
     // as the requesting frame's.
     //
+    // NB this function takes a "check_next_frame" boolean which indicates whether it should call back to the
+    // containing UnwindLLDB object to iterate the search down the stack (true) or if this call should look for
+    // a register save for that reg in the current frame only (false).  Allows UnwindLLDB to iterate through the
+    // RegisterContextLLDB's instead of using recursion to find saved register values.
     bool
-    SavedLocationForRegister (uint32_t lldb_regnum, RegisterLocation &regloc);
+    SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, bool check_next_frame);
 
     bool
-    ReadRegisterValueFromRegisterLocation (RegisterLocation regloc, 
+    ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, 
                                            const lldb_private::RegisterInfo *reg_info,
                                            lldb_private::RegisterValue &value);
 
     bool
-    WriteRegisterValueToRegisterLocation (RegisterLocation regloc, 
+    WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, 
                                           const lldb_private::RegisterInfo *reg_info,
                                           const lldb_private::RegisterValue &value);
 
     // Get the contents of a general purpose (address-size) register for this frame 
-    // (usually retrieved from the m_next_frame)
-    // m_base_reg_ectx and m_next_frame should both be initialized appropriately before calling.
+    // (usually retrieved from the next frame)
     bool
     ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
 
@@ -164,8 +150,6 @@
 
     lldb_private::Thread& m_thread;
     
-    SharedPtr m_next_frame;
-
     ///
     // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
     // i.e. where THIS frame saved them
@@ -194,9 +178,11 @@
     lldb_private::SymbolContext& m_sym_ctx;
     bool m_sym_ctx_valid;                         // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
 
-    uint32_t m_frame_number;                      // What stack frame level this frame is - used for debug logging
+    uint32_t m_frame_number;                      // What stack frame this RegisterContext is
 
-    std::map<uint32_t, RegisterLocation> m_registers; // where to find reg values for this frame
+    std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> m_registers; // where to find reg values for this frame
+
+    lldb_private::UnwindLLDB& m_parent_unwind;    // The UnwindLLDB that is creating this RegisterContextLLDB
 
     //------------------------------------------------------------------
     // For RegisterContextLLDB only
@@ -205,4 +191,6 @@
     DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB);
 };
 
+} // namespace lldb_private
+
 #endif  // lldb_RegisterContextLLDB_h_

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=143423&r1=143422&r2=143423&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Mon Oct 31 22:21:25 2011
@@ -69,10 +69,10 @@
 {
     // First, set up the 0th (initial) frame
     CursorSP first_cursor_sp(new Cursor ());
-    RegisterContextLLDB::SharedPtr reg_ctx_sp (new RegisterContextLLDB (m_thread, 
-                                                                        RegisterContextLLDB::SharedPtr(), 
+    RegisterContextLLDBSharedPtr reg_ctx_sp (new RegisterContextLLDB (m_thread, 
+                                                                        RegisterContextLLDBSharedPtr(), 
                                                                         first_cursor_sp->sctx, 
-                                                                        0));
+                                                                        0, *this));
     if (reg_ctx_sp.get() == NULL)
         return false;
     
@@ -104,10 +104,10 @@
         return false;
 
     uint32_t cur_idx = m_frames.size ();
-    RegisterContextLLDB::SharedPtr reg_ctx_sp(new RegisterContextLLDB (m_thread, 
+    RegisterContextLLDBSharedPtr reg_ctx_sp(new RegisterContextLLDB (m_thread, 
                                                                        m_frames[cur_idx - 1]->reg_ctx, 
                                                                        cursor_sp->sctx, 
-                                                                       cur_idx));
+                                                                       cur_idx, *this));
     if (reg_ctx_sp.get() == NULL)
         return false;
 
@@ -225,3 +225,28 @@
         reg_ctx_sp = m_frames[idx]->reg_ctx;
     return reg_ctx_sp;
 }
+
+UnwindLLDB::RegisterContextLLDBSharedPtr
+UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
+{
+    RegisterContextLLDBSharedPtr reg_ctx_sp;
+    if (frame_num >= m_frames.size())
+        return reg_ctx_sp;
+    reg_ctx_sp = m_frames[frame_num]->reg_ctx;
+    return reg_ctx_sp;
+}
+
+bool
+UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num)
+{
+    int64_t frame_num = starting_frame_num;
+    if (frame_num >= m_frames.size())
+        return false;
+    while (frame_num >= 0)
+    {
+        if (m_frames[frame_num]->reg_ctx->SavedLocationForRegister (lldb_regnum, regloc, false))
+            return true;
+        frame_num--;
+    }
+    return false;
+}

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h?rev=143423&r1=143422&r2=143423&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.h Mon Oct 31 22:21:25 2011
@@ -18,10 +18,10 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Unwind.h"
 
-#include "RegisterContextLLDB.h"
-
 namespace lldb_private {
 
+class RegisterContextLLDB;
+
 class UnwindLLDB : public lldb_private::Unwind
 {
 public: 
@@ -29,8 +29,29 @@
     
     virtual
     ~UnwindLLDB() { }
-    
+
 protected:
+    friend class lldb_private::RegisterContextLLDB;
+
+    struct RegisterLocation {
+        enum RegisterLocationTypes
+        {
+            eRegisterNotSaved = 0,              // register was not preserved by callee.  If volatile reg, is unavailable
+            eRegisterSavedAtMemoryLocation,     // register is saved at a specific word of target mem (target_memory_location)
+            eRegisterInRegister,                // register is available in a (possible other) register (register_number)
+            eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space
+            eRegisterValueInferred              // register val was computed (and is in inferred_value)
+        };
+        int type;
+        union
+        {
+            lldb::addr_t target_memory_location;
+            uint32_t     register_number;       // in eRegisterKindLLDB register numbering system
+            void*        host_memory_location;
+            uint64_t     inferred_value;        // eRegisterValueInferred - e.g. stack pointer == cfa + offset
+        } location;
+    };
+
     void
     DoClear()
     {
@@ -48,13 +69,27 @@
     lldb::RegisterContextSP
     DoCreateRegisterContextForFrame (lldb_private::StackFrame *frame);
 
+    typedef lldb::SharedPtr<lldb_private::RegisterContextLLDB>::Type RegisterContextLLDBSharedPtr;
+
+    // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame 1's RegisterContextLLDB)
+    // The RegisterContext for frame_num must already exist or this returns an empty shared pointer.
+    RegisterContextLLDBSharedPtr
+    GetRegisterContextForFrameNum (uint32_t frame_num);
+
+    // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the first one that
+    // has a saved location for this reg.
+    bool
+    SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num);
+
+
 private:
+
     struct Cursor
     {
         lldb::addr_t start_pc;  // The start address of the function/symbol for this frame - current pc if unknown
         lldb::addr_t cfa;       // The canonical frame address for this stack frame
         lldb_private::SymbolContext sctx;  // A symbol context we'll contribute to & provide to the StackFrame creation
-        RegisterContextLLDB::SharedPtr reg_ctx; // These are all RegisterContextLLDB's
+        RegisterContextLLDBSharedPtr reg_ctx; // These are all RegisterContextLLDB's
 
         Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx() { }
     private:





More information about the lldb-commits mailing list