[Lldb-commits] [lldb] r230210 - UnwindPlan::Row refactor -- add support for CFA set by a DWARF expression

Pavel Labath labath at google.com
Mon Feb 23 02:19:17 PST 2015


Author: labath
Date: Mon Feb 23 04:19:16 2015
New Revision: 230210

URL: http://llvm.org/viewvc/llvm-project?rev=230210&view=rev
Log:
UnwindPlan::Row refactor -- add support for CFA set by a DWARF expression

Summary:
This change refactors UnwindPlan::Row to be able to store the fact that the CFA is value is set
by evaluating a dwarf expression (DW_CFA_def_cfa_expression). This is achieved by creating a new
class CFAValue and moving all CFA setting/getting code there. Note that code using the new
CFAValue::isDWARFExpression is not yet present and will be added in a follow-up patch. Therefore,
this patch should not change the functionality in any way.

Test Plan: Ran tests on Mac and Linux. No regressions detected.

Reviewers: jasonmolenda, clayborg

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D7755

Modified:
    lldb/trunk/include/lldb/Symbol/UnwindPlan.h
    lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
    lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
    lldb/trunk/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
    lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
    lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
    lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
    lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
    lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
    lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
    lldb/trunk/source/Symbol/CompactUnwindInfo.cpp
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
    lldb/trunk/source/Symbol/UnwindPlan.cpp

Modified: lldb/trunk/include/lldb/Symbol/UnwindPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindPlan.h?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindPlan.h (original)
+++ lldb/trunk/include/lldb/Symbol/UnwindPlan.h Mon Feb 23 04:19:16 2015
@@ -237,17 +237,178 @@ public:
             } m_location;
         };
     
+        class CFAValue
+        {
+        public:
+
+            enum ValueType
+            {
+                unspecified,                  // not specified
+                isRegisterPlusOffset,         // CFA = register + offset
+                isRegisterDereferenced,       // CFA = [reg]
+                isDWARFExpression             // CFA = eval(dwarf_expr)
+            };
+
+            CFAValue() :
+                m_type(unspecified),
+                m_value()
+            {
+            }
+
+            bool
+            operator == (const CFAValue& rhs) const;
+
+            bool
+            operator != (const CFAValue &rhs) const
+            {
+                return !(*this == rhs);
+            }
+
+            void
+            SetUnspecified()
+            {
+                m_type = unspecified;
+            }
+
+            bool
+            IsUnspecified () const
+            {
+                return m_type == unspecified;
+            }
+
+            bool
+            IsRegisterPlusOffset () const
+            {
+                return m_type == isRegisterPlusOffset;
+            }
+
+            void
+            SetIsRegisterPlusOffset (uint32_t reg_num, int32_t offset)
+            {
+                m_type = isRegisterPlusOffset;
+                m_value.reg.reg_num = reg_num;
+                m_value.reg.offset = offset;
+            }
+
+            bool
+            IsRegisterDereferenced () const
+            {
+                return m_type == isRegisterDereferenced;
+            }
+
+            void
+            SetIsRegisterDereferenced (uint32_t reg_num)
+            {
+                m_type = isRegisterDereferenced;
+                m_value.reg.reg_num = reg_num;
+            }
+
+            bool
+            IsDWARFExpression () const
+            {
+                return m_type == isDWARFExpression;
+            }
+
+            void
+            SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len)
+            {
+                m_type = isDWARFExpression;
+                m_value.expr.opcodes = opcodes;
+                m_value.expr.length = len;
+            }
+
+            uint32_t
+            GetRegisterNumber () const
+            {
+                if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset)
+                    return m_value.reg.reg_num;
+                return LLDB_INVALID_REGNUM;
+            }
+
+            ValueType
+            GetValueType () const
+            {
+                return m_type;
+            }
+
+            int32_t
+            GetOffset () const
+            {
+                if (m_type == isRegisterPlusOffset)
+                    return m_value.reg.offset;
+                return 0;
+            }
+
+            void IncOffset (int32_t delta)
+            {
+                if (m_type == isRegisterPlusOffset)
+                    m_value.reg.offset += delta;
+            }
+
+            void SetOffset (int32_t offset)
+            {
+                if (m_type == isRegisterPlusOffset)
+                    m_value.reg.offset = offset;
+            }
+
+            void
+            GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
+            {
+                if (m_type == isDWARFExpression)
+                {
+                    *opcodes = m_value.expr.opcodes;
+                    len = m_value.expr.length;
+                }
+                else
+                {
+                    *opcodes = NULL;
+                    len = 0;
+                }
+            }
+
+            const uint8_t *
+            GetDWARFExpressionBytes ()
+            {
+                if (m_type == isDWARFExpression)
+                    return m_value.expr.opcodes;
+                return NULL;
+            }
+
+            int
+            GetDWARFExpressionLength ()
+            {
+                if (m_type == isDWARFExpression)
+                    return m_value.expr.length;
+                return 0;
+            }
+
+            void
+            Dump (Stream &s,
+                  const UnwindPlan* unwind_plan,
+                  Thread* thread) const;
+
+        private:
+            ValueType m_type;            // How do we compute CFA value?
+            union
+            {
+                struct {
+                    // For m_type == isRegisterPlusOffset or m_type == isRegisterDereferenced
+                    uint32_t reg_num; // The register number
+                    // For m_type == isRegisterPlusOffset
+                    int32_t offset;
+                } reg;
+                // For m_type == isDWARFExpression
+                struct {
+                    const uint8_t *opcodes;
+                    uint16_t length;
+                } expr;
+            } m_value;
+        }; // class CFAValue
+
     public:
         Row ();
-    
-        Row (const UnwindPlan::Row& rhs) : 
-            m_offset             (rhs.m_offset),
-            m_cfa_type           (rhs.m_cfa_type),
-            m_cfa_reg_num        (rhs.m_cfa_reg_num),
-            m_cfa_offset         (rhs.m_cfa_offset),
-            m_register_locations (rhs.m_register_locations)
-        {
-        }
+
+        Row (const UnwindPlan::Row& rhs) = default;
 
         bool
         operator == (const Row &rhs) const;
