1 //===-- UnwindLLDB.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_UNWINDLLDB_H 10 #define LLDB_TARGET_UNWINDLLDB_H 11 12 #include <vector> 13 14 #include "lldb/Symbol/FuncUnwinders.h" 15 #include "lldb/Symbol/SymbolContext.h" 16 #include "lldb/Symbol/UnwindPlan.h" 17 #include "lldb/Target/RegisterContext.h" 18 #include "lldb/Target/Unwind.h" 19 #include "lldb/Utility/ConstString.h" 20 #include "lldb/lldb-public.h" 21 22 namespace lldb_private { 23 24 class RegisterContextUnwind; 25 26 class UnwindLLDB : public lldb_private::Unwind { 27 public: 28 UnwindLLDB(lldb_private::Thread &thread); 29 30 ~UnwindLLDB() override = default; 31 32 enum RegisterSearchResult { 33 eRegisterFound = 0, 34 eRegisterNotFound, 35 eRegisterIsVolatile 36 }; 37 38 protected: 39 friend class lldb_private::RegisterContextUnwind; 40 41 /// An UnwindPlan::Row::AbstractRegisterLocation, combined with the register 42 /// context and memory for a specific stop point, is used to create a 43 /// ConcreteRegisterLocation. 44 struct ConcreteRegisterLocation { 45 enum RegisterLocationTypes { 46 eRegisterNotSaved = 0, // register was not preserved by callee. If 47 // volatile reg, is unavailable 48 eRegisterSavedAtMemoryLocation, // register is saved at a specific word of 49 // target mem (target_memory_location) 50 eRegisterInRegister, // register is available in a (possible other) 51 // register (register_number) 52 eRegisterSavedAtHostMemoryLocation, // register is saved at a word in 53 // lldb's address space 54 eRegisterValueInferred, // register val was computed (and is in 55 // inferred_value) 56 eRegisterInLiveRegisterContext // register value is in a live (stack frame 57 // #0) register 58 }; 59 int type; 60 union { 61 lldb::addr_t target_memory_location; 62 uint32_t 63 register_number; // in eRegisterKindLLDB register numbering system 64 void *host_memory_location; 65 uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == 66 // cfa + offset 67 } location; 68 }; 69 70 void DoClear() override { 71 m_frames.clear(); 72 m_candidate_frame.reset(); 73 m_unwind_complete = false; 74 } 75 76 uint32_t DoGetFrameCount() override; 77 78 bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, 79 lldb::addr_t &start_pc, 80 bool &behaves_like_zeroth_frame) override; 81 82 lldb::RegisterContextSP 83 DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; 84 85 typedef std::shared_ptr<RegisterContextUnwind> RegisterContextLLDBSP; 86 87 // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame 88 // 1's RegisterContextUnwind) 89 // The RegisterContext for frame_num must already exist or this returns an 90 // empty shared pointer. 91 RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num); 92 93 // Iterate over the RegisterContextUnwind's in our m_frames vector, look for 94 // the first one that has a saved location for this reg. 95 bool SearchForSavedLocationForRegister( 96 uint32_t lldb_regnum, 97 lldb_private::UnwindLLDB::ConcreteRegisterLocation ®loc, 98 uint32_t starting_frame_num, bool pc_register); 99 100 /// Provide the list of user-specified trap handler functions 101 /// 102 /// The Platform is one source of trap handler function names; that 103 /// may be augmented via a setting. The setting needs to be converted 104 /// into an array of ConstStrings before it can be used - we only want 105 /// to do that once per thread so it's here in the UnwindLLDB object. 106 /// 107 /// \return 108 /// Vector of ConstStrings of trap handler function names. May be 109 /// empty. 110 const std::vector<ConstString> &GetUserSpecifiedTrapHandlerFunctionNames() { 111 return m_user_supplied_trap_handler_functions; 112 } 113 114 private: 115 struct Cursor { 116 lldb::addr_t start_pc = 117 LLDB_INVALID_ADDRESS; // The start address of the function/symbol for 118 // this frame - current pc if unknown 119 lldb::addr_t cfa = LLDB_INVALID_ADDRESS; // The canonical frame address for 120 // this stack frame 121 lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & 122 // provide to the StackFrame creation 123 RegisterContextLLDBSP 124 reg_ctx_lldb_sp; // These are all RegisterContextUnwind's 125 126 Cursor() = default; 127 128 private: 129 Cursor(const Cursor &) = delete; 130 const Cursor &operator=(const Cursor &) = delete; 131 }; 132 133 typedef std::shared_ptr<Cursor> CursorSP; 134 std::vector<CursorSP> m_frames; 135 CursorSP m_candidate_frame; 136 bool m_unwind_complete; // If this is true, we've enumerated all the frames in 137 // the stack, and m_frames.size() is the 138 // number of frames, etc. Otherwise we've only gone as far as directly asked, 139 // and m_frames.size() 140 // is how far we've currently gone. 141 142 std::vector<ConstString> m_user_supplied_trap_handler_functions; 143 144 // Check if Full UnwindPlan of First frame is valid or not. 145 // If not then try Fallback UnwindPlan of the frame. If Fallback 146 // UnwindPlan succeeds then update the Full UnwindPlan with the 147 // Fallback UnwindPlan. 148 void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi); 149 150 CursorSP GetOneMoreFrame(ABI *abi); 151 152 bool AddOneMoreFrame(ABI *abi); 153 154 bool AddFirstFrame(); 155 156 // For UnwindLLDB only 157 UnwindLLDB(const UnwindLLDB &) = delete; 158 const UnwindLLDB &operator=(const UnwindLLDB &) = delete; 159 }; 160 161 } // namespace lldb_private 162 163 #endif // LLDB_TARGET_UNWINDLLDB_H 164