1 //===-- UnwindPlan.h --------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_UnwindPlan_h
11 #define liblldb_UnwindPlan_h
19 // Other libraries and framework includes
21 #include "lldb/lldb-private.h"
22 #include "lldb/Core/AddressRange.h"
23 #include "lldb/Core/Stream.h"
24 #include "lldb/Core/ConstString.h"
26 namespace lldb_private {
28 // The UnwindPlan object specifies how to unwind out of a function - where
29 // this function saves the caller's register values before modifying them
30 // (for non-volatile aka saved registers) and how to find this frame's
31 // Canonical Frame Address (CFA).
33 // Most commonly, registers are saved on the stack, offset some bytes from
34 // the Canonical Frame Address, or CFA, which is the starting address of
35 // this function's stack frame (the CFA is same as the eh_frame's CFA,
36 // whatever that may be on a given architecture).
37 // The CFA address for the stack frame does not change during
38 // the lifetime of the function.
40 // Internally, the UnwindPlan is structured as a vector of register locations
41 // organized by code address in the function, showing which registers have been
42 // saved at that point and where they are saved.
43 // It can be thought of as the expanded table form of the DWARF CFI
44 // encoded information.
46 // Other unwind information sources will be converted into UnwindPlans before
47 // being added to a FuncUnwinders object. The unwind source may be
48 // an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based
50 // The UnwindPlan is the canonical form of this information that the unwinder
51 // code will use when walking the stack.
57 class RegisterLocation
62 unspecified, // not specified, we may be able to assume this
63 // is the same register. gcc doesn't specify all
64 // initial values so we really don't know...
65 undefined, // reg is not available, e.g. volatile reg
66 same, // reg is unchanged
67 atCFAPlusOffset, // reg = deref(CFA + offset)
68 isCFAPlusOffset, // reg = CFA + offset
69 inOtherRegister, // reg = other reg
70 atDWARFExpression, // reg = deref(eval(dwarf_expr))
71 isDWARFExpression // reg = eval(dwarf_expr)
81 operator == (const RegisterLocation& rhs) const;
84 operator != (const RegisterLocation &rhs) const
86 return !(*this == rhs);
110 return m_type == same;
114 IsUnspecified () const
116 return m_type == unspecified;
122 return m_type == undefined;
126 IsCFAPlusOffset () const
128 return m_type == isCFAPlusOffset;
132 IsAtCFAPlusOffset () const
134 return m_type == atCFAPlusOffset;
138 IsInOtherRegister () const
140 return m_type == inOtherRegister;
144 IsAtDWARFExpression () const
146 return m_type == atDWARFExpression;
150 IsDWARFExpression () const
152 return m_type == isDWARFExpression;
156 SetAtCFAPlusOffset (int32_t offset)
158 m_type = atCFAPlusOffset;
159 m_location.offset = offset;
163 SetIsCFAPlusOffset (int32_t offset)
165 m_type = isCFAPlusOffset;
166 m_location.offset = offset;
170 SetInRegister (uint32_t reg_num)
172 m_type = inOtherRegister;
173 m_location.reg_num = reg_num;
177 GetRegisterNumber () const
179 if (m_type == inOtherRegister)
180 return m_location.reg_num;
181 return LLDB_INVALID_REGNUM;
185 GetLocationType () const
193 if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset)
194 return m_location.offset;
199 GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
201 if (m_type == atDWARFExpression || m_type == isDWARFExpression)
203 *opcodes = m_location.expr.opcodes;
204 len = m_location.expr.length;
214 SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len);
217 SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len);
220 GetDWARFExpressionBytes ()
222 if (m_type == atDWARFExpression || m_type == isDWARFExpression)
223 return m_location.expr.opcodes;
228 GetDWARFExpressionLength ()
230 if (m_type == atDWARFExpression || m_type == isDWARFExpression)
231 return m_location.expr.length;
237 const UnwindPlan* unwind_plan,
238 const UnwindPlan::Row* row,
243 RestoreType m_type; // How do we locate this register?
246 // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset
248 // For m_type == inOtherRegister
249 uint32_t reg_num; // The register number
250 // For m_type == atDWARFExpression or m_type == isDWARFExpression
252 const uint8_t *opcodes;
263 unspecified, // not specified
264 isRegisterPlusOffset, // CFA = register + offset
265 isRegisterDereferenced, // CFA = [reg]
266 isDWARFExpression // CFA = eval(dwarf_expr)
276 operator == (const CFAValue& rhs) const;
279 operator != (const CFAValue &rhs) const
281 return !(*this == rhs);
287 m_type = unspecified;
291 IsUnspecified () const
293 return m_type == unspecified;
297 IsRegisterPlusOffset () const
299 return m_type == isRegisterPlusOffset;
303 SetIsRegisterPlusOffset (uint32_t reg_num, int32_t offset)
305 m_type = isRegisterPlusOffset;
306 m_value.reg.reg_num = reg_num;
307 m_value.reg.offset = offset;
311 IsRegisterDereferenced () const
313 return m_type == isRegisterDereferenced;
317 SetIsRegisterDereferenced (uint32_t reg_num)
319 m_type = isRegisterDereferenced;
320 m_value.reg.reg_num = reg_num;
324 IsDWARFExpression () const
326 return m_type == isDWARFExpression;
330 SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len)
332 m_type = isDWARFExpression;
333 m_value.expr.opcodes = opcodes;
334 m_value.expr.length = len;
338 GetRegisterNumber () const
340 if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset)
341 return m_value.reg.reg_num;
342 return LLDB_INVALID_REGNUM;
346 GetValueType () const
354 if (m_type == isRegisterPlusOffset)
355 return m_value.reg.offset;
359 void IncOffset (int32_t delta)
361 if (m_type == isRegisterPlusOffset)
362 m_value.reg.offset += delta;
365 void SetOffset (int32_t offset)
367 if (m_type == isRegisterPlusOffset)
368 m_value.reg.offset = offset;
372 GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
374 if (m_type == isDWARFExpression)
376 *opcodes = m_value.expr.opcodes;
377 len = m_value.expr.length;
387 GetDWARFExpressionBytes ()
389 if (m_type == isDWARFExpression)
390 return m_value.expr.opcodes;
395 GetDWARFExpressionLength ()
397 if (m_type == isDWARFExpression)
398 return m_value.expr.length;
404 const UnwindPlan* unwind_plan,
405 Thread* thread) const;
408 ValueType m_type; // How do we compute CFA value?
412 // For m_type == isRegisterPlusOffset or m_type == isRegisterDereferenced
413 uint32_t reg_num; // The register number
414 // For m_type == isRegisterPlusOffset
417 // For m_type == isDWARFExpression
419 const uint8_t *opcodes;
428 Row (const UnwindPlan::Row& rhs) = default;
431 operator == (const Row &rhs) const;
434 GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const;
437 SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location);
440 RemoveRegisterInfo (uint32_t reg_num);
449 SetOffset(lldb::addr_t offset)
455 SlideOffset(lldb::addr_t offset)
460 CFAValue& GetCFAValue()
466 SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num,
471 SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num,
476 SetRegisterLocationToUndefined (uint32_t reg_num,
478 bool can_replace_only_if_unspecified);
481 SetRegisterLocationToUnspecified (uint32_t reg_num,
485 SetRegisterLocationToRegister (uint32_t reg_num,
486 uint32_t other_reg_num,
490 SetRegisterLocationToSame (uint32_t reg_num,
497 Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, lldb::addr_t base_addr) const;
500 typedef std::map<uint32_t, RegisterLocation> collection;
501 lldb::addr_t m_offset; // Offset into the function for this row
503 CFAValue m_cfa_value;
504 collection m_register_locations;
508 typedef std::shared_ptr<Row> RowSP;
510 UnwindPlan (lldb::RegisterKind reg_kind) :
512 m_plan_valid_address_range (),
513 m_register_kind (reg_kind),
514 m_return_addr_register (LLDB_INVALID_REGNUM),
516 m_plan_is_sourced_from_compiler (eLazyBoolCalculate),
517 m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate),
519 m_personality_func_addr ()
523 // Performs a deep copy of the plan, including all the rows (expensive).
524 UnwindPlan (const UnwindPlan &rhs) :
525 m_plan_valid_address_range (rhs.m_plan_valid_address_range),
526 m_register_kind (rhs.m_register_kind),
527 m_return_addr_register (rhs.m_return_addr_register),
528 m_source_name (rhs.m_source_name),
529 m_plan_is_sourced_from_compiler (rhs.m_plan_is_sourced_from_compiler),
530 m_plan_is_valid_at_all_instruction_locations (rhs.m_plan_is_valid_at_all_instruction_locations),
531 m_lsda_address (rhs.m_lsda_address),
532 m_personality_func_addr (rhs.m_personality_func_addr)
534 m_row_list.reserve (rhs.m_row_list.size());
535 for (const RowSP &row_sp: rhs.m_row_list)
536 m_row_list.emplace_back (new Row (*row_sp));
539 ~UnwindPlan() = default;
542 Dump (Stream& s, Thread* thread, lldb::addr_t base_addr) const;
545 AppendRow (const RowSP& row_sp);
548 InsertRow (const RowSP& row_sp, bool replace_existing = false);
550 // Returns a pointer to the best row for the given offset into the function's instructions.
551 // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned.
552 // In practice, the UnwindPlan for a function with no known start address will be the architectural default
553 // UnwindPlan which will only have one row.
555 GetRowForFunctionOffset (int offset) const;
558 GetRegisterKind () const
560 return m_register_kind;
564 SetRegisterKind (lldb::RegisterKind kind)
566 m_register_kind = kind;
570 SetReturnAddressRegister (uint32_t regnum)
572 m_return_addr_register = regnum;
576 GetReturnAddressRegister (void)
578 return m_return_addr_register;
582 GetInitialCFARegister () const
584 if (m_row_list.empty())
585 return LLDB_INVALID_REGNUM;
586 return m_row_list.front()->GetCFAValue().GetRegisterNumber();
589 // This UnwindPlan may not be valid at every address of the function span.
590 // For instance, a FastUnwindPlan will not be valid at the prologue setup
591 // instructions - only in the body of the function.
593 SetPlanValidAddressRange (const AddressRange& range);
596 GetAddressRange () const
598 return m_plan_valid_address_range;
602 PlanValidAtAddress (Address addr);
605 IsValidRowIndex (uint32_t idx) const;
607 const UnwindPlan::RowSP
608 GetRowAtIndex (uint32_t idx) const;
610 const UnwindPlan::RowSP
613 lldb_private::ConstString
614 GetSourceName () const;
617 SetSourceName (const char *);
619 // Was this UnwindPlan emitted by a compiler?
620 lldb_private::LazyBool
621 GetSourcedFromCompiler () const
623 return m_plan_is_sourced_from_compiler;
626 // Was this UnwindPlan emitted by a compiler?
628 SetSourcedFromCompiler (lldb_private::LazyBool from_compiler)
630 m_plan_is_sourced_from_compiler = from_compiler;
633 // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
634 // e.g. for exception handling.
635 lldb_private::LazyBool
636 GetUnwindPlanValidAtAllInstructions () const
638 return m_plan_is_valid_at_all_instruction_locations;
641 // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
642 // e.g. for exception handling.
644 SetUnwindPlanValidAtAllInstructions (lldb_private::LazyBool valid_at_all_insn)
646 m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
650 GetRowCount () const;
656 m_plan_valid_address_range.Clear();
657 m_register_kind = lldb::eRegisterKindDWARF;
658 m_source_name.Clear();
659 m_plan_is_sourced_from_compiler = eLazyBoolCalculate;
660 m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate;
661 m_lsda_address.Clear();
662 m_personality_func_addr.Clear();
666 GetRegisterInfo (Thread* thread, uint32_t reg_num) const;
669 GetLSDAAddress () const
671 return m_lsda_address;
675 SetLSDAAddress (Address lsda_addr)
677 m_lsda_address = lsda_addr;
681 GetPersonalityFunctionPtr () const
683 return m_personality_func_addr;
687 SetPersonalityFunctionPtr (Address presonality_func_ptr)
689 m_personality_func_addr = presonality_func_ptr;
693 typedef std::vector<RowSP> collection;
694 collection m_row_list;
695 AddressRange m_plan_valid_address_range;
696 lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be
697 // translated to lldb native reg nums at unwind time
698 uint32_t m_return_addr_register; // The register that has the return address for the caller frame
699 // e.g. the lr on arm
700 lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from
701 lldb_private::LazyBool m_plan_is_sourced_from_compiler;
702 lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
704 Address m_lsda_address; // Where the language specific data area exists in the module - used
705 // in exception handling.
706 Address m_personality_func_addr; // The address of a pointer to the personality function - used in
707 // exception handling.
708 }; // class UnwindPlan
710 } // namespace lldb_private
712 #endif // liblldb_UnwindPlan_h