@@ -279,47 +440,9 @@ public:
             m_offset += offset;
         }
 
-        // How we can reconstruct the CFA address for this stack frame, at this location
-        enum CFAType
-        {
-            CFAIsRegisterPlusOffset,   // the CFA value in a register plus (or minus) an offset
-            CFAIsRegisterDereferenced  // the address in a register is dereferenced to get CFA value
-        };
-
-        CFAType
-        GetCFAType () const
-        {
-            return m_cfa_type;
-        }
-
-        void
-        SetCFAType (CFAType cfa_type)
+        CFAValue& GetCFAValue()
         {
-            m_cfa_type = cfa_type;
-        }
-
-        // If GetCFAType() is CFAIsRegisterPlusOffset, add GetCFAOffset to the reg value to get CFA value
-        // If GetCFAType() is CFAIsRegisterDereferenced, dereference the addr in the reg to get CFA value
-        uint32_t
-        GetCFARegister () const
-        {
-            return m_cfa_reg_num;
-        }
-        
-        void
-        SetCFARegister (uint32_t reg_num);
-
-        // This should not be used when GetCFAType() is CFAIsRegisterDereferenced; will return 0 in that case.
-        int32_t
-        GetCFAOffset () const
-        {
-            return m_cfa_offset;
-        }
-
-        void
-        SetCFAOffset (int32_t offset)
-        {
-            m_cfa_offset = offset;
+            return m_cfa_value;
         }
 
         bool
@@ -360,14 +483,7 @@ public:
         typedef std::map<uint32_t, RegisterLocation> collection;
         lldb::addr_t m_offset;      // Offset into the function for this row
 
-        CFAType m_cfa_type;
-
-        // If m_cfa_type == CFAIsRegisterPlusOffset, the CFA address is computed as m_cfa_reg_num + m_cfa_offset
-        // If m_cfa_type == CFAIsRegisterDereferenced, the CFA address is computed as *(m_cfa_reg_num) - i.e. the
-        // address in m_cfa_reg_num is dereferenced and the pointer value read is the CFA addr.
-        uint32_t m_cfa_reg_num;     // The Call Frame Address register number
-        int32_t  m_cfa_offset;      // The offset from the CFA for this row
-
+        CFAValue m_cfa_value;
         collection m_register_locations;
     }; // class Row
 
@@ -437,7 +553,7 @@ public:
     {
         if (m_row_list.empty())
             return LLDB_INVALID_REGNUM;
-        return m_row_list.front()->GetCFARegister();
+        return m_row_list.front()->GetCFAValue().GetRegisterNumber();
     }
 
     // This UnwindPlan may not be valid at every address of the function span.  

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Mon Feb 23 04:19:16 2015
@@ -587,7 +587,7 @@ ABIMacOSX_arm::CreateFunctionEntryUnwind
     UnwindPlan::RowSP row(new UnwindPlan::Row);
     
     // Our Call Frame Address is the stack pointer value
-    row->SetCFARegister (sp_reg_num);
+    row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
     
     // The previous PC is in the LR
     row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
@@ -613,8 +613,7 @@ ABIMacOSX_arm::CreateDefaultUnwindPlan (
     UnwindPlan::RowSP row(new UnwindPlan::Row);
     const int32_t ptr_size = 4;
     
-    row->SetCFARegister (fp_reg_num);
-    row->SetCFAOffset (2 * ptr_size);
+    row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
     row->SetOffset (0);
     
     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp Mon Feb 23 04:19:16 2015
@@ -562,7 +562,7 @@ ABIMacOSX_arm64::CreateFunctionEntryUnwi
     UnwindPlan::RowSP row(new UnwindPlan::Row);
     
     // Our previous Call Frame Address is the stack pointer
-    row->SetCFARegister (sp_reg_num);
+    row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
     
     // Our previous PC is in the LR
     row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
@@ -589,8 +589,7 @@ ABIMacOSX_arm64::CreateDefaultUnwindPlan
     UnwindPlan::RowSP row(new UnwindPlan::Row);    
     const int32_t ptr_size = 8;
     
-    row->SetCFARegister (fp_reg_num);
-    row->SetCFAOffset (2 * ptr_size);
+    row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
     row->SetOffset (0);
     
     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);

Modified: lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Mon Feb 23 04:19:16 2015
@@ -746,8 +746,7 @@ ABIMacOSX_i386::CreateFunctionEntryUnwin
     uint32_t pc_reg_num = dwarf_eip;
     
     UnwindPlan::RowSP row(new UnwindPlan::Row);
-    row->SetCFARegister (sp_reg_num);
-    row->SetCFAOffset (4);
+    row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 4);
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, false);
     row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
     unwind_plan.AppendRow (row);
@@ -774,8 +773,7 @@ ABIMacOSX_i386::CreateDefaultUnwindPlan
     UnwindPlan::RowSP row(new UnwindPlan::Row);
     const int32_t ptr_size = 4;
 
-    row->SetCFARegister (fp_reg_num);
-    row->SetCFAOffset (2 * ptr_size);
+    row->GetCFAValue().SetIsRegisterPlusOffset (fp_reg_num, 2 * ptr_size);
     row->SetOffset (0);
     
     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);

Modified: lldb/trunk/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp Mon Feb 23 04:19:16 2015
@@ -385,8 +385,7 @@ ABISysV_hexagon::CreateFunctionEntryUnwi
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     // Our Call Frame Address is the stack pointer value
-    row->SetCFARegister(LLDB_REGNUM_GENERIC_SP);
-    row->SetCFAOffset(4);
+    row->GetCFAValue().SetIsRegisterPlusOffset (LLDB_REGNUM_GENERIC_SP, 4);
     row->SetOffset(0);
 
     // The previous PC is in the LR
