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
9namespace lldb_private {
10
11class UnwindTable;
12
13class FuncUnwinders {
14public:
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
56 bool ContainsAddress(const Address &addr) const {
57 return m_range.ContainsFileAddress(so_addr: 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
104private:
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

source code of lldb/include/lldb/Symbol/FuncUnwinders.h