1 #ifndef liblldb_FuncUnwinders_h
2 #define liblldb_FuncUnwinders_h
4 #include "lldb/Core/AddressRange.h"
5 #include "lldb/lldb-private-enumerations.h"
9 namespace lldb_private {
15 // FuncUnwinders objects are used to track UnwindPlans for a function
16 // (named or not - really just an address range)
18 // We'll record four different UnwindPlans for each address range:
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.
30 // Additionally, FuncUnwinds object can be asked where the prologue
31 // instructions are finished for migrating breakpoints past the
32 // stack frame setup instructions when we don't have line table information.
34 FuncUnwinders(lldb_private::UnwindTable &unwind_table, AddressRange range);
38 // current_offset is the byte offset into the function.
39 // 0 means no instructions have executed yet. -1 means the offset is unknown.
40 // On architectures where the pc points to the next instruction that will
42 // offset value will have already been decremented by 1 to stay within the
44 // correct function body.
45 lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target,
48 lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
49 lldb_private::Thread &thread,
52 lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
53 lldb_private::Thread &thread);
56 GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread);
59 GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread);
61 Address &GetFirstNonPrologueInsn(Target &target);
63 const Address &GetFunctionStartAddress() const;
65 bool ContainsAddress(const Address &addr) const {
66 return m_range.ContainsFileAddress(addr);
69 // A function may have a Language Specific Data Area specified -- a block of
71 // the object file which is used in the processing of an exception throw /
73 // If any of the UnwindPlans have the address of the LSDA region for this
75 // this will return it.
76 Address GetLSDAAddress(Target &target);
78 // A function may have a Personality Routine associated with it -- used in the
79 // processing of throwing an exception. If any of the UnwindPlans have the
80 // address of the personality routine, this will return it. Read the
82 // at this address to get the personality function address.
83 Address GetPersonalityRoutinePtrAddress(Target &target);
85 // The following methods to retrieve specific unwind plans should rarely be
87 // Instead, clients should ask for the *behavior* they are looking for, using
89 // of the above UnwindPlan retrieval methods.
91 lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread,
94 lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target, int current_offset);
96 lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
100 lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target,
103 lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
107 lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target,
110 lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target, int current_offset);
112 lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);
114 lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
117 lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target);
119 // Do a simplistic comparison for the register restore rule for getting
120 // the caller's pc value on two UnwindPlans -- returns LazyBoolYes if
121 // they have the same unwind rule for the pc, LazyBoolNo if they do not
122 // have the same unwind rule for the pc, and LazyBoolCalculate if it was
123 // unable to determine this for some reason.
124 lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation(
125 Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b);
127 UnwindTable &m_unwind_table;
128 AddressRange m_range;
130 std::recursive_mutex m_mutex;
132 lldb::UnwindPlanSP m_unwind_plan_assembly_sp;
133 lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp;
134 lldb::UnwindPlanSP m_unwind_plan_debug_frame_sp;
136 // augmented by assembly inspection so it's valid everywhere
137 lldb::UnwindPlanSP m_unwind_plan_eh_frame_augmented_sp;
138 lldb::UnwindPlanSP m_unwind_plan_debug_frame_augmented_sp;
140 std::vector<lldb::UnwindPlanSP> m_unwind_plan_compact_unwind;
141 lldb::UnwindPlanSP m_unwind_plan_arm_unwind_sp;
142 lldb::UnwindPlanSP m_unwind_plan_fast_sp;
143 lldb::UnwindPlanSP m_unwind_plan_arch_default_sp;
144 lldb::UnwindPlanSP m_unwind_plan_arch_default_at_func_entry_sp;
146 // Fetching the UnwindPlans can be expensive - if we've already attempted
147 // to get one & failed, don't try again.
148 bool m_tried_unwind_plan_assembly : 1, m_tried_unwind_plan_eh_frame : 1,
149 m_tried_unwind_plan_debug_frame : 1,
150 m_tried_unwind_plan_eh_frame_augmented : 1,
151 m_tried_unwind_plan_debug_frame_augmented : 1,
152 m_tried_unwind_plan_compact_unwind : 1,
153 m_tried_unwind_plan_arm_unwind : 1, m_tried_unwind_fast : 1,
154 m_tried_unwind_arch_default : 1,
155 m_tried_unwind_arch_default_at_func_entry : 1;
157 Address m_first_non_prologue_insn;
159 DISALLOW_COPY_AND_ASSIGN(FuncUnwinders);
161 }; // class FuncUnwinders
163 } // namespace lldb_private
165 #endif // liblldb_FuncUnwinders_h