LLDB  mainline
RegisterContextUnwind.h
Go to the documentation of this file.
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 
15 #include "lldb/Symbol/UnwindPlan.h"
18 #include "lldb/Target/UnwindLLDB.h"
19 #include "lldb/lldb-private.h"
20 
21 namespace lldb_private {
22 
23 class UnwindLLDB;
24 
26 public:
27  typedef std::shared_ptr<RegisterContextUnwind> SharedPtr;
28 
30  const SharedPtr &next_frame,
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 
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 {
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 
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.
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.
153 
156  const lldb_private::RegisterInfo *reg_info,
158 
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.
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 &reg_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 
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
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 
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 
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 
259  const RegisterContextUnwind &
260  operator=(const RegisterContextUnwind &) = delete;
261 };
262 
263 } // namespace lldb_private
264 
265 #endif // LLDB_TARGET_REGISTERCONTEXTUNWIND_H
lldb_private::RegisterContextUnwind::ReadPC
bool ReadPC(lldb::addr_t &start_pc)
Definition: RegisterContextUnwind.cpp:2299
lldb_private::RegisterContextUnwind::eSkipFrame
@ eSkipFrame
Definition: RegisterContextUnwind.h:81
lldb_private::RegisterContextUnwind::~RegisterContextUnwind
~RegisterContextUnwind() override=default
lldb_private::RegisterContextUnwind::eTrapHandlerFrame
@ eTrapHandlerFrame
Definition: RegisterContextUnwind.h:78
lldb_private::RegisterContextUnwind::GetRegisterCount
size_t GetRegisterCount() override
Definition: RegisterContextUnwind.cpp:1074
lldb_private::RegisterValue
Definition: RegisterValue.h:28
UnwindLLDB.h
lldb_private::RegisterContextUnwind::IsUnwindPlanValidForCurrentPC
void void bool IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp)
Definition: RegisterContextUnwind.cpp:84
lldb_private::RegisterContextUnwind::TryFallbackUnwindPlan
bool TryFallbackUnwindPlan()
If the unwind has to the caller frame has failed, try something else.
Definition: RegisterContextUnwind.cpp:1707
lldb_private::RegisterContextUnwind::UnwindLogMsg
void UnwindLogMsg(const char *fmt,...) __attribute__((format(printf
Definition: RegisterContextUnwind.cpp:2331
lldb_private::RegisterContextUnwind::SharedPtr
std::shared_ptr< RegisterContextUnwind > SharedPtr
Definition: RegisterContextUnwind.h:27
__attribute__
__attribute__((always_inline)) int uuid_is_null(uuid_t uuid)
Definition: UuidCompatibility.h:18
lldb_private::RegisterContextUnwind::InitializeNonZerothFrame
void InitializeNonZerothFrame()
Definition: RegisterContextUnwind.cpp:303
lldb_private::Process
Definition: Process.h:338
lldb_private::RegisterContextUnwind::ReadRegisterValueFromRegisterLocation
bool ReadRegisterValueFromRegisterLocation(lldb_private::UnwindLLDB::RegisterLocation regloc, const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value)
Definition: RegisterContextUnwind.cpp:1096
lldb_private::RegisterContextUnwind::m_sym_ctx_valid
bool m_sym_ctx_valid
Definition: RegisterContextUnwind.h:247
lldb_private::RegisterContextUnwind::GetRegisterSet
const lldb_private::RegisterSet * GetRegisterSet(size_t reg_set) override
Definition: RegisterContextUnwind.cpp:1086
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::RegisterContextUnwind::m_all_registers_available
bool m_all_registers_available
Definition: RegisterContextUnwind.h:222
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::RegisterContextUnwind::InitializeZerothFrame
void InitializeZerothFrame()
Definition: RegisterContextUnwind.cpp:112
lldb_private::RegisterContextUnwind::GetFullUnwindPlanForFrame
lldb::UnwindPlanSP GetFullUnwindPlanForFrame()
Definition: RegisterContextUnwind.cpp:783
lldb_private::RegisterContextUnwind::CheckIfLoopingStack
bool CheckIfLoopingStack()
Definition: RegisterContextUnwind.cpp:689
lldb_private::RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan
bool ForceSwitchToFallbackUnwindPlan()
Switch to the fallback unwind plan unconditionally without any safety checks that it is providing bet...
Definition: RegisterContextUnwind.cpp:1846
lldb_private::RegisterContextUnwind::GetCFA
bool GetCFA(lldb::addr_t &cfa)
Definition: RegisterContextUnwind.cpp:2250
RegisterNumber
A class to represent register numbers, and able to convert between different register numbering schem...
Definition: RegisterNumber.h:19
lldb_private::RegisterContextUnwind::m_frame_type
int m_frame_type
Definition: RegisterContextUnwind.h:224
lldb_private::UnwindLLDB::RegisterSearchResult
RegisterSearchResult
Definition: UnwindLLDB.h:32
lldb_private::RegisterContextUnwind::m_frame_number
uint32_t m_frame_number
Definition: RegisterContextUnwind.h:250
lldb_private::Thread
Definition: Thread.h:61
lldb_private::RegisterContextUnwind::GetReturnAddressHint
lldb::addr_t GetReturnAddressHint(int32_t plan_offset)
Definition: RegisterContextUnwind.cpp:2064
lldb_private::RegisterContextUnwind::IsTrapHandlerSymbol
bool IsTrapHandlerSymbol(lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const
Determines if a SymbolContext is a trap handler or not.
Definition: RegisterContextUnwind.cpp:1217
lldb_private::RegisterContextUnwind::IsValid
bool IsValid() const
Definition: RegisterContextUnwind.cpp:1191
lldb_private::UnwindLLDB
Definition: UnwindLLDB.h:26
lldb_private::RegisterContextUnwind::RegisterContextUnwind
RegisterContextUnwind(lldb_private::Thread &thread, const SharedPtr &next_frame, lldb_private::SymbolContext &sym_ctx, uint32_t frame_number, lldb_private::UnwindLLDB &unwind_lldb)
Definition: RegisterContextUnwind.cpp:53
lldb_private::UnwindPlan::Row::FAValue
Definition: UnwindPlan.h:198
lldb_private::UnwindLLDB::RegisterLocation
Definition: UnwindLLDB.h:41
lldb_private::RegisterContextUnwind::ConvertRegisterKindToRegisterNumber
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
Definition: RegisterContextUnwind.cpp:1090
lldb_private::RegisterContextUnwind::IsTrapHandlerFrame
bool IsTrapHandlerFrame() const
Definition: RegisterContextUnwind.cpp:1201
lldb_private::RegisterContextUnwind::m_parent_unwind
lldb_private::UnwindLLDB & m_parent_unwind
Definition: RegisterContextUnwind.h:255
lldb_private::RegisterContextUnwind::m_current_offset_backed_up_one
int m_current_offset_backed_up_one
Definition: RegisterContextUnwind.h:241
lldb_private::RegisterContextUnwind::GetStartPC
bool GetStartPC(lldb::addr_t &start_pc)
Definition: RegisterContextUnwind.cpp:2275
UnwindPlan.h
lldb_private::RegisterContextUnwind::IsFrameZero
bool IsFrameZero() const
Definition: RegisterContextUnwind.cpp:718
lldb_private::RegisterContext
Definition: RegisterContext.h:17
lldb_private::RegisterContextUnwind::GetPrevFrame
SharedPtr GetPrevFrame() const
Definition: RegisterContextUnwind.cpp:2268
lldb_private::RegisterContextUnwind::GetNextFrame
SharedPtr GetNextFrame() const
Definition: RegisterContextUnwind.cpp:2261
lldb::RegisterKind
RegisterKind
Register numbering types.
Definition: lldb-enumerations.h:228
lldb-private.h
lldb_private::RegisterContextUnwind::m_thread
lldb_private::Thread & m_thread
Definition: RegisterContextUnwind.h:210
lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan
void PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP unwind_plan)
Check if the given unwind plan indicates a signal trap handler, and update frame type and symbol cont...
Definition: RegisterContextUnwind.cpp:1893
lldb_private::RegisterContextUnwind::InvalidateAllRegisters
void InvalidateAllRegisters() override
Definition: RegisterContextUnwind.cpp:1070
lldb_private::RegisterContextUnwind::IsSkipFrame
bool IsSkipFrame() const
Definition: RegisterContextUnwind.cpp:1213
uint32_t
lldb_private::Address
Definition: Address.h:59
lldb_private::RegisterContextUnwind::m_afa
lldb::addr_t m_afa
Definition: RegisterContextUnwind.h:227
lldb_private::RegisterContextUnwind::GetRegisterSetCount
size_t GetRegisterSetCount() override
Definition: RegisterContextUnwind.cpp:1082
lldb_private::RegisterContextUnwind::m_fast_unwind_plan_sp
lldb::UnwindPlanSP m_fast_unwind_plan_sp
Definition: RegisterContextUnwind.h:218
lldb_private::RegisterContextUnwind::eDebuggerFrame
@ eDebuggerFrame
Definition: RegisterContextUnwind.h:79
lldb_private::RegisterContextUnwind::m_sym_ctx
lldb_private::SymbolContext & m_sym_ctx
Definition: RegisterContextUnwind.h:246
lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame
lldb::UnwindPlanSP GetFastUnwindPlanForFrame()
Definition: RegisterContextUnwind.cpp:739
lldb_private::RegisterContextUnwind::ReadGPRValue
bool ReadGPRValue(lldb::RegisterKind register_kind, uint32_t regnum, lldb::addr_t &value)
Definition: RegisterContextUnwind.cpp:2105
lldb_private::RegisterContextUnwind::BehavesLikeZerothFrame
bool BehavesLikeZerothFrame() const override
Indicates that this frame is currently executing code, that the PC value is not a return-pc but an ac...
Definition: RegisterContextUnwind.cpp:720
lldb_private::RegisterContextUnwind::m_behaves_like_zeroth_frame
bool m_behaves_like_zeroth_frame
Definition: RegisterContextUnwind.h:244
lldb_private::RegisterContextUnwind::m_cfa
lldb::addr_t m_cfa
Definition: RegisterContextUnwind.h:226
lldb_private::RegisterContextUnwind::WriteRegisterValueToRegisterLocation
bool WriteRegisterValueToRegisterLocation(lldb_private::UnwindLLDB::RegisterLocation regloc, const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value)
Definition: RegisterContextUnwind.cpp:1149
lldb_private::RegisterContextUnwind::WriteRegister
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override
Definition: RegisterContextUnwind.cpp:2211
SymbolContext.h
lldb_private::RegisterContextUnwind
Definition: RegisterContextUnwind.h:25
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::RegisterContextUnwind::eNotAValidFrame
@ eNotAValidFrame
Definition: RegisterContextUnwind.h:83
lldb_private::RegisterContextUnwind::UnwindLogMsgVerbose
void void UnwindLogMsgVerbose(const char *fmt,...) __attribute__((format(printf
Definition: RegisterContextUnwind.cpp:2348
lldb_private::RegisterContextUnwind::m_start_pc
lldb_private::Address m_start_pc
Definition: RegisterContextUnwind.h:228
lldb_private::RegisterContextUnwind::m_current_offset
int m_current_offset
Definition: RegisterContextUnwind.h:231
lldb_private::RegisterContextUnwind::SavedLocationForRegister
lldb_private::UnwindLLDB::RegisterSearchResult SavedLocationForRegister(uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc)
Definition: RegisterContextUnwind.cpp:1247
lldb_private::RegisterContextUnwind::ReadAllRegisterValues
bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override
Definition: RegisterContextUnwind.cpp:2237
lldb_private::RegisterContextUnwind::m_current_pc
lldb_private::Address m_current_pc
Definition: RegisterContextUnwind.h:229
lldb_private::RegisterContextUnwind::ReadRegister
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override
Definition: RegisterContextUnwind.cpp:2168
lldb_private::RegisterContextUnwind::GetRegisterInfoAtIndex
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
Definition: RegisterContextUnwind.cpp:1078
lldb_private::RegisterContextUnwind::m_fallback_unwind_plan_sp
lldb::UnwindPlanSP m_fallback_unwind_plan_sp
Definition: RegisterContextUnwind.h:220
RegisterNumber.h
lldb_private::RegisterContextUnwind::m_full_unwind_plan_sp
lldb::UnwindPlanSP m_full_unwind_plan_sp
Definition: RegisterContextUnwind.h:219
lldb_private::RegisterContextUnwind::ReadFrameAddress
bool ReadFrameAddress(lldb::RegisterKind register_kind, UnwindPlan::Row::FAValue &fa, lldb::addr_t &address)
Definition: RegisterContextUnwind.cpp:1940
lldb
Definition: SBAddress.h:15
RegisterContext.h
lldb_private::RegisterContextUnwind::WriteAllRegisterValues
bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override
Definition: RegisterContextUnwind.cpp:2243
lldb_private::RegisterContextUnwind::m_registers
std::map< uint32_t, lldb_private::UnwindLLDB::RegisterLocation > m_registers
Definition: RegisterContextUnwind.h:253
lldb_private::RegisterContextUnwind::FrameType
FrameType
Definition: RegisterContextUnwind.h:76
lldb_private::RegisterContextUnwind::eNormalFrame
@ eNormalFrame
Definition: RegisterContextUnwind.h:77