[Lldb-commits] [lldb] r358964 - FuncUnwinders: remove "current_offset" from function arguments

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 23 02:57:14 PDT 2019


Author: labath
Date: Tue Apr 23 02:57:14 2019
New Revision: 358964

URL: http://llvm.org/viewvc/llvm-project?rev=358964&view=rev
Log:
FuncUnwinders: remove "current_offset" from function arguments

Summary:
This argument was added back in 2010 (r118882) to support the ability to unwind
from functions whose eh_frame entry does not cover the entire range of
the function.

However, due to the caching happening in FuncUnwinders, this solution is
very fragile. FuncUnwinders will cache the plan it got from eh_frame
regardless of the value of the current_offset, so our ability to unwind
from a given function depended what was the value of "current_offset" the
first time that this function was called.

Furthermore, since the "image show-unwind" command did not know what's
the right offset to pass, this created an unfortunate situation where
"image show-unwind" would show no valid plans for a function, even
though they were available and being used.

In this patch I implement the feature slightly differently. Instead of
giving just a base address to the eh_frame unwinder, I give it the
entire range we are interested in. Then, I change the unwinder to return
the first plan that covers (even partially) that range. This way even a
partial plan will be returned, regardless of the address in the function
where we are stopped at.

This solution is still not 100% correct, as it will not handle a
function which is covered by two independent fde entries. However, I
don't expect anybody will write this kind of functions, and this wasn't
handled by the previous implementation either. If this is ever needed in
the future. The eh_frame unwinder can be extended to return "composite"
unwind plans created by merging sevelar fde entries.

I also create a test which triggers this scenario. As doing this is
virtually impossible without hand-written assembly, the test only works
on x86 linux.

Reviewers: jasonmolenda, clayborg

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D60829

Added:
    lldb/trunk/lit/Unwind/Inputs/eh-frame-small-fde.s
    lldb/trunk/lit/Unwind/eh-frame-small-fde.test
Modified:
    lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
    lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
    lldb/trunk/include/lldb/Utility/RangeMap.h
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
    lldb/trunk/source/Symbol/FuncUnwinders.cpp

Modified: lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h?rev=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h (original)
+++ lldb/trunk/include/lldb/Symbol/DWARFCallFrameInfo.h Tue Apr 23 02:57:14 2019
@@ -43,9 +43,15 @@ public:
   // address.
   bool GetAddressRange(Address addr, AddressRange &range);
 
-  // Return an UnwindPlan based on the call frame information encoded in the
-  // FDE of this DWARFCallFrameInfo section.
-  bool GetUnwindPlan(Address addr, UnwindPlan &unwind_plan);
+  /// Return an UnwindPlan based on the call frame information encoded in the
+  /// FDE of this DWARFCallFrameInfo section. The returned plan will be valid
+  /// (at least) for the given address.
+  bool GetUnwindPlan(const Address &addr, UnwindPlan &unwind_plan);
+
+  /// Return an UnwindPlan based on the call frame information encoded in the
+  /// FDE of this DWARFCallFrameInfo section. The returned plan will be valid
+  /// (at least) for some address in the given range.
+  bool GetUnwindPlan(const AddressRange &range, UnwindPlan &unwind_plan);
 
   typedef RangeVector<lldb::addr_t, uint32_t> FunctionAddressAndSizeVector;
 
@@ -115,8 +121,8 @@ private:
 
   bool IsEHFrame() const;
 
-  bool GetFDEEntryByFileAddress(lldb::addr_t file_offset,
-                                FDEEntryMap::Entry &fde_entry);
+  llvm::Optional<FDEEntryMap::Entry>
+  GetFirstFDEEntryInRange(const AddressRange &range);
 
   void GetFDEIndex();
 

Modified: lldb/trunk/include/lldb/Symbol/FuncUnwinders.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/FuncUnwinders.h?rev=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/FuncUnwinders.h (original)
+++ lldb/trunk/include/lldb/Symbol/FuncUnwinders.h Tue Apr 23 02:57:14 2019
@@ -35,17 +35,10 @@ public:
 
   ~FuncUnwinders();
 
