LLDB mainline
UnwindPlan.h
Go to the documentation of this file.
1//===-- UnwindPlan.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_SYMBOL_UNWINDPLAN_H
10#define LLDB_SYMBOL_UNWINDPLAN_H
11
12#include <map>
13#include <memory>
14#include <vector>
15
18#include "lldb/Utility/Stream.h"
19#include "lldb/lldb-private.h"
20
21namespace lldb_private {
22
23// The UnwindPlan object specifies how to unwind out of a function - where this
24// function saves the caller's register values before modifying them (for non-
25// volatile aka saved registers) and how to find this frame's Canonical Frame
26// Address (CFA) or Aligned Frame Address (AFA).
27
28// CFA is a DWARF's Canonical Frame Address.
29// Most commonly, registers are saved on the stack, offset some bytes from the
30// Canonical Frame Address, or CFA, which is the starting address of this
31// function's stack frame (the CFA is same as the eh_frame's CFA, whatever that
32// may be on a given architecture). The CFA address for the stack frame does
33// not change during the lifetime of the function.
34
35// AFA is an artificially introduced Aligned Frame Address.
36// It is used only for stack frames with realignment (e.g. when some of the
37// locals has an alignment requirement higher than the stack alignment right
38// after the function call). It is used to access register values saved on the
39// stack after the realignment (and so they are inaccessible through the CFA).
40// AFA usually equals the stack pointer value right after the realignment.
41
42// Internally, the UnwindPlan is structured as a vector of register locations
43// organized by code address in the function, showing which registers have been
44// saved at that point and where they are saved. It can be thought of as the
45// expanded table form of the DWARF CFI encoded information.
46
47// Other unwind information sources will be converted into UnwindPlans before
48// being added to a FuncUnwinders object. The unwind source may be an eh_frame
49// FDE, a DWARF debug_frame FDE, or assembly language based prologue analysis.
50// The UnwindPlan is the canonical form of this information that the unwinder
51// code will use when walking the stack.
52
54public:
55 class Row {
56 public:
58 public:
60 unspecified, // not specified, we may be able to assume this
61 // is the same register. gcc doesn't specify all
62 // initial values so we really don't know...
63 undefined, // reg is not available, e.g. volatile reg
64 same, // reg is unchanged
65 atCFAPlusOffset, // reg = deref(CFA + offset)
66 isCFAPlusOffset, // reg = CFA + offset
67 atAFAPlusOffset, // reg = deref(AFA + offset)
68 isAFAPlusOffset, // reg = AFA + offset
69 inOtherRegister, // reg = other reg
70 atDWARFExpression, // reg = deref(eval(dwarf_expr))
71 isDWARFExpression, // reg = eval(dwarf_expr)
72 isConstant // reg = constant
73 };
74
76
77 bool operator==(const AbstractRegisterLocation &rhs) const;
78
79 bool operator!=(const AbstractRegisterLocation &rhs) const {
80 return !(*this == rhs);
81 }
82
84
86
87 void SetSame() { m_type = same; }
88
89 bool IsSame() const { return m_type == same; }
90
91 bool IsUnspecified() const { return m_type == unspecified; }
92
93 bool IsUndefined() const { return m_type == undefined; }
94
95 bool IsCFAPlusOffset() const { return m_type == isCFAPlusOffset; }
96
97 bool IsAtCFAPlusOffset() const { return m_type == atCFAPlusOffset; }
98
99 bool IsAFAPlusOffset() const { return m_type == isAFAPlusOffset; }
100
101 bool IsAtAFAPlusOffset() const { return m_type == atAFAPlusOffset; }
102
103 bool IsInOtherRegister() const { return m_type == inOtherRegister; }
104
105 bool IsAtDWARFExpression() const { return m_type == atDWARFExpression; }
106
107 bool IsDWARFExpression() const { return m_type == isDWARFExpression; }
108
109 bool IsConstant() const { return m_type == isConstant; }
110
111 void SetIsConstant(uint64_t value) {
113 m_location.constant_value = value;
114 }
115
116 uint64_t GetConstant() const { return m_location.constant_value; }
117
120 m_location.offset = offset;
121 }
122
125 m_location.offset = offset;
126 }
127
130 m_location.offset = offset;
131 }
132
135 m_location.offset = offset;
136 }
137
138 void SetInRegister(uint32_t reg_num) {
140 m_location.reg_num = reg_num;
141 }
142
143 uint32_t GetRegisterNumber() const {
144 if (m_type == inOtherRegister)
145 return m_location.reg_num;
146 return LLDB_INVALID_REGNUM;
147 }
148
150
151 int32_t GetOffset() const {
152 switch(m_type)
153 {
154 case atCFAPlusOffset:
155 case isCFAPlusOffset:
156 case atAFAPlusOffset:
157 case isAFAPlusOffset:
158 return m_location.offset;
159 default:
160 return 0;
161 }
162 }
163
164 void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const {
166 *opcodes = m_location.expr.opcodes;
167 len = m_location.expr.length;
168 } else {
169 *opcodes = nullptr;
170 len = 0;
171 }
172 }
173
174 void SetAtDWARFExpression(const uint8_t *opcodes, uint32_t len);
175
176 void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len);
177
178 const uint8_t *GetDWARFExpressionBytes() {
180 return m_location.expr.opcodes;
181 return nullptr;
182 }
183
186 return m_location.expr.length;
187 return 0;
188 }
189
190 void Dump(Stream &s, const UnwindPlan *unwind_plan,
191 const UnwindPlan::Row *row, Thread *thread, bool verbose) const;
192
193 private:
194 RestoreType m_type = unspecified; // How do we locate this register?
195 union {
196 // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset
197 int32_t offset;
198 // For m_type == inOtherRegister
199 uint32_t reg_num; // The register number
200 // For m_type == atDWARFExpression or m_type == isDWARFExpression
201 struct {
202 const uint8_t *opcodes;
203 uint16_t length;
205 // For m_type == isConstant
208 };
209
210 class FAValue {
211 public:
213 unspecified, // not specified
214 isRegisterPlusOffset, // FA = register + offset
216 isDWARFExpression, // FA = eval(dwarf_expr)
217 isRaSearch, // FA = SP + offset + ???
218 isConstant, // FA = constant
219 };
220
222
223 bool operator==(const FAValue &rhs) const;
224
225 bool operator!=(const FAValue &rhs) const { return !(*this == rhs); }
226
228
229 bool IsUnspecified() const { return m_type == unspecified; }
230
231 void SetRaSearch(int32_t offset) {
233 m_value.ra_search_offset = offset;
234 }
235
236 bool IsRegisterPlusOffset() const {
238 }
239
240 void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset) {
242 m_value.reg.reg_num = reg_num;
243 m_value.reg.offset = offset;
244 }
245
248 }
249
252 m_value.reg.reg_num = reg_num;
253 }
254
255 bool IsDWARFExpression() const { return m_type == isDWARFExpression; }
256
257 void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len) {
259 m_value.expr.opcodes = opcodes;
260 m_value.expr.length = len;
261 }
262
263 bool IsConstant() const { return m_type == isConstant; }
264
265 void SetIsConstant(uint64_t constant) {
267 m_value.constant = constant;
268 }
269
270 uint64_t GetConstant() const { return m_value.constant; }
271
272 uint32_t GetRegisterNumber() const {
274 return m_value.reg.reg_num;
275 return LLDB_INVALID_REGNUM;
276 }
277
278 ValueType GetValueType() const { return m_type; }
279
280 int32_t GetOffset() const {
281 switch (m_type) {
283 return m_value.reg.offset;
284 case isRaSearch:
285 return m_value.ra_search_offset;
286 default:
287 return 0;
288 }
289 }
290
291 void IncOffset(int32_t delta) {
293 m_value.reg.offset += delta;
294 }
295
296 void SetOffset(int32_t offset) {
298 m_value.reg.offset = offset;
299 }
300
301 void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const {
302 if (m_type == isDWARFExpression) {
303 *opcodes = m_value.expr.opcodes;
304 len = m_value.expr.length;
305 } else {
306 *opcodes = nullptr;
307 len = 0;
308 }
309 }
310
311 const uint8_t *GetDWARFExpressionBytes() {
313 return m_value.expr.opcodes;
314 return nullptr;
315 }
316
319 return m_value.expr.length;
320 return 0;
321 }
322
323 void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const;
324
325 private:
326 ValueType m_type = unspecified; // How do we compute CFA value?
327 union {
328 struct {
329 // For m_type == isRegisterPlusOffset or m_type ==
330 // isRegisterDereferenced
331 uint32_t reg_num; // The register number
332 // For m_type == isRegisterPlusOffset
333 int32_t offset;
335 // For m_type == isDWARFExpression
336 struct {
337 const uint8_t *opcodes;
338 uint16_t length;
340 // For m_type == isRaSearch
342 // For m_type = isConstant
343 uint64_t constant;
345 }; // class FAValue
346
347 Row();
348
349 bool operator==(const Row &rhs) const;
350
351 bool GetRegisterInfo(uint32_t reg_num,
352 AbstractRegisterLocation &register_location) const;
353
354 void SetRegisterInfo(uint32_t reg_num,
355 const AbstractRegisterLocation register_location);
356
357 void RemoveRegisterInfo(uint32_t reg_num);
358
359 lldb::addr_t GetOffset() const { return m_offset; }
360
361 void SetOffset(lldb::addr_t offset) { m_offset = offset; }
362
363 void SlideOffset(lldb::addr_t offset) { m_offset += offset; }
364
366
368
369 bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset,
370 bool can_replace);
371
372 bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset,
373 bool can_replace);
374
375 bool SetRegisterLocationToUndefined(uint32_t reg_num, bool can_replace,
376 bool can_replace_only_if_unspecified);
377
378 bool SetRegisterLocationToUnspecified(uint32_t reg_num, bool can_replace);
379
380 bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num,
381 bool can_replace);
382
383 bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace);
384
385 /// This method does not make a copy of the \a opcodes memory, it is
386 /// assumed to have the same lifetime as the Module this UnwindPlan will
387 /// be registered in.
388 bool SetRegisterLocationToIsDWARFExpression(uint32_t reg_num,
389 const uint8_t *opcodes,
390 uint32_t len, bool can_replace);
391
392 bool SetRegisterLocationToIsConstant(uint32_t reg_num, uint64_t constant,
393 bool can_replace);
394
395 // When this UnspecifiedRegistersAreUndefined mode is
396 // set, any register that is not specified by this Row will
397 // be described as Undefined.
398 // This will prevent the unwinder from iterating down the
399 // stack looking for a spill location, or a live register value
400 // at frame 0.
401 // It would be used for an UnwindPlan row where we can't track
402 // spilled registers -- for instance a jitted stack frame where
403 // we have no unwind information or start address -- and registers
404 // MAY have been spilled and overwritten, so providing the
405 // spilled/live value from a newer frame may show an incorrect value.
406 void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef) {
408 }
409
412 }
413
414 void Clear();
415
416 void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread,
417 lldb::addr_t base_addr) const;
418
419 protected:
420 typedef std::map<uint32_t, AbstractRegisterLocation> collection;
421 lldb::addr_t m_offset = 0; // Offset into the function for this row
422
427 }; // class Row
428
429 typedef std::shared_ptr<Row> RowSP;
430
436
437 // Performs a deep copy of the plan, including all the rows (expensive).
449 m_row_list.reserve(rhs.m_row_list.size());
450 for (const RowSP &row_sp : rhs.m_row_list)
451 m_row_list.emplace_back(new Row(*row_sp));
452 }
453
454 ~UnwindPlan() = default;
455
456 void Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const;
457
458 void AppendRow(const RowSP &row_sp);
459
460 void InsertRow(const RowSP &row_sp, bool replace_existing = false);
461
462 // Returns a pointer to the best row for the given offset into the function's
463 // instructions. If offset is -1 it indicates that the function start is
464 // unknown - the final row in the UnwindPlan is returned. In practice, the
465 // UnwindPlan for a function with no known start address will be the
466 // architectural default UnwindPlan which will only have one row.
468
470
472
473 void SetReturnAddressRegister(uint32_t regnum) {
474 m_return_addr_register = regnum;
475 }
476
478
479 uint32_t GetInitialCFARegister() const {
480 if (m_row_list.empty())
481 return LLDB_INVALID_REGNUM;
482 return m_row_list.front()->GetCFAValue().GetRegisterNumber();
483 }
484
485 // This UnwindPlan may not be valid at every address of the function span.
486 // For instance, a FastUnwindPlan will not be valid at the prologue setup
487 // instructions - only in the body of the function.
488 void SetPlanValidAddressRange(const AddressRange &range);
489
492 }
493
494 bool PlanValidAtAddress(Address addr);
495
496 bool IsValidRowIndex(uint32_t idx) const;
497
498 const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const;
499
500 const UnwindPlan::RowSP GetLastRow() const;
501
503
504 void SetSourceName(const char *);
505
506 // Was this UnwindPlan emitted by a compiler?
509 }
510
511 // Was this UnwindPlan emitted by a compiler?
513 m_plan_is_sourced_from_compiler = from_compiler;
514 }
515
516 // Is this UnwindPlan valid at all instructions? If not, then it is assumed
517 // valid at call sites, e.g. for exception handling.
520 }
521
522 // Is this UnwindPlan valid at all instructions? If not, then it is assumed
523 // valid at call sites, e.g. for exception handling.
525 lldb_private::LazyBool valid_at_all_insn) {
527 }
528
529 // Is this UnwindPlan for a signal trap frame? If so, then its saved pc
530 // may have been set manually by the signal dispatch code and therefore
531 // not follow a call to the child frame.
534 }
535
537 m_plan_is_for_signal_trap = is_for_signal_trap;
538 }
539
540 int GetRowCount() const;
541
542 void Clear() {
543 m_row_list.clear();
552 }
553
554 const RegisterInfo *GetRegisterInfo(Thread *thread, uint32_t reg_num) const;
555
557
558 void SetLSDAAddress(Address lsda_addr) { m_lsda_address = lsda_addr; }
559
561
562 void SetPersonalityFunctionPtr(Address presonality_func_ptr) {
563 m_personality_func_addr = presonality_func_ptr;
564 }
565
566private:
567 typedef std::vector<RowSP> collection;
570 lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers
571 // are in terms of - will need to be
572 // translated to lldb native reg nums at unwind time
573 uint32_t m_return_addr_register; // The register that has the return address
574 // for the caller frame
575 // e.g. the lr on arm
577 m_source_name; // for logging, where this UnwindPlan originated from
581
582 Address m_lsda_address; // Where the language specific data area exists in the
583 // module - used
584 // in exception handling.
585 Address m_personality_func_addr; // The address of a pointer to the
586 // personality function - used in
587 // exception handling.
588}; // class UnwindPlan
589
590} // namespace lldb_private
591
592#endif // LLDB_SYMBOL_UNWINDPLAN_H
A section + offset based address range class.
Definition: AddressRange.h:25
void Clear()
Clear the object's state.
A section + offset based address class.
Definition: Address.h:62
void Clear()
Clear the object's state.
Definition: Address.h:181
A uniqued constant string class.
Definition: ConstString.h:40
void Clear()
Clear this object's state.
Definition: ConstString.h:232
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
struct lldb_private::UnwindPlan::Row::AbstractRegisterLocation::@24::@25 expr
void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const
Definition: UnwindPlan.h:164
bool operator!=(const AbstractRegisterLocation &rhs) const
Definition: UnwindPlan.h:79
void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len)
Definition: UnwindPlan.cpp:67
void Dump(Stream &s, const UnwindPlan *unwind_plan, const UnwindPlan::Row *row, Thread *thread, bool verbose) const
Definition: UnwindPlan.cpp:95
union lldb_private::UnwindPlan::Row::AbstractRegisterLocation::@24 m_location
bool operator==(const AbstractRegisterLocation &rhs) const
Definition: UnwindPlan.cpp:25
void SetAtDWARFExpression(const uint8_t *opcodes, uint32_t len)
Definition: UnwindPlan.cpp:58
void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len)
Definition: UnwindPlan.h:257
void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const
Definition: UnwindPlan.cpp:197
const uint8_t * GetDWARFExpressionBytes()
Definition: UnwindPlan.h:311
union lldb_private::UnwindPlan::Row::FAValue::@26 m_value
bool operator==(const FAValue &rhs) const
Definition: UnwindPlan.cpp:172
struct lldb_private::UnwindPlan::Row::FAValue::@26::@27 reg
void SetIsRegisterDereferenced(uint32_t reg_num)
Definition: UnwindPlan.h:250
struct lldb_private::UnwindPlan::Row::FAValue::@26::@28 expr
void SetIsConstant(uint64_t constant)
Definition: UnwindPlan.h:265
bool operator!=(const FAValue &rhs) const
Definition: UnwindPlan.h:225
void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const
Definition: UnwindPlan.h:301
void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
Definition: UnwindPlan.h:240
bool SetRegisterLocationToIsConstant(uint32_t reg_num, uint64_t constant, bool can_replace)
Definition: UnwindPlan.cpp:372
bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
Definition: UnwindPlan.cpp:298
bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace)
Definition: UnwindPlan.cpp:350
bool SetRegisterLocationToIsDWARFExpression(uint32_t reg_num, const uint8_t *opcodes, uint32_t len, bool can_replace)
This method does not make a copy of the opcodes memory, it is assumed to have the same lifetime as th...
Definition: UnwindPlan.cpp:361
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
Definition: UnwindPlan.cpp:286
bool GetRegisterInfo(uint32_t reg_num, AbstractRegisterLocation &register_location) const
Definition: UnwindPlan.cpp:258
std::map< uint32_t, AbstractRegisterLocation > collection
Definition: UnwindPlan.h:420
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
Definition: UnwindPlan.cpp:338
void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, lldb::addr_t base_addr) const
Definition: UnwindPlan.cpp:232
bool SetRegisterLocationToUnspecified(uint32_t reg_num, bool can_replace)
Definition: UnwindPlan.cpp:327
void RemoveRegisterInfo(uint32_t reg_num)
Definition: UnwindPlan.cpp:273
lldb::addr_t GetOffset() const
Definition: UnwindPlan.h:359
bool operator==(const Row &rhs) const
Definition: UnwindPlan.cpp:384
bool SetRegisterLocationToUndefined(uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
Definition: UnwindPlan.cpp:310
void SlideOffset(lldb::addr_t offset)
Definition: UnwindPlan.h:363
void SetOffset(lldb::addr_t offset)
Definition: UnwindPlan.h:361
void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef)
Definition: UnwindPlan.h:406
void SetRegisterInfo(uint32_t reg_num, const AbstractRegisterLocation register_location)
Definition: UnwindPlan.cpp:280
lldb_private::LazyBool GetUnwindPlanValidAtAllInstructions() const
Definition: UnwindPlan.h:518
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:536
void InsertRow(const RowSP &row_sp, bool replace_existing=false)
Definition: UnwindPlan.cpp:400
const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const
Definition: UnwindPlan.cpp:437
lldb::RegisterKind m_register_kind
Definition: UnwindPlan.h:570
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:471
UnwindPlan(const UnwindPlan &rhs)
Definition: UnwindPlan.h:438
UnwindPlan(lldb::RegisterKind reg_kind)
Definition: UnwindPlan.h:431
uint32_t GetInitialCFARegister() const
Definition: UnwindPlan.h:479
const RegisterInfo * GetRegisterInfo(Thread *thread, uint32_t reg_num) const
Definition: UnwindPlan.cpp:600
Address GetPersonalityFunctionPtr() const
Definition: UnwindPlan.h:560
lldb_private::LazyBool m_plan_is_for_signal_trap
Definition: UnwindPlan.h:580
const UnwindPlan::RowSP GetLastRow() const
Definition: UnwindPlan.cpp:450
void SetPlanValidAddressRange(const AddressRange &range)
Definition: UnwindPlan.cpp:461
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:473
uint32_t GetReturnAddressRegister()
Definition: UnwindPlan.h:477
AddressRange m_plan_valid_address_range
Definition: UnwindPlan.h:569
std::vector< RowSP > collection
Definition: UnwindPlan.h:567
bool IsValidRowIndex(uint32_t idx) const
Definition: UnwindPlan.cpp:433
uint32_t m_return_addr_register
Definition: UnwindPlan.h:573
void SetPersonalityFunctionPtr(Address presonality_func_ptr)
Definition: UnwindPlan.h:562
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:392
lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations
Definition: UnwindPlan.h:579
UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const
Definition: UnwindPlan.cpp:415
lldb::RegisterKind GetRegisterKind() const
Definition: UnwindPlan.h:469
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:429
void SetLSDAAddress(Address lsda_addr)
Definition: UnwindPlan.h:558
lldb_private::ConstString m_source_name
Definition: UnwindPlan.h:577
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:512
const AddressRange & GetAddressRange() const
Definition: UnwindPlan.h:490
bool PlanValidAtAddress(Address addr)
Definition: UnwindPlan.cpp:466
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:594
Address GetLSDAAddress() const
Definition: UnwindPlan.h:556
lldb_private::LazyBool GetUnwindPlanForSignalTrap() const
Definition: UnwindPlan.h:532
void Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const
Definition: UnwindPlan.cpp:523
lldb_private::ConstString GetSourceName() const
Definition: UnwindPlan.cpp:598
lldb_private::LazyBool GetSourcedFromCompiler() const
Definition: UnwindPlan.h:507
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:524
lldb_private::LazyBool m_plan_is_sourced_from_compiler
Definition: UnwindPlan.h:578
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:87
A class that represents a running process on the host machine.
uint64_t addr_t
Definition: lldb-types.h:80
RegisterKind
Register numbering types.
@ eRegisterKindDWARF
the register numbers seen DWARF
Every register is described in detail including its name, alternate name (optional),...