@@ -410,8 +409,7 @@ ABISysV_hexagon::CreateDefaultUnwindPlan
 
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
-    row->SetCFARegister(LLDB_REGNUM_GENERIC_FP);
-    row->SetCFAOffset(8);
+    row->GetCFAValue().SetIsRegisterPlusOffset (LLDB_REGNUM_GENERIC_FP, 8);
 
     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num,-8, true);
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num,-4, true);

Modified: lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp Mon Feb 23 04:19:16 2015
@@ -985,7 +985,7 @@ ABISysV_ppc::CreateFunctionEntryUnwindPl
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     // Our Call Frame Address is the stack pointer value
-    row->SetCFARegister (sp_reg_num);
+    row->GetCFAValue().SetIsRegisterPlusOffset (sp_reg_num, 0);
 
     // The previous PC is in the LR
     row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
@@ -1011,8 +1011,7 @@ ABISysV_ppc::CreateDefaultUnwindPlan (Un
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     const int32_t ptr_size = 4;
-    row->SetCFARegister (sp_reg_num);
-    row->SetCFAType(lldb_private::UnwindPlan::Row::CFAIsRegisterDereferenced);
+    row->GetCFAValue().SetIsRegisterDereferenced (sp_reg_num);
 
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 1, true);
     row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);

Modified: lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp Mon Feb 23 04:19:16 2015
@@ -985,7 +985,7 @@ ABISysV_ppc64::CreateFunctionEntryUnwind
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     // Our Call Frame Address is the stack pointer value
-    row->SetCFARegister (sp_reg_num);
+    row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
 
     // The previous PC is in the LR
     row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
@@ -1011,8 +1011,7 @@ ABISysV_ppc64::CreateDefaultUnwindPlan (
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     const int32_t ptr_size = 8;
-    row->SetCFARegister (sp_reg_num);
-    row->SetCFAType(lldb_private::UnwindPlan::Row::CFAIsRegisterDereferenced);
+    row->GetCFAValue().SetIsRegisterDereferenced(sp_reg_num);
 
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * 2, true);
     row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);

Modified: lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Mon Feb 23 04:19:16 2015
@@ -1084,8 +1084,7 @@ ABISysV_x86_64::CreateFunctionEntryUnwin
     uint32_t pc_reg_num = gcc_dwarf_rip;
     
     UnwindPlan::RowSP row(new UnwindPlan::Row);
-    row->SetCFARegister (sp_reg_num);
-    row->SetCFAOffset (8);
+    row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
     row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
     row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
     unwind_plan.AppendRow (row);
@@ -1112,8 +1111,7 @@ ABISysV_x86_64::CreateDefaultUnwindPlan
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     const int32_t ptr_size = 8;
-    row->SetCFARegister (gcc_dwarf_rbp);
-    row->SetCFAOffset (2 * ptr_size);
+    row->GetCFAValue().SetIsRegisterPlusOffset(gcc_dwarf_rbp, 2 * ptr_size);
     row->SetOffset (0);
     
     row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);

Modified: lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp Mon Feb 23 04:19:16 2015
@@ -13643,7 +13643,7 @@ EmulateInstructionARM::CreateFunctionEnt
     UnwindPlan::RowSP row(new UnwindPlan::Row);
 
     // Our previous Call Frame Address is the stack pointer
-    row->SetCFARegister (dwarf_sp);
+    row->GetCFAValue().SetIsRegisterPlusOffset (dwarf_sp, 0);
     
     // Our previous PC is in the LR
     row->SetRegisterLocationToRegister(dwarf_pc, dwarf_lr, true);

Modified: lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp Mon Feb 23 04:19:16 2015
@@ -349,7 +349,7 @@ EmulateInstructionARM64::CreateFunctionE
     const bool can_replace = false;
 
     // Our previous Call Frame Address is the stack pointer
-    row->SetCFARegister (arm64_dwarf::sp);
+    row->GetCFAValue().SetIsRegisterPlusOffset(arm64_dwarf::sp, 0);
     
     // Our previous PC is in the LR
     row->SetRegisterLocationToRegister(arm64_dwarf::pc, arm64_dwarf::lr, can_replace);

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=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Mon Feb 23 04:19:16 2015
@@ -599,7 +599,7 @@ RegisterContextLLDB::InitializeNonZeroth
 
     if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
     {
-        UnwindLogMsg ("failed to get cfa reg %d/%d", row_register_kind, active_row->GetCFARegister());
+        UnwindLogMsg ("failed to get cfa");
         m_frame_type = eNotAValidFrame;
         return;
     }
@@ -1577,7 +1577,7 @@ RegisterContextLLDB::TryFallbackUnwindPl
 
     UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
     
-    if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM)
+    if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
     {
         addr_t new_cfa;
         if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa)
@@ -1654,7 +1654,7 @@ RegisterContextLLDB::ForceSwitchToFallba
 
     UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
     