-  // current_offset is the byte offset into the function.
-  // 0 means no instructions have executed yet.  -1 means the offset is unknown.
-  // On architectures where the pc points to the next instruction that will
-  // execute, this offset value will have already been decremented by 1 to stay
-  // within the bounds of the correct function body.
-  lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target,
-                                             int current_offset);
+  lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target);
 
   lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
-                                                lldb_private::Thread &thread,
-                                                int current_offset);
+                                                lldb_private::Thread &thread);
 
   lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
                                              lldb_private::Thread &thread);
@@ -81,26 +74,21 @@ public:
   // used. Instead, clients should ask for the *behavior* they are looking for,
   // using one of the above UnwindPlan retrieval methods.
 
-  lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread,
-                                           int current_offset);
+  lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread);
 
-  lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target, int current_offset);
+  lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target);
 
   lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
-                                                   Thread &thread,
-                                                   int current_offset);
+                                                   Thread &thread);
 
-  lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target,
-                                             int current_offset);
+  lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target);
 
   lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
-                                                      Thread &thread,
-                                                      int current_offset);
+                                                      Thread &thread);
 
-  lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target,
-                                                int current_offset);
+  lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target);
 
-  lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target, int current_offset);
+  lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target);
 
   lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);
 

Modified: lldb/trunk/include/lldb/Utility/RangeMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/RangeMap.h?rev=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/RangeMap.h (original)
+++ lldb/trunk/include/lldb/Utility/RangeMap.h Tue Apr 23 02:57:14 2019
@@ -624,6 +624,7 @@ struct RangeData : public Range<B, S> {
 template <typename B, typename S, typename T, unsigned N = 0>
 class RangeDataVector {
 public:
+  typedef lldb_private::Range<B, S> Range;
   typedef RangeData<B, S, T> Entry;
   typedef llvm::SmallVector<Entry, N> Collection;
 

Added: lldb/trunk/lit/Unwind/Inputs/eh-frame-small-fde.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Unwind/Inputs/eh-frame-small-fde.s?rev=358964&view=auto
==============================================================================
--- lldb/trunk/lit/Unwind/Inputs/eh-frame-small-fde.s (added)
+++ lldb/trunk/lit/Unwind/Inputs/eh-frame-small-fde.s Tue Apr 23 02:57:14 2019
@@ -0,0 +1,48 @@
+        .text
+        .globl  bar
+        .type   bar, @function
+bar:
+.LFB0:
+        .cfi_startproc
+        leal    (%edi, %edi), %eax
+        ret
+        .cfi_endproc
+.LFE0:
+        .size   bar, .-bar
+        .globl  foo
+        .type   foo, @function
+foo:
+.LFB1:
+        nop # Make the FDE entry start one byte later than the actual function.
+        .cfi_startproc
+        .cfi_register %rip, %r13
+        call    bar
+        addl    $1, %eax
+        jmp     *%r13 # Return
+        .cfi_endproc
+.LFE1:
+        .size   foo, .-foo
+        .globl  main
+        .type   main, @function
+main:
+.LFB2:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+        movl    $47, %edi
+
+        # Non-standard calling convention. Put return address in r13.
+        pushq   %r13
+        leaq    1f(%rip), %r13
+        jmp     foo # call
+1:
+        popq    %r13
+        popq    %rbp
+        .cfi_def_cfa 7, 8
+        ret
+        .cfi_endproc
+.LFE2:
+        .size   main, .-main

Added: lldb/trunk/lit/Unwind/eh-frame-small-fde.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Unwind/eh-frame-small-fde.test?rev=358964&view=auto
==============================================================================
--- lldb/trunk/lit/Unwind/eh-frame-small-fde.test (added)
+++ lldb/trunk/lit/Unwind/eh-frame-small-fde.test Tue Apr 23 02:57:14 2019
@@ -0,0 +1,22 @@
+# This test that we are able to unwind using eh_frame in case an FDE entry does
+# not cover the entire range of a function we are unwinding through.
+
+# REQUIRES: target-x86_64, system-linux, native
+
+# RUN: %clang %p/Inputs/eh-frame-small-fde.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n bar
+# CHECK: Breakpoint 1: where = {{.*}}`bar
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`bar
+# CHECK: frame #1: {{.*}}`foo + 6
+# CHECK: frame #2: {{.*}}`main + 20
+
+target modules show-unwind -n foo
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]: 0: CFA=rsp +8 => rip=r13

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Tue Apr 23 02:57:14 2019
@@ -3515,14 +3515,14 @@ protected:
           funcname.AsCString(), start_addr);
 
       UnwindPlanSP non_callsite_unwind_plan =
