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