-    if (active_row && active_row->GetCFARegister() != LLDB_INVALID_REGNUM)
+    if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
     {
         addr_t new_cfa;
         if (!ReadCFAValueForRow (m_fallback_unwind_plan_sp->GetRegisterKind(), active_row, new_cfa)
@@ -1683,57 +1683,69 @@ RegisterContextLLDB::ReadCFAValueForRow
                                          const UnwindPlan::RowSP &row,
                                          addr_t &cfa_value)
 {
-    RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFARegister());
     RegisterValue reg_value;
 
     cfa_value = LLDB_INVALID_ADDRESS;
     addr_t cfa_reg_contents;
 
-    if (ReadGPRValue (cfa_reg, cfa_reg_contents))
+    switch (row->GetCFAValue().GetValueType())
     {
-        if (row->GetCFAType() == UnwindPlan::Row::CFAIsRegisterDereferenced)
+    case UnwindPlan::Row::CFAValue::isRegisterDereferenced:
         {
-            const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB));
-            RegisterValue reg_value;
-            if (reg_info)
+            RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
+            if (ReadGPRValue (cfa_reg, cfa_reg_contents))
             {
-                Error error = ReadRegisterValueFromMemory(reg_info,
-                                                          cfa_reg_contents,
-                                                          reg_info->byte_size,
-                                                          reg_value);
-                if (error.Success ())
-                {
-                    cfa_value = reg_value.GetAsUInt64();
-                    UnwindLogMsg ("CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64,
-                                  cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
-                                  cfa_reg_contents, cfa_value);
-                    return true;
-                }
-                else
+                const RegisterInfo *reg_info = GetRegisterInfoAtIndex (cfa_reg.GetAsKind (eRegisterKindLLDB));
+                RegisterValue reg_value;
+                if (reg_info)
                 {
-                    UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64 "] but memory read failed.",
-                                  cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
-                                  cfa_reg_contents);
+                    Error error = ReadRegisterValueFromMemory(reg_info,
+                                                              cfa_reg_contents,
+                                                              reg_info->byte_size,
+                                                              reg_value);
+                    if (error.Success ())
+                    {
+                        cfa_value = reg_value.GetAsUInt64();
+                        UnwindLogMsg ("CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64,
+                                      cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
+                                      cfa_reg_contents, cfa_value);
+                        return true;
+                    }
+                    else
+                    {
+                        UnwindLogMsg ("Tried to deref reg %s (%d) [0x%" PRIx64 "] but memory read failed.",
+                                      cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
+                                      cfa_reg_contents);
+                    }
                 }
             }
+            break;
         }
-        else
+    case UnwindPlan::Row::CFAValue::isRegisterPlusOffset:
         {
-            if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1)
+            RegisterNumber cfa_reg (m_thread, row_register_kind, row->GetCFAValue().GetRegisterNumber());
+            if (ReadGPRValue (cfa_reg, cfa_reg_contents))
             {
-                UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
+                if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1)
+                {
+                    UnwindLogMsg ("Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64,
+                                  cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
+                                  cfa_reg_contents);
+                    cfa_reg_contents = LLDB_INVALID_ADDRESS;
+                    return false;
+                }
+                cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset();
+                UnwindLogMsg ("CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d",
+                              cfa_value,
                               cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB),
-                              cfa_reg_contents);
-                cfa_reg_contents = LLDB_INVALID_ADDRESS;
-                return false;
+                              cfa_reg_contents, row->GetCFAValue().GetOffset());
+                return true;
             }
-            cfa_value = cfa_reg_contents + row->GetCFAOffset ();
-            UnwindLogMsg ("CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d",
-                          cfa_value, 
-                          cfa_reg.GetName(), cfa_reg.GetAsKind (eRegisterKindLLDB), 
-                          cfa_reg_contents, row->GetCFAOffset ());
-            return true;
+            break;
         }
+    // TODO: handle isDWARFExpression
+    default:
+        return false;
     }
     return false;
 }

Modified: lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Mon Feb 23 04:19:16 2015
@@ -662,8 +662,8 @@ UnwindAssemblyInstEmulation::WriteRegist
                 m_cfa_reg_info = *reg_info;
                 const uint32_t cfa_reg_num = reg_info->kinds[m_unwind_plan_ptr->GetRegisterKind()];
                 assert (cfa_reg_num != LLDB_INVALID_REGNUM);
-                m_curr_row->SetCFARegister(cfa_reg_num);
-                m_curr_row->SetCFAOffset(m_initial_sp - reg_value.GetAsUInt64());
+                m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(cfa_reg_num, m_initial_sp -
+                        reg_value.GetAsUInt64());
                 m_curr_row_modified = true;
             }
             break;
@@ -673,7 +673,9 @@ UnwindAssemblyInstEmulation::WriteRegist
             // subsequent adjustments to the stack pointer.
             if (!m_fp_is_cfa)
             {
-                m_curr_row->SetCFAOffset (m_initial_sp - reg_value.GetAsUInt64());
+                m_curr_row->GetCFAValue().SetIsRegisterPlusOffset(
+                        m_curr_row->GetCFAValue().GetRegisterNumber(),
+                        m_initial_sp - reg_value.GetAsUInt64());
                 m_curr_row_modified = true;
             }
             break;

Modified: lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp (original)
+++ lldb/trunk/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp Mon Feb 23 04:19:16 2015
@@ -630,8 +630,7 @@ AssemblyParse_x86::get_non_call_site_unw
 
     // At the start of the function, find the CFA by adding wordsize to the SP register
     row->SetOffset (current_func_text_offset);
-    row->SetCFARegister (m_lldb_sp_regnum);
-    row->SetCFAOffset (m_wordsize);
+    row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum, m_wordsize);
 
     // caller's stack pointer value before the call insn is the CFA address
     initial_regloc.SetIsCFAPlusOffset (0);
@@ -691,9 +690,9 @@ AssemblyParse_x86::get_non_call_site_unw
         if (push_rbp_pattern_p ())
         {
             current_sp_bytes_offset_from_cfa += m_wordsize;
-            row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
+            row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
             UnwindPlan::Row::RegisterLocation regloc;
-            regloc.SetAtCFAPlusOffset (-row->GetCFAOffset());
+            regloc.SetAtCFAPlusOffset (-row->GetCFAValue().GetOffset());
             row->SetRegisterInfo (m_lldb_fp_regnum, regloc);
             saved_registers[m_machine_fp_regnum] = true;
             row_updated = true;
@@ -701,7 +700,7 @@ AssemblyParse_x86::get_non_call_site_unw
 
         else if (mov_rsp_rbp_pattern_p ())
         {
-            row->SetCFARegister (m_lldb_fp_regnum);
+            row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_fp_regnum, row->GetCFAValue().GetOffset());
             row_updated = true;
         }
 