-          func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
+          func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
       if (non_callsite_unwind_plan) {
         result.GetOutputStream().Printf(
             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
             non_callsite_unwind_plan->GetSourceName().AsCString());
       }
       UnwindPlanSP callsite_unwind_plan =
-          func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
+          func_unwinders_sp->GetUnwindPlanAtCallSite(*target);
       if (callsite_unwind_plan) {
         result.GetOutputStream().Printf(
             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
@@ -3539,7 +3539,7 @@ protected:
       result.GetOutputStream().Printf("\n");
 
       UnwindPlanSP assembly_sp =
-          func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
+          func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
       if (assembly_sp) {
         result.GetOutputStream().Printf(
             "Assembly language inspection UnwindPlan:\n");
@@ -3549,7 +3549,7 @@ protected:
       }
 
       UnwindPlanSP ehframe_sp =
-          func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
+          func_unwinders_sp->GetEHFrameUnwindPlan(*target);
       if (ehframe_sp) {
         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
@@ -3558,7 +3558,7 @@ protected:
       }
 
       UnwindPlanSP ehframe_augmented_sp =
-          func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
+          func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
       if (ehframe_augmented_sp) {
         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
@@ -3567,7 +3567,7 @@ protected:
       }
 
       if (UnwindPlanSP plan_sp =
-              func_unwinders_sp->GetDebugFrameUnwindPlan(*target, 0)) {
+              func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
         plan_sp->Dump(result.GetOutputStream(), thread.get(),
                       LLDB_INVALID_ADDRESS);
@@ -3576,7 +3576,7 @@ protected:
 
       if (UnwindPlanSP plan_sp =
               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
-                                                                  *thread, 0)) {
+                                                                  *thread)) {
         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
         plan_sp->Dump(result.GetOutputStream(), thread.get(),
                       LLDB_INVALID_ADDRESS);
@@ -3584,7 +3584,7 @@ protected:
       }
 
       UnwindPlanSP arm_unwind_sp =
-          func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
+          func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
       if (arm_unwind_sp) {
         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
@@ -3593,7 +3593,7 @@ protected:
       }
 
       UnwindPlanSP compact_unwind_sp =
-          func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
+          func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
       if (compact_unwind_sp) {
         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),

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=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Tue Apr 23 02:57:14 2019
@@ -244,8 +244,8 @@ void RegisterContextLLDB::InitializeZero
     }
 
     if (func_unwinders_sp.get() != nullptr)
-      call_site_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(
-          process->GetTarget(), m_current_offset_backed_up_one);
+      call_site_unwind_plan =
+          func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
 
     if (call_site_unwind_plan.get() != nullptr) {
       m_fallback_unwind_plan_sp = call_site_unwind_plan;
@@ -822,8 +822,8 @@ UnwindPlanSP RegisterContextLLDB::GetFul
   // unwind out of sigtramp.
   if (m_frame_type == eTrapHandlerFrame && process) {
     m_fast_unwind_plan_sp.reset();
-    unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(
-        process->GetTarget(), m_current_offset_backed_up_one);
+    unwind_plan_sp =
+        func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
     if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc) &&
         unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolYes) {
       return unwind_plan_sp;
@@ -844,8 +844,8 @@ UnwindPlanSP RegisterContextLLDB::GetFul
     // normally we would 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);
+    unwind_plan_sp =
+        func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget());
     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",
