]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Symbol/FuncUnwinders.h
MFV r337167: 9442 decrease indirect block size of spacemaps
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / Symbol / FuncUnwinders.h
1 #ifndef liblldb_FuncUnwinders_h
2 #define liblldb_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
16   // (named 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
32   // stack frame 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   // 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
41   // execute, this
42   // offset value will have already been decremented by 1 to stay within the
43   // bounds of the
44   // correct function body.
45   lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target,
46                                              int current_offset);
47
48   lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target,
49                                                 lldb_private::Thread &thread,
50                                                 int current_offset);
51
52   lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target,
53                                              lldb_private::Thread &thread);
54
55   lldb::UnwindPlanSP
56   GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread);
57
58   lldb::UnwindPlanSP
59   GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread);
60
61   Address &GetFirstNonPrologueInsn(Target &target);
62
63   const Address &GetFunctionStartAddress() const;
64
65   bool ContainsAddress(const Address &addr) const {
66     return m_range.ContainsFileAddress(addr);
67   }
68
69   // A function may have a Language Specific Data Area specified -- a block of
70   // data in
71   // the object file which is used in the processing of an exception throw /
72   // catch.
73   // If any of the UnwindPlans have the address of the LSDA region for this
74   // function,
75   // this will return it.
76   Address GetLSDAAddress(Target &target);
77
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
81   // target-pointer
82   // at this address to get the personality function address.
83   Address GetPersonalityRoutinePtrAddress(Target &target);
84
85   // The following methods to retrieve specific unwind plans should rarely be
86   // used.
87   // Instead, clients should ask for the *behavior* they are looking for, using
88   // one
89   // of the above UnwindPlan retrieval methods.
90
91   lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread,
92                                            int current_offset);
93
94   lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target, int current_offset);
95
96   lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target,
97                                                    Thread &thread,
98                                                    int current_offset);
99
100   lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target,
101                                              int current_offset);
102
103   lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target,
104                                                       Thread &thread,
105                                                       int current_offset);
106
107   lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target,
108                                                 int current_offset);
109
110   lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target, int current_offset);
111
112   lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread);
113
114   lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread);
115
116 private:
117   lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target);
118
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);
126
127   UnwindTable &m_unwind_table;
128   AddressRange m_range;
129
130   std::recursive_mutex m_mutex;
131
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;
135
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;
139
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;
145
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;
156
157   Address m_first_non_prologue_insn;
158
159   DISALLOW_COPY_AND_ASSIGN(FuncUnwinders);
160
161 }; // class FuncUnwinders
162
163 } // namespace lldb_private
164
165 #endif // liblldb_FuncUnwinders_h