@@ -717,9 +716,9 @@ AssemblyParse_x86::get_non_call_site_unw
             current_sp_bytes_offset_from_cfa += m_wordsize;
             // the PUSH instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer,
             // we need to add a new row of instructions.
-            if (row->GetCFARegister() == m_lldb_sp_regnum)
+            if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
             {
-                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
+                row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
                 row_updated = true;
             }
             // record where non-volatile (callee-saved, spilled) registers are saved on the stack
@@ -748,7 +747,8 @@ AssemblyParse_x86::get_non_call_site_unw
 
                 if (machine_regno == (int)m_machine_fp_regnum)
                 {
-                    row->SetCFARegister (m_lldb_sp_regnum);
+                    row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum,
+                            row->GetCFAValue().GetOffset());
                 }
 
                 in_epilogue = true;
@@ -757,9 +757,10 @@ AssemblyParse_x86::get_non_call_site_unw
 
             // the POP instruction has moved the stack pointer - if the CFA is set in terms of the stack pointer,
             // we need to add a new row of instructions.
-            if (row->GetCFARegister() == m_lldb_sp_regnum)
+            if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
             {
-                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
+                row->GetCFAValue().SetIsRegisterPlusOffset(m_lldb_sp_regnum,
+                        current_sp_bytes_offset_from_cfa);
                 row_updated = true;
             }
         }
@@ -777,7 +778,7 @@ AssemblyParse_x86::get_non_call_site_unw
             // In the Row, we want to express this as the offset from the CFA.  If the frame base
             // is rbp (like the above instruction), the CFA offset for rbp is probably 16.  So we
             // want to say that the value is stored at the CFA address - 96.
-            regloc.SetAtCFAPlusOffset (-(stack_offset + row->GetCFAOffset()));
+            regloc.SetAtCFAPlusOffset (-(stack_offset + row->GetCFAValue().GetOffset()));
 
             row->SetRegisterInfo (lldb_regno, regloc);
 
@@ -787,9 +788,9 @@ AssemblyParse_x86::get_non_call_site_unw
         else if (sub_rsp_pattern_p (stack_offset))
         {
             current_sp_bytes_offset_from_cfa += stack_offset;
-            if (row->GetCFARegister() == m_lldb_sp_regnum)
+            if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
             {
-                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
+                row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
                 row_updated = true;
             }
         }
@@ -797,9 +798,9 @@ AssemblyParse_x86::get_non_call_site_unw
         else if (add_rsp_pattern_p (stack_offset))
         {
             current_sp_bytes_offset_from_cfa -= stack_offset;
-            if (row->GetCFARegister() == m_lldb_sp_regnum)
+            if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
             {
-                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
+                row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
                 row_updated = true;
             }
             in_epilogue = true;
@@ -833,9 +834,9 @@ AssemblyParse_x86::get_non_call_site_unw
         else if (call_next_insn_pattern_p ())
         {
             current_sp_bytes_offset_from_cfa += m_wordsize;
-            if (row->GetCFARegister() == m_lldb_sp_regnum)
+            if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum)
             {
-                row->SetCFAOffset (current_sp_bytes_offset_from_cfa);
+                row->GetCFAValue().SetOffset (current_sp_bytes_offset_from_cfa);
                 row_updated = true;
             }
         }
@@ -904,8 +905,8 @@ AssemblyParse_x86::augment_unwind_plan_f
         return false;
     uint32_t cfa_reg = m_exe_ctx.GetThreadPtr()->GetRegisterContext()
                        ->ConvertRegisterKindToRegisterNumber (unwind_plan.GetRegisterKind(),
-                                                              first_row->GetCFARegister());
-    if (cfa_reg != m_lldb_sp_regnum || first_row->GetCFAOffset() != m_wordsize)
+                                                              first_row->GetCFAValue().GetRegisterNumber());
+    if (cfa_reg != m_lldb_sp_regnum || first_row->GetCFAValue().GetOffset() != m_wordsize)
         return false;
 
     UnwindPlan::RowSP original_last_row = unwind_plan.GetRowForFunctionOffset (-1);
