1 | //===-- RegisterContextUnwind.h ---------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_TARGET_REGISTERCONTEXTUNWIND_H |
10 | #define LLDB_TARGET_REGISTERCONTEXTUNWIND_H |
11 | |
12 | #include <vector> |
13 | |
14 | #include "lldb/Symbol/SymbolContext.h" |
15 | #include "lldb/Symbol/UnwindPlan.h" |
16 | #include "lldb/Target/RegisterContext.h" |
17 | #include "lldb/Target/RegisterNumber.h" |
18 | #include "lldb/Target/UnwindLLDB.h" |
19 | #include "lldb/lldb-private.h" |
20 | |
21 | namespace lldb_private { |
22 | |
23 | class UnwindLLDB; |
24 | |
25 | class RegisterContextUnwind : public lldb_private::RegisterContext { |
26 | public: |
27 | typedef std::shared_ptr<RegisterContextUnwind> SharedPtr; |
28 | |
29 | RegisterContextUnwind(lldb_private::Thread &thread, |
30 | const SharedPtr &next_frame, |
31 | lldb_private::SymbolContext &sym_ctx, |
32 | uint32_t frame_number, |
33 | lldb_private::UnwindLLDB &unwind_lldb); |
34 | |
35 | ~RegisterContextUnwind() override = default; |
36 | |
37 | void InvalidateAllRegisters() override; |
38 | |
39 | size_t GetRegisterCount() override; |
40 | |
41 | const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; |
42 | |
43 | size_t GetRegisterSetCount() override; |
44 | |
45 | const lldb_private::RegisterSet *GetRegisterSet(size_t reg_set) override; |
46 | |
47 | bool ReadRegister(const lldb_private::RegisterInfo *reg_info, |
48 | lldb_private::RegisterValue &value) override; |
49 | |
50 | bool WriteRegister(const lldb_private::RegisterInfo *reg_info, |
51 | const lldb_private::RegisterValue &value) override; |
52 | |
53 | bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; |
54 | |
55 | bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; |
56 | |
57 | uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, |
58 | uint32_t num) override; |
59 | |
60 | bool IsValid() const; |
61 | |
62 | bool IsTrapHandlerFrame() const; |
63 | |
64 | bool GetCFA(lldb::addr_t &cfa); |
65 | |
66 | bool GetStartPC(lldb::addr_t &start_pc); |
67 | |
68 | bool ReadPC(lldb::addr_t &start_pc); |
69 | |
70 | // Indicates whether this frame *behaves* like frame zero -- the currently |
71 | // executing frame -- or not. This can be true in the middle of the stack |
72 | // above asynchronous trap handlers (sigtramp) for instance. |
73 | bool BehavesLikeZerothFrame() const override; |
74 | |
75 | private: |
76 | enum FrameType { |
77 | eNormalFrame, |
78 | eTrapHandlerFrame, |
79 | eDebuggerFrame, // a debugger inferior function call frame; we get caller's |
80 | // registers from debugger |
81 | eSkipFrame, // The unwind resulted in a bogus frame but may get back on |
82 | // track so we don't want to give up yet |
83 | eNotAValidFrame // this frame is invalid for some reason - most likely it is |
84 | // past the top (end) of the stack |
85 | }; |
86 | |
87 | // UnwindLLDB needs to pass around references to RegisterLocations |
88 | friend class UnwindLLDB; |
89 | |
90 | // Returns true if we have an unwind loop -- the same stack frame unwinding |
91 | // multiple times. |
92 | bool CheckIfLoopingStack(); |
93 | |
94 | // Indicates whether this frame is frame zero -- the currently |
95 | // executing frame -- or not. |
96 | bool IsFrameZero() const; |
97 | |
98 | void InitializeZerothFrame(); |
99 | |
100 | void InitializeNonZerothFrame(); |
101 | |
102 | SharedPtr GetNextFrame() const; |
103 | |
104 | SharedPtr GetPrevFrame() const; |
105 | |
106 | // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've |
107 | // got one bogus frame at frame #1. |
108 | // There is a good chance we'll get back on track if we follow the frame |
109 | // pointer chain (or whatever is appropriate |
110 | // on this ABI) so we allow one invalid frame to be in the stack. Ideally |
111 | // we'll mark this frame specially at some |
112 | // point and indicate to the user that the unwinder had a hiccup. Often when |
113 | // this happens we will miss a frame of |
114 | // the program's actual stack in the unwind and we want to flag that for the |
115 | // user somehow. |
116 | bool IsSkipFrame() const; |
117 | |
118 | /// Determines if a SymbolContext is a trap handler or not |
119 | /// |
120 | /// Given a SymbolContext, determines if this is a trap handler function |
121 | /// aka asynchronous signal handler. |
122 | /// |
123 | /// \return |
124 | /// Returns true if the SymbolContext is a trap handler. |
125 | bool IsTrapHandlerSymbol(lldb_private::Process *process, |
126 | const lldb_private::SymbolContext &m_sym_ctx) const; |
127 | |
128 | /// Check if the given unwind plan indicates a signal trap handler, and |
129 | /// update frame type and symbol context if so. |
130 | void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan); |
131 | |
132 | // Provide a location for where THIS function saved the CALLER's register |
133 | // value |
134 | // Or a frame "below" this one saved it, i.e. a function called by this one, |
135 | // preserved a register that this |
136 | // function didn't modify/use. |
137 | // |
138 | // The RegisterLocation type may be set to eRegisterNotAvailable -- this will |
139 | // happen for a volatile register |
140 | // being queried mid-stack. Instead of floating frame 0's contents of that |
141 | // register up the stack (which may |
142 | // or may not be the value of that reg when the function was executing), we |
143 | // won't return any value. |
144 | // |
145 | // If a non-volatile register (a "preserved" register) is requested mid-stack |
146 | // and no frames "below" the requested |
147 | // stack have saved the register anywhere, it is safe to assume that frame 0's |
148 | // register values are still the same |
149 | // as the requesting frame's. |
150 | lldb_private::UnwindLLDB::RegisterSearchResult |
151 | SavedLocationForRegister(uint32_t lldb_regnum, |
152 | lldb_private::UnwindLLDB::RegisterLocation ®loc); |
153 | |
154 | bool ReadRegisterValueFromRegisterLocation( |
155 | lldb_private::UnwindLLDB::RegisterLocation regloc, |
156 | const lldb_private::RegisterInfo *reg_info, |
157 | lldb_private::RegisterValue &value); |
158 | |
159 | bool WriteRegisterValueToRegisterLocation( |
160 | lldb_private::UnwindLLDB::RegisterLocation regloc, |
161 | const lldb_private::RegisterInfo *reg_info, |
162 | const lldb_private::RegisterValue &value); |
163 | |
164 | /// If the unwind has to the caller frame has failed, try something else |
165 | /// |
166 | /// If lldb is using an assembly language based UnwindPlan for a frame and |
167 | /// the unwind to the caller frame fails, try falling back to a generic |
168 | /// UnwindPlan (architecture default unwindplan) to see if that might work |
169 | /// better. This is mostly helping to work around problems where the |
170 | /// assembly language inspection fails on hand-written assembly code. |
171 | /// |
172 | /// \return |
173 | /// Returns true if a fallback unwindplan was found & was installed. |
174 | bool TryFallbackUnwindPlan(); |
175 | |
176 | /// Switch to the fallback unwind plan unconditionally without any safety |
177 | /// checks that it is providing better results than the normal unwind plan. |
178 | /// |
179 | /// The only time it is valid to call this method is if the full unwindplan is |
180 | /// found to be fundamentally incorrect/impossible. |
181 | /// |
182 | /// Returns true if it was able to install the fallback unwind plan. |
183 | bool ForceSwitchToFallbackUnwindPlan(); |
184 | |
185 | // Get the contents of a general purpose (address-size) register for this |
186 | // frame |
187 | // (usually retrieved from the next frame) |
188 | bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum, |
189 | lldb::addr_t &value); |
190 | |
191 | bool ReadGPRValue(const RegisterNumber ®_num, lldb::addr_t &value); |
192 | |
193 | // Get the Frame Address register for a given frame. |
194 | bool ReadFrameAddress(lldb::RegisterKind register_kind, |
195 | UnwindPlan::Row::FAValue &fa, lldb::addr_t &address); |
196 | |
197 | lldb::UnwindPlanSP GetFastUnwindPlanForFrame(); |
198 | |
199 | lldb::UnwindPlanSP GetFullUnwindPlanForFrame(); |
200 | |
201 | void UnwindLogMsg(const char *fmt, ...) __attribute__((format(printf, 2, 3))); |
202 | |
203 | void UnwindLogMsgVerbose(const char *fmt, ...) |
204 | __attribute__((format(printf, 2, 3))); |
205 | |
206 | bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp); |
207 | |
208 | lldb::addr_t GetReturnAddressHint(int32_t plan_offset); |
209 | |
210 | lldb_private::Thread &m_thread; |
211 | |
212 | /// |
213 | // The following tell us how to retrieve the CALLER's register values (ie the |
214 | // "previous" frame, aka the frame above) |
215 | // i.e. where THIS frame saved them |
216 | /// |
217 | |
218 | lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL |
219 | lldb::UnwindPlanSP m_full_unwind_plan_sp; |
220 | lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL |
221 | |
222 | bool m_all_registers_available; // Can we retrieve all regs or just |
223 | // nonvolatile regs? |
224 | int m_frame_type; // enum FrameType |
225 | |
226 | lldb::addr_t m_cfa; |
227 | lldb::addr_t m_afa; |
228 | lldb_private::Address m_start_pc; |
229 | lldb_private::Address m_current_pc; |
230 | |
231 | int m_current_offset; // how far into the function we've executed; -1 if |
232 | // unknown |
233 | // 0 if no instructions have been executed yet. |
234 | |
235 | // 0 if no instructions have been executed yet. |
236 | // On architectures where the return address on the stack points |
237 | // to the instruction after the CALL, this value will have 1 |
238 | // subtracted from it. Else a function that ends in a CALL will |
239 | // have an offset pointing into the next function's address range. |
240 | // m_current_pc has the actual address of the "current" pc. |
241 | int m_current_offset_backed_up_one; // how far into the function we've |
242 | // executed; -1 if unknown |
243 | |
244 | bool m_behaves_like_zeroth_frame; // this frame behaves like frame zero |
245 | |
246 | lldb_private::SymbolContext &m_sym_ctx; |
247 | bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to |
248 | // use m_sym_ctx |
249 | |
250 | uint32_t m_frame_number; // What stack frame this RegisterContext is |
251 | |
252 | std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> |
253 | m_registers; // where to find reg values for this frame |
254 | |
255 | lldb_private::UnwindLLDB &m_parent_unwind; // The UnwindLLDB that is creating |
256 | // this RegisterContextUnwind |
257 | |
258 | RegisterContextUnwind(const RegisterContextUnwind &) = delete; |
259 | const RegisterContextUnwind & |
260 | operator=(const RegisterContextUnwind &) = delete; |
261 | }; |
262 | |
263 | } // namespace lldb_private |
264 | |
265 | #endif // LLDB_TARGET_REGISTERCONTEXTUNWIND_H |
266 | |