ravitheja updated this revision to Diff 60533.
ravitheja added a comment.

Making EH Frame CFI the full unwinder
when artificial symbols are found.


http://reviews.llvm.org/D21221

Files:
  source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
  source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
  source/Plugins/Process/Utility/RegisterContextLLDB.cpp

Index: source/Plugins/Process/Utility/RegisterContextLLDB.cpp
===================================================================
--- source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -210,12 +210,28 @@
         m_frame_type = eNormalFrame;
     }
 
+    // We've set m_frame_type and m_sym_ctx before these calls.
+
+    m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
+    m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
+
     // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
     // else treat the current pc value as the start_pc and record no offset.
     if (addr_range.GetBaseAddress().IsValid())
     {
         m_start_pc = addr_range.GetBaseAddress();
-        if (m_current_pc.GetSection() == m_start_pc.GetSection())
+        if (m_sym_ctx.symbol->IsSynthetic())
+        {
+            // The current offset should be recalculated here. The m_current_offset is
+            // calculated from the base address of the symbol. The symbol can lie in the PLT
+            // (Procedure Linkage Table) i.e its a symbol stub for external call. In this case
+            // the base address for the unwindplan and the base address of the symbol maybe different, hence
+            // the m_current_offset will be wrong.
+            AddressRange unwind_address_range = m_full_unwind_plan_sp->GetAddressRange();
+            if (unwind_address_range.ContainsFileAddress(m_current_pc))
+                m_current_offset = m_current_pc.GetOffset() - unwind_address_range.GetBaseAddress().GetOffset();
+        }
+        else if (m_current_pc.GetSection() == m_start_pc.GetSection())
         {
             m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
         }
@@ -236,11 +252,6 @@
         m_current_offset_backed_up_one = -1;
     }
 
-    // We've set m_frame_type and m_sym_ctx before these calls.
-
-    m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
-    m_full_unwind_plan_sp = GetFullUnwindPlanForFrame ();
-
     UnwindPlan::RowSP active_row;
     lldb::RegisterKind row_register_kind = eRegisterKindGeneric;
     if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc))
@@ -255,36 +266,14 @@
         }
     }
 
-    if (!active_row.get())
-    {
-        UnwindLogMsg ("could not find an unwindplan row for this frame's pc");
-        m_frame_type = eNotAValidFrame;
-        return;
-    }
-
-
     if (!ReadCFAValueForRow (row_register_kind, active_row, m_cfa))
     {
         // Try the fall back unwind plan since the
         // full unwind plan failed.
-        FuncUnwindersSP func_unwinders_sp;
-        UnwindPlanSP call_site_unwind_plan;
         bool cfa_status = false;
+        if (TryFallbackUnwindPlan())
+            cfa_status = true;
 
-        if (m_sym_ctx_valid)
-        {
-            func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx);
-        }
-
-        if(func_unwinders_sp.get() != nullptr)
-            call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget(), m_current_offset_backed_up_one);
-
-        if (call_site_unwind_plan.get() != nullptr)
-        {
-            m_fallback_unwind_plan_sp = call_site_unwind_plan;
-            if(TryFallbackUnwindPlan())
-                cfa_status = true;
-        }
         if (!cfa_status)
         {
             UnwindLogMsg ("could not read CFA value for first frame.");
@@ -881,6 +870,8 @@
         // call GetUnwindPlanAtCallSite() -- because CallSite may return an unwind plan sourced from
         // either eh_frame (that's what we intend) or compact unwind (this won't work)
         unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan (process->GetTarget(), m_current_offset_backed_up_one);
+        m_fallback_unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+
         if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc))
         {
             UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it",
@@ -1608,8 +1599,8 @@
 
     // If a compiler generated unwind plan failed, trying the arch default unwindplan
     // isn't going to do any better.
-    if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
-        return false;
+//    if (m_full_unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes)
+//        return false;
 
 
     // Get the caller's pc value and our own CFA value.
@@ -1655,7 +1646,32 @@
 
     m_full_unwind_plan_sp = m_fallback_unwind_plan_sp;
 
-    UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
+    // The current offset should be recalculated here. The m_current_offset is
+    // calculated from the base address of the symbol. The symbol can lie in the PLT
+    // (Procedure Linkage Table) i.e its a symbol stub for external call. In this case
+    // the base address for the unwindplan and the base address of the symbol maybe different, hence
+    // the m_current_offset will be wrong.
+
+    int fallback_offset = m_current_offset;
+    AddressRange fall_back_unwind_address_range = m_fallback_unwind_plan_sp->GetAddressRange();
+    if (m_sym_ctx.symbol->IsSynthetic() && fall_back_unwind_address_range.ContainsFileAddress(m_current_pc))
+    {
+        fallback_offset = m_current_pc.GetOffset() - fall_back_unwind_address_range.GetBaseAddress().GetOffset();
+    }
+    else if (m_current_pc.GetSection() == m_start_pc.GetSection())
+    {
+        fallback_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset();
+    }
+    else if (m_current_pc.GetModule() == m_start_pc.GetModule())
+    {
+        // This means that whatever symbol we kicked up isn't really correct
+        // --- we should not cross section boundaries ... We really should NULL out
+        // the function/symbol in this case unless there is a bad assumption
+        // here due to inlined functions?
+        fallback_offset = m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress();
+    }
+
+    UnwindPlan::RowSP active_row = m_fallback_unwind_plan_sp->GetRowForFunctionOffset (fallback_offset);
     
     if (active_row && active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::CFAValue::unspecified)
     {
@@ -1763,6 +1779,9 @@
                                          const UnwindPlan::RowSP &row,
                                          addr_t &cfa_value)
 {
+    if (row.get() == nullptr)
+        return false;
+
     RegisterValue reg_value;
 
     cfa_value = LLDB_INVALID_ADDRESS;
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -72,6 +72,9 @@
     uint32_t
     GetPluginVersion() override;
 
+    bool
+    AlwaysRelyOnEHUnwindInfo (lldb_private::SymbolContext &sym_ctx) override;
+
 protected:
     /// Runtime linker rendezvous structure.
     DYLDRendezvous m_rendezvous;
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -105,6 +105,14 @@
     }
 }
 
+bool
+DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
+{
+    if (sym_ctx.symbol->IsSynthetic())
+        return true;
+    return DynamicLoader::AlwaysRelyOnEHUnwindInfo(sym_ctx);
+}
+
 void
 DynamicLoaderPOSIXDYLD::DidAttach()
 {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to