@@ -985,7 +986,7 @@ AssemblyParse_x86::augment_unwind_plan_f
         // Inspect the instruction to check if we need a new row for it.
         cfa_reg = m_exe_ctx.GetThreadPtr()->GetRegisterContext()
                   ->ConvertRegisterKindToRegisterNumber (unwind_plan.GetRegisterKind(),
-                                                         row->GetCFARegister());
+                                                         row->GetCFAValue().GetRegisterNumber());
         if (cfa_reg == m_lldb_sp_regnum)
         {
             // CFA register is sp.
@@ -996,7 +997,7 @@ AssemblyParse_x86::augment_unwind_plan_f
             if (call_next_insn_pattern_p ())
             {
                 row->SetOffset (offset);
-                row->SetCFAOffset (m_wordsize + row->GetCFAOffset());
+                row->GetCFAValue().IncOffset (m_wordsize);
 
                 UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                 unwind_plan.InsertRow (new_row);
@@ -1009,7 +1010,7 @@ AssemblyParse_x86::augment_unwind_plan_f
             if (push_reg_p (regno))
             {
                 row->SetOffset (offset);
-                row->SetCFAOffset (m_wordsize + row->GetCFAOffset());
+                row->GetCFAValue().IncOffset (m_wordsize);
 
                 UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                 unwind_plan.InsertRow (new_row);
@@ -1024,7 +1025,7 @@ AssemblyParse_x86::augment_unwind_plan_f
                 // So we ignore this case.
 
                 row->SetOffset (offset);
-                row->SetCFAOffset (-m_wordsize + row->GetCFAOffset());
+                row->GetCFAValue().IncOffset (-m_wordsize);
 
                 UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                 unwind_plan.InsertRow (new_row);
@@ -1036,7 +1037,7 @@ AssemblyParse_x86::augment_unwind_plan_f
             if (push_imm_pattern_p ())
             {
                 row->SetOffset (offset);
-                row->SetCFAOffset (m_wordsize + row->GetCFAOffset());
+                row->GetCFAValue().IncOffset (m_wordsize);
                 UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                 unwind_plan.InsertRow (new_row);
                 unwind_plan_updated = true;
@@ -1048,7 +1049,7 @@ AssemblyParse_x86::augment_unwind_plan_f
             if (add_rsp_pattern_p (amount))
             {
                 row->SetOffset (offset);
-                row->SetCFAOffset (-amount + row->GetCFAOffset());
+                row->GetCFAValue().IncOffset (-amount);
 
                 UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                 unwind_plan.InsertRow (new_row);
@@ -1058,7 +1059,7 @@ AssemblyParse_x86::augment_unwind_plan_f
             if (sub_rsp_pattern_p (amount))
             {
                 row->SetOffset (offset);
-                row->SetCFAOffset (amount + row->GetCFAOffset());
+                row->GetCFAValue().IncOffset (amount);
 
                 UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                 unwind_plan.InsertRow (new_row);
@@ -1085,8 +1086,8 @@ AssemblyParse_x86::augment_unwind_plan_f
                     && ret_pattern_p ())
                 {
                     row->SetOffset (offset);
-                    row->SetCFARegister (first_row->GetCFARegister());
-                    row->SetCFAOffset (m_wordsize);
+                    row->GetCFAValue().SetIsRegisterPlusOffset (
+                        first_row->GetCFAValue().GetRegisterNumber(), m_wordsize);
 
                     UnwindPlan::RowSP new_row(new UnwindPlan::Row(*row));
                     unwind_plan.InsertRow (new_row);
@@ -1169,8 +1170,7 @@ AssemblyParse_x86::get_fast_unwind_plan
     row->SetRegisterInfo (m_lldb_sp_regnum, sp_reginfo);
 
     // Zero instructions into the function
-    row->SetCFARegister (m_lldb_sp_regnum);
-    row->SetCFAOffset (m_wordsize);
+    row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_sp_regnum, m_wordsize);
     row->SetOffset (0);
     unwind_plan.AppendRow (row);
     UnwindPlan::Row *newrow = new UnwindPlan::Row;
@@ -1178,7 +1178,7 @@ AssemblyParse_x86::get_fast_unwind_plan
     row.reset(newrow);
 
     // push %rbp has executed - stack moved, rbp now saved
-    row->SetCFAOffset (2 * m_wordsize);
+    row->GetCFAValue().IncOffset (m_wordsize);
     fp_reginfo.SetAtCFAPlusOffset (2 * -m_wordsize);
     row->SetRegisterInfo (m_lldb_fp_regnum, fp_reginfo);
     row->SetOffset (1);
@@ -1189,8 +1189,7 @@ AssemblyParse_x86::get_fast_unwind_plan
     row.reset(newrow);
 
     // mov %rsp, %rbp has executed
-    row->SetCFARegister (m_lldb_fp_regnum);
-    row->SetCFAOffset (2 * m_wordsize);
+    row->GetCFAValue().SetIsRegisterPlusOffset (m_lldb_fp_regnum, 2 * m_wordsize);
     row->SetOffset (prologue_size);     /// 3 or 4 bytes depending on arch
     unwind_plan.AppendRow (row);
 
@@ -1300,9 +1299,10 @@ UnwindAssembly_x86::AugmentUnwindPlanFro
     // If there is no description of the prologue, don't try to augment this eh_frame
     // unwinder code, fall back to assembly parsing instead.
 
-    if (first_row->GetCFAType() != UnwindPlan::Row::CFAType::CFAIsRegisterPlusOffset
-        || RegisterNumber (thread, unwind_plan.GetRegisterKind(), first_row->GetCFARegister()) != sp_regnum
-        || first_row->GetCFAOffset() != wordsize)
+    if (first_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::isRegisterPlusOffset
+        || RegisterNumber (thread, unwind_plan.GetRegisterKind(),
+            first_row->GetCFAValue().GetRegisterNumber()) != sp_regnum
+        || first_row->GetCFAValue().GetOffset() != wordsize)
     {
         return false;
     }
@@ -1326,9 +1326,9 @@ UnwindAssembly_x86::AugmentUnwindPlanFro
 
         // We're checking that both of them have an unwind rule like "CFA=esp+4" or CFA+rsp+8".
 
-        if (first_row->GetCFAType() == last_row->GetCFAType()
-            && first_row->GetCFARegister() == last_row->GetCFARegister()
-            && first_row->GetCFAOffset() == last_row->GetCFAOffset())
+        if (first_row->GetCFAValue().GetValueType() == last_row->GetCFAValue().GetValueType()
+            && first_row->GetCFAValue().GetRegisterNumber() == last_row->GetCFAValue().GetRegisterNumber()
+            && first_row->GetCFAValue().GetOffset() == last_row->GetCFAValue().GetOffset())
         {
             // Get the register locations for eip/rip from the first & last rows.
             // Are they both CFA plus an offset?  Is it the same offset?

Modified: lldb/trunk/source/Symbol/CompactUnwindInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompactUnwindInfo.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CompactUnwindInfo.cpp (original)
+++ lldb/trunk/source/Symbol/CompactUnwindInfo.cpp Mon Feb 23 04:19:16 2015
@@ -720,8 +720,9 @@ CompactUnwindInfo::CreateUnwindPlan_x86_
     {
         case UNWIND_X86_64_MODE_RBP_FRAME:
         {
-            row->SetCFARegister (translate_to_eh_frame_regnum_x86_64 (UNWIND_X86_64_REG_RBP));
-            row->SetCFAOffset (2 * wordsize);
+            row->GetCFAValue().SetIsRegisterPlusOffset (
+                    translate_to_eh_frame_regnum_x86_64 (UNWIND_X86_64_REG_RBP),
+                    2 * wordsize);
             row->SetOffset (0);
             row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rbp, wordsize * -2, true);
             row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true);
@@ -809,16 +810,9 @@ CompactUnwindInfo::CreateUnwindPlan_x86_
                 }
             }
 
-            if (mode == UNWIND_X86_64_MODE_STACK_IND)
-            {
-                row->SetCFAOffset (stack_size);
-            }
-            else
-            {
-                row->SetCFAOffset (stack_size * wordsize);
-            }
+            int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND ? stack_size : stack_size * wordsize;
+            row->GetCFAValue().SetIsRegisterPlusOffset (x86_64_eh_regnum::rsp, offset);
 
-            row->SetCFARegister (x86_64_eh_regnum::rsp);
             row->SetOffset (0);
             row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true);
             row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true);
@@ -1009,8 +1003,8 @@ CompactUnwindInfo::CreateUnwindPlan_i386
     {
         case UNWIND_X86_MODE_EBP_FRAME:
         {
-            row->SetCFARegister (translate_to_eh_frame_regnum_i386 (UNWIND_X86_REG_EBP));
-            row->SetCFAOffset (2 * wordsize);
+            row->GetCFAValue().SetIsRegisterPlusOffset (
+                    translate_to_eh_frame_regnum_i386 (UNWIND_X86_REG_EBP), 2 * wordsize);
             row->SetOffset (0);
             row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::ebp, wordsize * -2, true);
             row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
@@ -1091,17 +1085,8 @@ CompactUnwindInfo::CreateUnwindPlan_i386
                 }
             }
 
-            row->SetCFARegister (i386_eh_regnum::esp);
-
-            if (mode == UNWIND_X86_MODE_STACK_IND)
-            {
-                row->SetCFAOffset (stack_size);
-            }
-            else
-            {
-                row->SetCFAOffset (stack_size * wordsize);
-            }
-
+            int32_t offset = mode == UNWIND_X86_MODE_STACK_IND ? stack_size : stack_size * wordsize;
+            row->GetCFAValue().SetIsRegisterPlusOffset (i386_eh_regnum::esp, offset);
             row->SetOffset (0);
             row->SetRegisterLocationToAtCFAPlusOffset (i386_eh_regnum::eip, wordsize * -1, true);
             row->SetRegisterLocationToIsCFAPlusOffset (i386_eh_regnum::esp, 0, true);

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Mon Feb 23 04:19:16 2015
@@ -284,8 +284,7 @@ DWARFCallFrameInfo::ParseCIE (const dw_o
                 // register and offset.
                 uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
                 int op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
-                cie_sp->initial_row.SetCFARegister (reg_num);
-                cie_sp->initial_row.SetCFAOffset (op_offset);
+                cie_sp->initial_row.GetCFAValue().SetIsRegisterPlusOffset (reg_num, op_offset);
                 continue;
             }
             if (primary_opcode == DW_CFA_offset)
@@ -719,8 +718,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
                         // register and offset.
                         reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
                         op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
-                        row->SetCFARegister (reg_num);
-                        row->SetCFAOffset (op_offset);
+                        row->GetCFAValue().SetIsRegisterPlusOffset (reg_num, op_offset);
                     }
                     break;
 