@@ -858,7 +858,7 @@ UnwindPlanSP RegisterContextLLDB::GetFul
   // the assembly language instructions
   if (behaves_like_zeroth_frame && process) {
     unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
-        process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+        process->GetTarget(), m_thread);
     if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress(m_current_pc)) {
       if (unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
         // We probably have an UnwindPlan created by inspecting assembly
@@ -873,8 +873,7 @@ UnwindPlanSP RegisterContextLLDB::GetFul
         // location what helps in the most common cases when the instruction
         // emulation fails.
         UnwindPlanSP call_site_unwind_plan =
-            func_unwinders_sp->GetUnwindPlanAtCallSite(
-                process->GetTarget(), m_current_offset_backed_up_one);
+            func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
         if (call_site_unwind_plan &&
             call_site_unwind_plan.get() != unwind_plan_sp.get() &&
             call_site_unwind_plan->GetSourceName() !=
@@ -893,8 +892,8 @@ UnwindPlanSP RegisterContextLLDB::GetFul
   // Typically this is unwind info from an eh_frame section intended for
   // exception handling; only valid at call sites
   if (process) {
-    unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite(
-        process->GetTarget(), m_current_offset_backed_up_one);
+    unwind_plan_sp =
+        func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
   }
   int valid_offset = -1;
   if (IsUnwindPlanValidForCurrentPC(unwind_plan_sp, valid_offset)) {
@@ -908,7 +907,7 @@ UnwindPlanSP RegisterContextLLDB::GetFul
   // call-site assembly inspection UnwindPlan if possible.
   if (process) {
     unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite(
-        process->GetTarget(), m_thread, m_current_offset_backed_up_one);
+        process->GetTarget(), m_thread);
   }
   if (unwind_plan_sp &&
       unwind_plan_sp->GetSourcedFromCompiler() == eLazyBoolNo) {
@@ -923,8 +922,7 @@ UnwindPlanSP RegisterContextLLDB::GetFul
     // code it is often written in a way that it valid at all location what
     // helps in the most common cases when the instruction emulation fails.
     UnwindPlanSP call_site_unwind_plan =
-        func_unwinders_sp->GetUnwindPlanAtCallSite(
-            process->GetTarget(), m_current_offset_backed_up_one);
+        func_unwinders_sp->GetUnwindPlanAtCallSite(process->GetTarget());
     if (call_site_unwind_plan &&
         call_site_unwind_plan.get() != unwind_plan_sp.get() &&
         call_site_unwind_plan->GetSourceName() !=

Modified: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp?rev=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp (original)
+++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp Tue Apr 23 02:57:14 2019
@@ -146,8 +146,15 @@ DWARFCallFrameInfo::DWARFCallFrameInfo(O
                                        SectionSP &section_sp, Type type)
     : m_objfile(objfile), m_section_sp(section_sp), m_type(type) {}
 
-bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) {
+bool DWARFCallFrameInfo::GetUnwindPlan(const Address &addr,
+                                       UnwindPlan &unwind_plan) {
+  return GetUnwindPlan(AddressRange(addr, 1), unwind_plan);
+}
+
+bool DWARFCallFrameInfo::GetUnwindPlan(const AddressRange &range,
+                                       UnwindPlan &unwind_plan) {
   FDEEntryMap::Entry fde_entry;
+  Address addr = range.GetBaseAddress();
 
   // Make sure that the Address we're searching for is the same object file as
   // this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
@@ -156,9 +163,9 @@ bool DWARFCallFrameInfo::GetUnwindPlan(A
       module_sp->GetObjectFile() != &m_objfile)
     return false;
 
-  if (!GetFDEEntryByFileAddress(addr.GetFileAddress(), fde_entry))
-    return false;
-  return FDEToUnwindPlan(fde_entry.data, addr, unwind_plan);
+  if (llvm::Optional<FDEEntryMap::Entry> entry = GetFirstFDEEntryInRange(range))
+    return FDEToUnwindPlan(entry->data, addr, unwind_plan);
+  return false;
 }
 
 bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) {
@@ -183,23 +190,21 @@ bool DWARFCallFrameInfo::GetAddressRange
   return true;
 }
 
-bool DWARFCallFrameInfo::GetFDEEntryByFileAddress(
-    addr_t file_addr, FDEEntryMap::Entry &fde_entry) {
-  if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted())
-    return false;
+llvm::Optional<DWARFCallFrameInfo::FDEEntryMap::Entry>
+DWARFCallFrameInfo::GetFirstFDEEntryInRange(const AddressRange &range) {
+  if (!m_section_sp || m_section_sp->IsEncrypted())
+    return llvm::None;
 
   GetFDEIndex();
 
-  if (m_fde_index.IsEmpty())
-    return false;
-
-  FDEEntryMap::Entry *fde = m_fde_index.FindEntryThatContains(file_addr);
+  addr_t start_file_addr = range.GetBaseAddress().GetFileAddress();
+  const FDEEntryMap::Entry *fde =
+      m_fde_index.FindEntryThatContainsOrFollows(start_file_addr);
+  if (fde && fde->DoesIntersect(
+                 FDEEntryMap::Range(start_file_addr, range.GetByteSize())))
+    return *fde;
 
-  if (fde == nullptr)
-    return false;
-
-  fde_entry = *fde;
-  return true;
+  return llvm::None;
 }
 
 void DWARFCallFrameInfo::GetFunctionAddressAndSizeVector(

Modified: lldb/trunk/source/Symbol/FuncUnwinders.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/FuncUnwinders.cpp?rev=358964&r1=358963&r2=358964&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/FuncUnwinders.cpp (original)
+++ lldb/trunk/source/Symbol/FuncUnwinders.cpp Tue Apr 23 02:57:14 2019
@@ -51,24 +51,22 @@ FuncUnwinders::FuncUnwinders(UnwindTable
 
 FuncUnwinders::~FuncUnwinders() {}
 
-UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target,
-                                                    int current_offset) {
+UnwindPlanSP FuncUnwinders::GetUnwindPlanAtCallSite(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
 
-  if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target, current_offset))
+  if (UnwindPlanSP plan_sp = GetEHFrameUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target, current_offset))
+  if (UnwindPlanSP plan_sp = GetDebugFrameUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target, current_offset))
+  if (UnwindPlanSP plan_sp = GetCompactUnwindUnwindPlan(target))
     return plan_sp;
-  if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target, current_offset))
+  if (UnwindPlanSP plan_sp = GetArmUnwindUnwindPlan(target))
     return plan_sp;
 
   return nullptr;
 }
 
-UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target,
-                                                       int current_offset) {
+UnwindPlanSP FuncUnwinders::GetCompactUnwindUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_compact_unwind.size() > 0)
     return m_unwind_plan_compact_unwind[0]; // FIXME support multiple compact
@@ -79,8 +77,6 @@ UnwindPlanSP FuncUnwinders::GetCompactUn
   m_tried_unwind_plan_compact_unwind = true;
   if (m_range.GetBaseAddress().IsValid()) {
     Address current_pc(m_range.GetBaseAddress());
-    if (current_offset != -1)
-      current_pc.SetOffset(current_pc.GetOffset() + current_offset);
     CompactUnwindInfo *compact_unwind = m_unwind_table.GetCompactUnwindInfo();
     if (compact_unwind) {
       UnwindPlanSP unwind_plan_sp(new UnwindPlan(lldb::eRegisterKindGeneric));
@@ -95,53 +91,43 @@ UnwindPlanSP FuncUnwinders::GetCompactUn
   return UnwindPlanSP();
 }
 
-UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target,
-                                                 int current_offset) {
+UnwindPlanSP FuncUnwinders::GetEHFrameUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_eh_frame_sp.get() || m_tried_unwind_plan_eh_frame)
     return m_unwind_plan_eh_frame_sp;
 
   m_tried_unwind_plan_eh_frame = true;
   if (m_range.GetBaseAddress().IsValid()) {
-    Address current_pc(m_range.GetBaseAddress());
-    if (current_offset != -1)
-      current_pc.SetOffset(current_pc.GetOffset() + current_offset);
     DWARFCallFrameInfo *eh_frame = m_unwind_table.GetEHFrameInfo();
     if (eh_frame) {
       m_unwind_plan_eh_frame_sp =
           std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!eh_frame->GetUnwindPlan(current_pc, *m_unwind_plan_eh_frame_sp))
+      if (!eh_frame->GetUnwindPlan(m_range, *m_unwind_plan_eh_frame_sp))
         m_unwind_plan_eh_frame_sp.reset();
     }
   }
   return m_unwind_plan_eh_frame_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target,
