reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
#ifndef liblldb_FuncUnwinders_h
#define liblldb_FuncUnwinders_h

#include "lldb/Core/AddressRange.h"
#include "lldb/lldb-private-enumerations.h"
#include <mutex>
#include <vector>

namespace lldb_private {

class UnwindTable;

class FuncUnwinders {
public:
  // FuncUnwinders objects are used to track UnwindPlans for a function (named
  // or not - really just an address range)

  // We'll record four different UnwindPlans for each address range:
  //
  //   1. Unwinding from a call site (a valid exception throw location)
  //      This is often sourced from the eh_frame exception handling info
  //   2. Unwinding from a non-call site (any location in the function)
  //      This is often done by analyzing the function prologue assembly
  //      language instructions
  //   3. A fast unwind method for this function which only retrieves a
  //      limited set of registers necessary to walk the stack
  //   4. An architectural default unwind plan when none of the above are
  //      available for some reason.

  // Additionally, FuncUnwinds object can be asked where the prologue
  // instructions are finished for migrating breakpoints past the stack frame
  // setup instructions when we don't have line table information.

  FuncUnwinders(lldb_private::UnwindTable &unwind_table, AddressRange range);

  ~FuncUnwinders();

  lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread);

  lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
                                                lldb_private::Thread &thread);

  lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
                                             lldb_private::Thread &thread);

  lldb::UnwindPlanSP
  GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread);

  lldb::UnwindPlanSP
  GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread);

  Address &GetFirstNonPrologueInsn(Target &target);

  const Address &GetFunctionStartAddress() const;

  bool ContainsAddress(const Address &addr) const {
    return m_range.ContainsFileAddress(addr);
  }

  // A function may have a Language Specific Data Area specified -- a block of
  // data in
  // the object file which is used in the processing of an exception throw /
  // catch. If any of the UnwindPlans have the address of the LSDA region for
  // this function, this will return it.
  Address GetLSDAAddress(Target &target);

  // A function may have a Personality Routine associated with it -- used in the
  // processing of throwing an exception.  If any of the UnwindPlans have the
  // address of the personality routine, this will return it.  Read the target-
  // pointer at this address to get the personality function address.
  Address GetPersonalityRoutinePtrAddress(Target &target);

  // The following methods to retrieve specific unwind plans should rarely be
  // 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);

  lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target);

  lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target,
                                                      Thread &thread);

  lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target);

  lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
                                                   Thread &thread);

  lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target);

  lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
                                                      Thread &thread);

  lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target);

  lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target);

  lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread);

  lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);

  lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);

private:
  lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target);

  // Do a simplistic comparison for the register restore rule for getting the
  // caller's pc value on two UnwindPlans -- returns LazyBoolYes if they have
  // the same unwind rule for the pc, LazyBoolNo if they do not have the same
  // unwind rule for the pc, and LazyBoolCalculate if it was unable to
  // determine this for some reason.
  lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation(
      Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b);

  UnwindTable &m_unwind_table;
  AddressRange m_range;

  std::recursive_mutex m_mutex;

  lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
  lldb::UnwindPlanSP m_unwind_plan_object_file_sp;
  lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
  lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;

  // augmented by assembly inspection so it's valid everywhere
  lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp;
  lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
  lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;

  std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
  lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp;
  lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp;
  lldb::UnwindPlanSP m_unwind_plan_fast_sp;
  lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
  lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;

  // Fetching the UnwindPlans can be expensive - if we've already attempted to
  // get one & failed, don't try again.
  bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1,
      m_tried_unwind_plan_object_file : 1,
      m_tried_unwind_plan_debug_frame : 1,
      m_tried_unwind_plan_object_file_augmented : 1,
      m_tried_unwind_plan_eh_frame_augmented : 1,
      m_tried_unwind_plan_debug_frame_augmented : 1,
      m_tried_unwind_plan_compact_unwind : 1,
      m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_plan_symbol_file : 1,
      m_tried_unwind_fast : 1, m_tried_unwind_arch_default : 1,
      m_tried_unwind_arch_default_at_func_entry : 1;

  Address m_first_non_prologue_insn;

  DISALLOW_COPY_AND_ASSIGN(FuncUnwinders);

}; // class FuncUnwinders

} // namespace lldb_private

#endif // liblldb_FuncUnwinders_h