@@ -730,7 +728,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
                         // number. The required action is to define the current CFA rule to
                         // use the provided register (but to keep the old offset).
                         reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
-                        row->SetCFARegister (reg_num);
+                        row->GetCFAValue().SetIsRegisterPlusOffset (reg_num,
+                                row->GetCFAValue().GetOffset());
                     }
                     break;
 
@@ -741,7 +740,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
                         // the current CFA rule to use the provided offset (but
                         // to keep the old register).
                         op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
-                        row->SetCFAOffset (op_offset);
+                        row->GetCFAValue().SetIsRegisterPlusOffset (
+                                row->GetCFAValue().GetRegisterNumber(), op_offset);
                     }
                     break;
 
@@ -792,8 +792,7 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
                         // that the second operand is signed and factored.
                         reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
                         op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
-                        row->SetCFARegister (reg_num);
-                        row->SetCFAOffset (op_offset);
+                        row->GetCFAValue().SetIsRegisterPlusOffset (reg_num, op_offset);
                     }
                     break;
 
@@ -803,7 +802,8 @@ DWARFCallFrameInfo::FDEToUnwindPlan (dw_
                         // offset. This instruction is identical to  DW_CFA_def_cfa_offset
                         // except that the operand is signed and factored.
                         op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
-                        row->SetCFAOffset (op_offset);
+                        row->GetCFAValue().SetIsRegisterPlusOffset (
+                                row->GetCFAValue().GetRegisterNumber(), op_offset);
                     }
                     break;
 

Modified: lldb/trunk/source/Symbol/UnwindPlan.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/UnwindPlan.cpp?rev=230210&r1=230209&r2=230210&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/UnwindPlan.cpp (original)
+++ lldb/trunk/source/Symbol/UnwindPlan.cpp Mon Feb 23 04:19:16 2015
@@ -94,31 +94,7 @@ UnwindPlan::Row::RegisterLocation::Dump
                 s.PutChar('=');
                 if (m_type == atCFAPlusOffset)
                     s.PutChar('[');
