[Lldb-commits] [lldb] r162167 - in /lldb/trunk: include/lldb/Symbol/DWARFCallFrameInfo.h include/lldb/Symbol/UnwindPlan.h source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Symbol/DWARFCallFrameInfo.cpp

Jason Molenda jmolenda at apple.com
Fri Aug 17 23:53:34 PDT 2012


Author: jmolenda
Date: Sat Aug 18 01:53:34 2012
New Revision: 162167

URL: http://llvm.org/viewvc/llvm-project?rev=162167&view=rev
Log:
Some eh_frame unwind instructions will define a return address register;
when you want to find the caller's saved pc, you look up the return address
register and use that.  On arm, for instance, this would be the contents of
the link register (lr).

If the eh_frame CIE defines an RA, record that fact in the UnwindPlan.

When we're finding a saved register, if it's the pc, lok for the location
of the return address register instead.

<rdar://problem/12062310> 

Modified:
    lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
    lldb/trunk/include/lldb/Symbol/UnwindPlan.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp

Modified: lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h?rev=162167&r1=162166&r2=162167&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h (original)
+++ lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h Sat Aug 18 01:53:34 2012
@@ -75,7 +75,7 @@
         lldb_private::UnwindPlan::Row initial_row;
 
         CIE(dw_offset_t offset) : cie_offset(offset), version (-1), code_align (0),
-                                  data_align (0), return_addr_reg_num (-1), inst_offset (0),
+                                  data_align (0), return_addr_reg_num (LLDB_INVALID_REGNUM), inst_offset (0),
                                   inst_length (0), ptr_encoding (0), initial_row() {}
     };
 

Modified: lldb/trunk/include/lldb/Symbol/UnwindPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindPlan.h?rev=162167&r1=162166&r2=162167&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindPlan.h (original)
+++ lldb/trunk/include/lldb/Symbol/UnwindPlan.h Sat Aug 18 01:53:34 2012
@@ -348,6 +348,7 @@
         m_row_list (), 
         m_plan_valid_address_range (), 
         m_register_kind (reg_kind), 
+        m_return_addr_register (LLDB_INVALID_REGNUM),
         m_source_name ()
     {
     }
@@ -381,6 +382,18 @@
         m_register_kind = kind;
     }
     
+    void
+    SetReturnAddressRegister (uint32_t regnum)
+    {
+        m_return_addr_register = regnum;
+    }
+    
+    uint32_t
+    GetReturnAddressRegister (void)
+    {
+        return m_return_addr_register;
+    }
+
     uint32_t
     GetInitialCFARegister () const
     {
@@ -441,7 +454,9 @@
     collection m_row_list;
     AddressRange m_plan_valid_address_range;
     lldb::RegisterKind m_register_kind;   // The RegisterKind these register numbers are in terms of - will need to be
-                                // translated to lldb native reg nums at unwind time
+                                          // translated to lldb native reg nums at unwind time
+    uint32_t m_return_addr_register;      // The register that has the return address for the caller frame
+                                          // e.g. the lr on arm
     lldb_private::ConstString m_source_name;  // for logging, where this UnwindPlan originated from
 }; // class UnwindPlan
 

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=162167&r1=162166&r2=162167&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Sat Aug 18 01:53:34 2012
@@ -1034,6 +1034,12 @@
         return true;
     }
 
+    uint32_t pc_regnum;
+    if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, eRegisterKindLLDB, pc_regnum))
+    {
+        pc_regnum = LLDB_INVALID_REGNUM;
+    }
+
     // Look through the available UnwindPlans for the register location.
 
     UnwindPlan::Row::RegisterLocation unwindplan_regloc;
@@ -1078,20 +1084,35 @@
             UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
             unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
             uint32_t row_regnum;
-            if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
+
+            // If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm),
+            // look for the return address register number in the UnwindPlan's row.
+            if (lldb_regnum == pc_regnum && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
             {
-                if (log)
+               row_regnum = m_full_unwind_plan_sp->GetReturnAddressRegister();
+               if (log)
+               {
+                   log->Printf("%*sFrame %u requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead",
+                               m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, row_regnum);
+               }
+            }
+            else
+            {
+                if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum))
                 {
-                    if (unwindplan_registerkind == eRegisterKindGeneric)
-                        log->Printf("%*sFrame %u could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme",
-                                    m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                                    lldb_regnum);
-                    else
-                        log->Printf("%*sFrame %u could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
-                                    m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
-                                    lldb_regnum, (int) unwindplan_registerkind);
+                    if (log)
+                    {
+                        if (unwindplan_registerkind == eRegisterKindGeneric)
+                            log->Printf("%*sFrame %u could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme",
+                                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                                        lldb_regnum);
+                        else
+                            log->Printf("%*sFrame %u could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
+                                        m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+                                        lldb_regnum, (int) unwindplan_registerkind);
+                    }
+                    return false;
                 }
-                return false;
             }
 
             if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=162167&r1=162166&r2=162167&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Sat Aug 18 01:53:34 2012
@@ -407,6 +407,7 @@
     UnwindPlan::RowSP row(cie_initial_row);
 
     unwind_plan.SetRegisterKind (m_reg_kind);
+    unwind_plan.SetReturnAddressRegister (cie->return_addr_reg_num);
 
     UnwindPlan::Row::RegisterLocation reg_location;
     while (m_cfi_data.ValidOffset(offset) && offset < end_offset)





More information about the lldb-commits mailing list