-                                                    int current_offset) {
+UnwindPlanSP FuncUnwinders::GetDebugFrameUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_debug_frame_sp || m_tried_unwind_plan_debug_frame)
     return m_unwind_plan_debug_frame_sp;
 
   m_tried_unwind_plan_debug_frame = true;
   if (m_range.GetBaseAddress().IsValid()) {
-    Address current_pc(m_range.GetBaseAddress());
-    if (current_offset != -1)
-      current_pc.SetOffset(current_pc.GetOffset() + current_offset);
     DWARFCallFrameInfo *debug_frame = m_unwind_table.GetDebugFrameInfo();
     if (debug_frame) {
       m_unwind_plan_debug_frame_sp =
           std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric);
-      if (!debug_frame->GetUnwindPlan(current_pc,
-                                      *m_unwind_plan_debug_frame_sp))
+      if (!debug_frame->GetUnwindPlan(m_range, *m_unwind_plan_debug_frame_sp))
         m_unwind_plan_debug_frame_sp.reset();
     }
   }
   return m_unwind_plan_debug_frame_sp;
 }
 
-UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target,
-                                                   int current_offset) {
+UnwindPlanSP FuncUnwinders::GetArmUnwindUnwindPlan(Target &target) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_arm_unwind_sp.get() || m_tried_unwind_plan_arm_unwind)
     return m_unwind_plan_arm_unwind_sp;
@@ -149,8 +135,6 @@ UnwindPlanSP FuncUnwinders::GetArmUnwind
   m_tried_unwind_plan_arm_unwind = true;
   if (m_range.GetBaseAddress().IsValid()) {
     Address current_pc(m_range.GetBaseAddress());
-    if (current_offset != -1)
-      current_pc.SetOffset(current_pc.GetOffset() + current_offset);
     ArmUnwindInfo *arm_unwind_info = m_unwind_table.GetArmUnwindInfo();
     if (arm_unwind_info) {
       m_unwind_plan_arm_unwind_sp =
@@ -164,8 +148,7 @@ UnwindPlanSP FuncUnwinders::GetArmUnwind
 }
 
 UnwindPlanSP FuncUnwinders::GetEHFrameAugmentedUnwindPlan(Target &target,
-                                                          Thread &thread,
-                                                          int current_offset) {
+                                                          Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_eh_frame_augmented_sp.get() ||
       m_tried_unwind_plan_eh_frame_augmented)
@@ -183,7 +166,7 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAu
 
   m_tried_unwind_plan_eh_frame_augmented = true;
 
-  UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target, current_offset);
+  UnwindPlanSP eh_frame_plan = GetEHFrameUnwindPlan(target);
   if (!eh_frame_plan)
     return m_unwind_plan_eh_frame_augmented_sp;
 
@@ -205,9 +188,8 @@ UnwindPlanSP FuncUnwinders::GetEHFrameAu
   return m_unwind_plan_eh_frame_augmented_sp;
 }
 
