/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Symbol/FuncUnwinders.h
Line | Count | Source |
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 | | |
56 | 235k | bool ContainsAddress(const Address &addr) const { |
57 | 235k | return m_range.ContainsFileAddress(addr); |
58 | 235k | } |
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 |