1 #ifndef liblldb_UnwindPlan_h
2 #define liblldb_UnwindPlan_h
4 #include "lldb/lldb-private.h"
5 #include "lldb/Core/AddressRange.h"
6 #include "lldb/Core/Stream.h"
7 #include "lldb/Core/ConstString.h"
12 namespace lldb_private {
14 // The UnwindPlan object specifies how to unwind out of a function - where
15 // this function saves the caller's register values before modifying them
16 // (for non-volatile aka saved registers) and how to find this frame's
17 // Canonical Frame Address (CFA).
19 // Most commonly, registers are saved on the stack, offset some bytes from
20 // the Canonical Frame Address, or CFA, which is the starting address of
21 // this function's stack frame (the CFA is same as the eh_frame's CFA,
22 // whatever that may be on a given architecture).
23 // The CFA address for the stack frame does not change during
24 // the lifetime of the function.
26 // Internally, the UnwindPlan is structured as a vector of register locations
27 // organized by code address in the function, showing which registers have been
28 // saved at that point and where they are saved.
29 // It can be thought of as the expanded table form of the DWARF CFI
30 // encoded information.
32 // Other unwind information sources will be converted into UnwindPlans before
33 // being added to a FuncUnwinders object. The unwind source may be
34 // an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based
36 // The UnwindPlan is the canonical form of this information that the unwinder
37 // code will use when walking the stack.
44 class RegisterLocation
50 unspecified, // not specified, we may be able to assume this
51 // is the same register. gcc doesn't specify all
52 // initial values so we really don't know...
53 undefined, // reg is not available, e.g. volatile reg
54 same, // reg is unchanged
55 atCFAPlusOffset, // reg = deref(CFA + offset)
56 isCFAPlusOffset, // reg = CFA + offset
57 inOtherRegister, // reg = other reg
58 atDWARFExpression, // reg = deref(eval(dwarf_expr))
59 isDWARFExpression // reg = eval(dwarf_expr)
69 operator == (const RegisterLocation& rhs) const;
72 operator != (const RegisterLocation &rhs) const
74 return !(*this == rhs);
98 return m_type == same;
102 IsUnspecified () const
104 return m_type == unspecified;
108 IsCFAPlusOffset () const
110 return m_type == isCFAPlusOffset;
114 IsAtCFAPlusOffset () const
116 return m_type == atCFAPlusOffset;
120 IsInOtherRegister () const
122 return m_type == inOtherRegister;
126 IsAtDWARFExpression () const
128 return m_type == atDWARFExpression;
132 IsDWARFExpression () const
134 return m_type == isDWARFExpression;
138 SetAtCFAPlusOffset (int32_t offset)
140 m_type = atCFAPlusOffset;
141 m_location.offset = offset;
145 SetIsCFAPlusOffset (int32_t offset)
147 m_type = isCFAPlusOffset;
148 m_location.offset = offset;
152 SetInRegister (uint32_t reg_num)
154 m_type = inOtherRegister;
155 m_location.reg_num = reg_num;
159 GetRegisterNumber () const
161 if (m_type == inOtherRegister)
162 return m_location.reg_num;
163 return LLDB_INVALID_REGNUM;
167 GetLocationType () const
175 if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset)
176 return m_location.offset;
181 GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
183 if (m_type == atDWARFExpression || m_type == isDWARFExpression)
185 *opcodes = m_location.expr.opcodes;
186 len = m_location.expr.length;
196 SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len);
199 SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len);
202 GetDWARFExpressionBytes ()
204 if (m_type == atDWARFExpression || m_type == isDWARFExpression)
205 return m_location.expr.opcodes;
210 GetDWARFExpressionLength ()
212 if (m_type == atDWARFExpression || m_type == isDWARFExpression)
213 return m_location.expr.length;
219 const UnwindPlan* unwind_plan,
220 const UnwindPlan::Row* row,
225 RestoreType m_type; // How do we locate this register?
228 // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset
230 // For m_type == inOtherRegister
231 uint32_t reg_num; // The register number
232 // For m_type == atDWARFExpression or m_type == isDWARFExpression
234 const uint8_t *opcodes;
246 unspecified, // not specified
247 isRegisterPlusOffset, // CFA = register + offset
248 isRegisterDereferenced, // CFA = [reg]
249 isDWARFExpression // CFA = eval(dwarf_expr)
259 operator == (const CFAValue& rhs) const;
262 operator != (const CFAValue &rhs) const
264 return !(*this == rhs);
270 m_type = unspecified;
274 IsUnspecified () const
276 return m_type == unspecified;
280 IsRegisterPlusOffset () const
282 return m_type == isRegisterPlusOffset;
286 SetIsRegisterPlusOffset (uint32_t reg_num, int32_t offset)
288 m_type = isRegisterPlusOffset;
289 m_value.reg.reg_num = reg_num;
290 m_value.reg.offset = offset;
294 IsRegisterDereferenced () const
296 return m_type == isRegisterDereferenced;
300 SetIsRegisterDereferenced (uint32_t reg_num)
302 m_type = isRegisterDereferenced;
303 m_value.reg.reg_num = reg_num;
307 IsDWARFExpression () const
309 return m_type == isDWARFExpression;
313 SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len)
315 m_type = isDWARFExpression;
316 m_value.expr.opcodes = opcodes;
317 m_value.expr.length = len;
321 GetRegisterNumber () const
323 if (m_type == isRegisterDereferenced || m_type == isRegisterPlusOffset)
324 return m_value.reg.reg_num;
325 return LLDB_INVALID_REGNUM;
329 GetValueType () const
337 if (m_type == isRegisterPlusOffset)
338 return m_value.reg.offset;
342 void IncOffset (int32_t delta)
344 if (m_type == isRegisterPlusOffset)
345 m_value.reg.offset += delta;
348 void SetOffset (int32_t offset)
350 if (m_type == isRegisterPlusOffset)
351 m_value.reg.offset = offset;
355 GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const
357 if (m_type == isDWARFExpression)
359 *opcodes = m_value.expr.opcodes;
360 len = m_value.expr.length;
370 GetDWARFExpressionBytes ()
372 if (m_type == isDWARFExpression)
373 return m_value.expr.opcodes;
378 GetDWARFExpressionLength ()
380 if (m_type == isDWARFExpression)
381 return m_value.expr.length;
387 const UnwindPlan* unwind_plan,
388 Thread* thread) const;
391 ValueType m_type; // How do we compute CFA value?
395 // For m_type == isRegisterPlusOffset or m_type == isRegisterDereferenced
396 uint32_t reg_num; // The register number
397 // For m_type == isRegisterPlusOffset
400 // For m_type == isDWARFExpression
402 const uint8_t *opcodes;
411 Row (const UnwindPlan::Row& rhs) = default;
414 operator == (const Row &rhs) const;
417 GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const;
420 SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location);
423 RemoveRegisterInfo (uint32_t reg_num);
432 SetOffset(lldb::addr_t offset)
438 SlideOffset(lldb::addr_t offset)
443 CFAValue& GetCFAValue()
449 SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num,
454 SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num,
459 SetRegisterLocationToUndefined (uint32_t reg_num,
461 bool can_replace_only_if_unspecified);
464 SetRegisterLocationToUnspecified (uint32_t reg_num,
468 SetRegisterLocationToRegister (uint32_t reg_num,
469 uint32_t other_reg_num,
473 SetRegisterLocationToSame (uint32_t reg_num,
480 Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, lldb::addr_t base_addr) const;
483 typedef std::map<uint32_t, RegisterLocation> collection;
484 lldb::addr_t m_offset; // Offset into the function for this row
486 CFAValue m_cfa_value;
487 collection m_register_locations;
492 typedef std::shared_ptr<Row> RowSP;
494 UnwindPlan (lldb::RegisterKind reg_kind) :
496 m_plan_valid_address_range (),
497 m_register_kind (reg_kind),
498 m_return_addr_register (LLDB_INVALID_REGNUM),
500 m_plan_is_sourced_from_compiler (eLazyBoolCalculate),
501 m_plan_is_valid_at_all_instruction_locations (eLazyBoolCalculate),
503 m_personality_func_addr ()
507 // Performs a deep copy of the plan, including all the rows (expensive).
508 UnwindPlan (const UnwindPlan &rhs) :
509 m_plan_valid_address_range (rhs.m_plan_valid_address_range),
510 m_register_kind (rhs.m_register_kind),
511 m_return_addr_register (rhs.m_return_addr_register),
512 m_source_name (rhs.m_source_name),
513 m_plan_is_sourced_from_compiler (rhs.m_plan_is_sourced_from_compiler),
514 m_plan_is_valid_at_all_instruction_locations (rhs.m_plan_is_valid_at_all_instruction_locations),
515 m_lsda_address (rhs.m_lsda_address),
516 m_personality_func_addr (rhs.m_personality_func_addr)
518 m_row_list.reserve (rhs.m_row_list.size());
519 for (const RowSP &row_sp: rhs.m_row_list)
520 m_row_list.emplace_back (new Row (*row_sp));
528 Dump (Stream& s, Thread* thread, lldb::addr_t base_addr) const;
531 AppendRow (const RowSP& row_sp);
534 InsertRow (const RowSP& row_sp);
536 // Returns a pointer to the best row for the given offset into the function's instructions.
537 // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned.
538 // In practice, the UnwindPlan for a function with no known start address will be the architectural default
539 // UnwindPlan which will only have one row.
541 GetRowForFunctionOffset (int offset) const;
544 GetRegisterKind () const
546 return m_register_kind;
550 SetRegisterKind (lldb::RegisterKind kind)
552 m_register_kind = kind;
556 SetReturnAddressRegister (uint32_t regnum)
558 m_return_addr_register = regnum;
562 GetReturnAddressRegister (void)
564 return m_return_addr_register;
568 GetInitialCFARegister () const
570 if (m_row_list.empty())
571 return LLDB_INVALID_REGNUM;
572 return m_row_list.front()->GetCFAValue().GetRegisterNumber();
575 // This UnwindPlan may not be valid at every address of the function span.
576 // For instance, a FastUnwindPlan will not be valid at the prologue setup
577 // instructions - only in the body of the function.
579 SetPlanValidAddressRange (const AddressRange& range);
582 GetAddressRange () const
584 return m_plan_valid_address_range;
588 PlanValidAtAddress (Address addr);
591 IsValidRowIndex (uint32_t idx) const;
593 const UnwindPlan::RowSP
594 GetRowAtIndex (uint32_t idx) const;
596 const UnwindPlan::RowSP
599 lldb_private::ConstString
600 GetSourceName () const;
603 SetSourceName (const char *);
605 // Was this UnwindPlan emitted by a compiler?
606 lldb_private::LazyBool
607 GetSourcedFromCompiler () const
609 return m_plan_is_sourced_from_compiler;
612 // Was this UnwindPlan emitted by a compiler?
614 SetSourcedFromCompiler (lldb_private::LazyBool from_compiler)
616 m_plan_is_sourced_from_compiler = from_compiler;
619 // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
620 // e.g. for exception handling.
621 lldb_private::LazyBool
622 GetUnwindPlanValidAtAllInstructions () const
624 return m_plan_is_valid_at_all_instruction_locations;
627 // Is this UnwindPlan valid at all instructions? If not, then it is assumed valid at call sites,
628 // e.g. for exception handling.
630 SetUnwindPlanValidAtAllInstructions (lldb_private::LazyBool valid_at_all_insn)
632 m_plan_is_valid_at_all_instruction_locations = valid_at_all_insn;
636 GetRowCount () const;
642 m_plan_valid_address_range.Clear();
643 m_register_kind = lldb::eRegisterKindDWARF;
644 m_source_name.Clear();
645 m_plan_is_sourced_from_compiler = eLazyBoolCalculate;
646 m_plan_is_valid_at_all_instruction_locations = eLazyBoolCalculate;
647 m_lsda_address.Clear();
648 m_personality_func_addr.Clear();
652 GetRegisterInfo (Thread* thread, uint32_t reg_num) const;
655 GetLSDAAddress () const
657 return m_lsda_address;
661 SetLSDAAddress (Address lsda_addr)
663 m_lsda_address = lsda_addr;
667 GetPersonalityFunctionPtr () const
669 return m_personality_func_addr;
673 SetPersonalityFunctionPtr (Address presonality_func_ptr)
675 m_personality_func_addr = presonality_func_ptr;
681 typedef std::vector<RowSP> collection;
682 collection m_row_list;
683 AddressRange m_plan_valid_address_range;
684 lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be
685 // translated to lldb native reg nums at unwind time
686 uint32_t m_return_addr_register; // The register that has the return address for the caller frame
687 // e.g. the lr on arm
688 lldb_private::ConstString m_source_name; // for logging, where this UnwindPlan originated from
689 lldb_private::LazyBool m_plan_is_sourced_from_compiler;
690 lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations;
692 Address m_lsda_address; // Where the language specific data area exists in the module - used
693 // in exception handling.
694 Address m_personality_func_addr; // The address of a pointer to the personality function - used in
695 // exception handling.
696 }; // class UnwindPlan
698 } // namespace lldb_private
700 #endif //liblldb_UnwindPlan_h