-UnwindPlanSP
-FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread,
-                                                int current_offset) {
+UnwindPlanSP FuncUnwinders::GetDebugFrameAugmentedUnwindPlan(Target &target,
+                                                             Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_debug_frame_augmented_sp.get() ||
       m_tried_unwind_plan_debug_frame_augmented)
@@ -225,8 +207,7 @@ FuncUnwinders::GetDebugFrameAugmentedUnw
 
   m_tried_unwind_plan_debug_frame_augmented = true;
 
-  UnwindPlanSP debug_frame_plan =
-      GetDebugFrameUnwindPlan(target, current_offset);
+  UnwindPlanSP debug_frame_plan = GetDebugFrameUnwindPlan(target);
   if (!debug_frame_plan)
     return m_unwind_plan_debug_frame_augmented_sp;
 
@@ -249,8 +230,7 @@ FuncUnwinders::GetDebugFrameAugmentedUnw
 }
 
 UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target,
-                                                  Thread &thread,
-                                                  int current_offset) {
+                                                  Thread &thread) {
   std::lock_guard<std::recursive_mutex> guard(m_mutex);
   if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly ||
       !m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) {
@@ -306,16 +286,14 @@ LazyBool FuncUnwinders::CompareUnwindPla
 }
 
 UnwindPlanSP FuncUnwinders::GetUnwindPlanAtNonCallSite(Target &target,
-                                                       Thread &thread,
-                                                       int current_offset) {
-  UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target, current_offset);
+                                                       Thread &thread) {
+  UnwindPlanSP eh_frame_sp = GetEHFrameUnwindPlan(target);
   if (!eh_frame_sp)
-    eh_frame_sp = GetDebugFrameUnwindPlan(target, current_offset);
+    eh_frame_sp = GetDebugFrameUnwindPlan(target);
   UnwindPlanSP arch_default_at_entry_sp =
       GetUnwindPlanArchitectureDefaultAtFunctionEntry(thread);
   UnwindPlanSP arch_default_sp = GetUnwindPlanArchitectureDefault(thread);
-  UnwindPlanSP assembly_sp =
-      GetAssemblyUnwindPlan(target, thread, current_offset);
+  UnwindPlanSP assembly_sp = GetAssemblyUnwindPlan(target, thread);
 
   // This point of this code is to detect when a function is using a non-
   // standard ABI, and the eh_frame correctly describes that alternate ABI.
@@ -344,11 +322,9 @@ UnwindPlanSP FuncUnwinders::GetUnwindPla
     return eh_frame_sp;
   }
 
-  if (UnwindPlanSP plan_sp =
-          GetEHFrameAugmentedUnwindPlan(target, thread, current_offset))
+  if (UnwindPlanSP plan_sp = GetEHFrameAugmentedUnwindPlan(target, thread))
     return plan_sp;
-  if (UnwindPlanSP plan_sp =
-          GetDebugFrameAugmentedUnwindPlan(target, thread, current_offset))
+  if (UnwindPlanSP plan_sp = GetDebugFrameAugmentedUnwindPlan(target, thread))
     return plan_sp;
 
   return assembly_sp;
@@ -453,9 +429,9 @@ FuncUnwinders::GetUnwindAssemblyProfiler
 Address FuncUnwinders::GetLSDAAddress(Target &target) {
   Address lsda_addr;
 
-  UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target, -1);
+  UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target);
   if (unwind_plan_sp.get() == nullptr) {
-    unwind_plan_sp = GetCompactUnwindUnwindPlan(target, -1);
+    unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
   }
   if (unwind_plan_sp.get() && unwind_plan_sp->GetLSDAAddress().IsValid()) {
     lsda_addr = unwind_plan_sp->GetLSDAAddress();
@@ -466,9 +442,9 @@ Address FuncUnwinders::GetLSDAAddress(Ta
 Address FuncUnwinders::GetPersonalityRoutinePtrAddress(Target &target) {
   Address personality_addr;
 
-  UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target, -1);
+  UnwindPlanSP unwind_plan_sp = GetEHFrameUnwindPlan(target);
   if (unwind_plan_sp.get() == nullptr) {
-    unwind_plan_sp = GetCompactUnwindUnwindPlan(target, -1);
+    unwind_plan_sp = GetCompactUnwindUnwindPlan(target);
   }
   if (unwind_plan_sp.get() &&
       unwind_plan_sp->GetPersonalityFunctionPtr().IsValid()) {




More information about the lldb-commits mailing list