1 #ifndef LLDB_SYMBOL_FUNCUNWINDERS_H 2 #define LLDB_SYMBOL_FUNCUNWINDERS_H 3 4 #include "lldb/Core/AddressRange.h" 5 #include "lldb/lldb-private-enumerations.h" 6 #include <mutex> 7 #include <vector> 8 9 namespace lldb_private { 10 11 class UnwindTable; 12 13 class FuncUnwinders { 14 public: 15 // FuncUnwinders objects are used to track UnwindPlans for a function (named 16 // or not - really just an address range) 17 18 // We'll record four different UnwindPlans for each address range: 19 // 20 // 1. Unwinding from a call site (a valid exception throw location) 21 // This is often sourced from the eh_frame exception handling info 22 // 2. Unwinding from a non-call site (any location in the function) 23 // This is often done by analyzing the function prologue assembly 24 // language instructions 25 // 3. A fast unwind method for this function which only retrieves a 26 // limited set of registers necessary to walk the stack 27 // 4. An architectural default unwind plan when none of the above are 28 // available for some reason. 29 30 // Additionally, FuncUnwinds object can be asked where the prologue 31 // instructions are finished for migrating breakpoints past the stack frame 32 // setup instructions when we don't have line table information. 33 34 FuncUnwinders(lldb_private::UnwindTable &unwind_table, AddressRange range); 35 36 ~FuncUnwinders(); 37 38 lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread); 39 40 lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target, 41 lldb_private::Thread &thread); 42 43 lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target, 44 lldb_private::Thread &thread); 45 46 lldb::UnwindPlanSP 47 GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread); 48 49 lldb::UnwindPlanSP 50 GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread); 51 52 Address &GetFirstNonPrologueInsn(Target &target); 53 54 const Address &GetFunctionStartAddress() const; 55 ContainsAddress(const Address & addr)56 bool ContainsAddress(const Address &addr) const { 57 return m_range.ContainsFileAddress(addr); 58 } 59 60 // A function may have a Language Specific Data Area specified -- a block of 61 // data in 62 // the object file which is used in the processing of an exception throw / 63 // catch. If any of the UnwindPlans have the address of the LSDA region for 64 // this function, this will return it. 65 Address GetLSDAAddress(Target &target); 66 67 // A function may have a Personality Routine associated with it -- used in the 68 // processing of throwing an exception. If any of the UnwindPlans have the 69 // address of the personality routine, this will return it. Read the target- 70 // pointer at this address to get the personality function address. 71 Address GetPersonalityRoutinePtrAddress(Target &target); 72 73 // The following methods to retrieve specific unwind plans should rarely be 74 // used. Instead, clients should ask for the *behavior* they are looking for, 75 // using one of the above UnwindPlan retrieval methods. 76 77 lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread); 78 79 lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target); 80 81 lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target, 82 Thread &thread); 83 84 lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target); 85 86 lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target, 87 Thread &thread); 88 89 lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target); 90 91 lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target, 92 Thread &thread); 93 94 lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target); 95 96 lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target); 97 98 lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread); 99 100 lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread); 101 102 lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread); 103 104 private: 105 lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target); 106 107 // Do a simplistic comparison for the register restore rule for getting the 108 // caller's pc value on two UnwindPlans -- returns LazyBoolYes if they have 109 // the same unwind rule for the pc, LazyBoolNo if they do not have the same 110 // unwind rule for the pc, and LazyBoolCalculate if it was unable to 111 // determine this for some reason. 112 lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation( 113 Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b); 114 115 UnwindTable &m_unwind_table; 116 AddressRange m_range; 117 118 std::recursive_mutex m_mutex; 119 120 lldb::UnwindPlanSP m_unwind_plan_assembly_sp; 121 lldb::UnwindPlanSP m_unwind_plan_object_file_sp; 122 lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; 123 lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp; 124 125 // augmented by assembly inspection so it's valid everywhere 126 lldb::UnwindPlanSP m_unwind_plan_object_file_augmented_sp; 127 lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp; 128 lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp; 129 130 std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind; 131 lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp; 132 lldb::UnwindPlanSP m_unwind_plan_symbol_file_sp; 133 lldb::UnwindPlanSP m_unwind_plan_fast_sp; 134 lldb::UnwindPlanSP m_unwind_plan_arch_default_sp; 135 lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp; 136 137 // Fetching the UnwindPlans can be expensive - if we've already attempted to 138 // get one & failed, don't try again. 139 bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1, 140 m_tried_unwind_plan_object_file : 1, 141 m_tried_unwind_plan_debug_frame : 1, 142 m_tried_unwind_plan_object_file_augmented : 1, 143 m_tried_unwind_plan_eh_frame_augmented : 1, 144 m_tried_unwind_plan_debug_frame_augmented : 1, 145 m_tried_unwind_plan_compact_unwind : 1, 146 m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_plan_symbol_file : 1, 147 m_tried_unwind_fast : 1, m_tried_unwind_arch_default : 1, 148 m_tried_unwind_arch_default_at_func_entry : 1; 149 150 Address m_first_non_prologue_insn; 151 152 FuncUnwinders(const FuncUnwinders &) = delete; 153 const FuncUnwinders &operator=(const FuncUnwinders &) = delete; 154 155 }; // class FuncUnwinders 156 157 } // namespace lldb_private 158 159 #endif // LLDB_SYMBOL_FUNCUNWINDERS_H 160