-                if (verbose)
-                    s.Printf ("CFA%+d", m_location.offset);
-
-                if (unwind_plan && row)
-                {
-                    const uint32_t cfa_reg = row->GetCFARegister();
-                    const RegisterInfo *cfa_reg_info = unwind_plan->GetRegisterInfo (thread, cfa_reg);
-                    const int32_t offset = row->GetCFAOffset() + m_location.offset;
-                    if (verbose)
-                    {                        
-                        if (cfa_reg_info)
-                            s.Printf (" (%s%+d)",  cfa_reg_info->name, offset); 
-                        else
-                            s.Printf (" (reg(%u)%+d)",  cfa_reg, offset); 
-                    }
-                    else
-                    {
-                        if (cfa_reg_info)
-                            s.Printf ("%s",  cfa_reg_info->name); 
-                        else
-                            s.Printf ("reg(%u)",  cfa_reg); 
-                        if (offset != 0)
-                            s.Printf ("%+d", offset);
-                    }
-                }
+                s.Printf ("CFA%+d", m_location.offset);
                 if (m_type == atCFAPlusOffset)
                     s.PutChar(']');
             }
@@ -150,38 +126,83 @@ UnwindPlan::Row::RegisterLocation::Dump
     }
 }
 
+static void
+DumpRegisterName (Stream &s, const UnwindPlan* unwind_plan, Thread *thread, uint32_t reg_num) {
+    const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, reg_num);
+    if (reg_info)
+        s.PutCString (reg_info->name);
+    else
+        s.Printf ("reg(%u)", reg_num);
+}
+
+bool
+UnwindPlan::Row::CFAValue::operator == (const UnwindPlan::Row::CFAValue& rhs) const
+{
+    if (m_type == rhs.m_type)
+    {
+        switch (m_type)
+        {
+            case unspecified:
+                return true;
+
+            case isRegisterPlusOffset:
+                return m_value.reg.offset == rhs.m_value.reg.offset;
+
+            case isRegisterDereferenced:
+                return m_value.reg.reg_num == rhs.m_value.reg.reg_num;
+
+            case isDWARFExpression:
+                if (m_value.expr.length == rhs.m_value.expr.length)
+                    return !memcmp (m_value.expr.opcodes, rhs.m_value.expr.opcodes, m_value.expr.length);
+                break;
+        }
+    }
+    return false;
+}
+
+void
+UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan* unwind_plan, Thread* thread) const
+{
+    switch(m_type) {
+    case isRegisterPlusOffset:
+        DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
+        s.Printf ("%+3d", m_value.reg.offset);
+        break;
+    case isRegisterDereferenced:
+        s.PutChar ('[');
+        DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
+        s.PutChar (']');
+        break;
+    case isDWARFExpression:
+        s.PutCString ("dwarf-expr");
+        break;
+    default:
+        s.PutCString ("unspecified");
+        break;
+    }
+}
+
 void
 UnwindPlan::Row::Clear ()
 {
-    m_cfa_type = CFAIsRegisterPlusOffset;
+    m_cfa_value.SetUnspecified();
     m_offset = 0;
-    m_cfa_reg_num = LLDB_INVALID_REGNUM;
-    m_cfa_offset = 0;
     m_register_locations.clear();
 }
 
 void
 UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const
 {
-    const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, GetCFARegister());
-
     if (base_addr != LLDB_INVALID_ADDRESS)
         s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
     else
         s.Printf ("%4" PRId64 ": CFA=", GetOffset());
             
-    if (reg_info)
-        s.Printf ("%s", reg_info->name);
-    else
-        s.Printf ("reg(%u)", GetCFARegister());
-    s.Printf ("%+3d => ", GetCFAOffset ());
+    m_cfa_value.Dump(s, unwind_plan, thread);
+    s.Printf(" => ");
     for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
     {
-        reg_info = unwind_plan->GetRegisterInfo (thread, idx->first);
-        if (reg_info)
-            s.Printf ("%s", reg_info->name);
-        else
-            s.Printf ("reg(%u)", idx->first);
+        DumpRegisterName(s, unwind_plan, thread, idx->first);
         const bool verbose = false;
         idx->second.Dump(s, unwind_plan, this, thread, verbose);
         s.PutChar (' ');
@@ -191,9 +212,7 @@ UnwindPlan::Row::Dump (Stream& s, const
 
 UnwindPlan::Row::Row() :
     m_offset (0),
-    m_cfa_type (CFAIsRegisterPlusOffset),
-    m_cfa_reg_num (LLDB_INVALID_REGNUM),
-    m_cfa_offset (0),
+    m_cfa_value (),
     m_register_locations ()
 {
 }
@@ -302,35 +321,11 @@ UnwindPlan::Row::SetRegisterLocationToSa
     return true;
 }
 
-void
-UnwindPlan::Row::SetCFARegister (uint32_t reg_num)
-{
-    m_cfa_reg_num = reg_num;
-}
-
 bool
 UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const
 {
-    if (m_offset != rhs.m_offset || m_cfa_reg_num != rhs.m_cfa_reg_num || m_cfa_offset != rhs.m_cfa_offset)
-        return false;
-
-    if (m_cfa_type != rhs.m_cfa_type)
-        return false;
-
-    if (m_cfa_type == CFAIsRegisterPlusOffset)
-    {
-        if (m_cfa_reg_num != rhs.m_cfa_reg_num)
-            return false;
-        if (m_cfa_offset != rhs.m_cfa_offset)
-            return false;
-    }
-    if (m_cfa_type == CFAIsRegisterDereferenced)
-    {
-        if (m_cfa_reg_num != rhs.m_cfa_reg_num)
-            return false;
-    }
-
-    return m_register_locations == rhs.m_register_locations;
+    return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value &&
+        m_register_locations == rhs.m_register_locations;
 }
 
 void
@@ -439,7 +434,10 @@ UnwindPlan::PlanValidAtAddress (Address
 
     // If the 0th Row of unwind instructions is missing, or if it doesn't provide
     // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan.
-    if (GetRowAtIndex(0).get() == nullptr || GetRowAtIndex(0)->GetCFARegister() == LLDB_INVALID_REGNUM)
+    // CFA set by a DWARF expression is not currently supported, so ignore that as well.
+    if (GetRowAtIndex(0).get() == nullptr ||
+            GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified ||
+            GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::isDWARFExpression)
     {
         Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
         if (log)





More information about the lldb-commits mailing list