1 //===-- Unwind.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_UNWIND_H
10 #define LLDB_TARGET_UNWIND_H
11 
12 #include <mutex>
13 
14 #include "lldb/lldb-private.h"
15 
16 namespace lldb_private {
17 
18 class Unwind {
19 protected:
20   // Classes that inherit from Unwind can see and modify these
21   Unwind(Thread &thread) : m_thread(thread) {}
22 
23 public:
24   virtual ~Unwind() = default;
25 
26   void Clear() {
27     std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
28     DoClear();
29   }
30 
31   uint32_t GetFrameCount() {
32     std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
33     return DoGetFrameCount();
34   }
35 
36   uint32_t GetFramesUpTo(uint32_t end_idx) {
37     lldb::addr_t cfa;
38     lldb::addr_t pc;
39     uint32_t idx;
40     bool behaves_like_zeroth_frame = (end_idx == 0);
41 
42     for (idx = 0; idx < end_idx; idx++) {
43       if (!DoGetFrameInfoAtIndex(idx, cfa, pc, behaves_like_zeroth_frame)) {
44         break;
45       }
46     }
47     return idx;
48   }
49 
50   bool GetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
51                            lldb::addr_t &pc, bool &behaves_like_zeroth_frame) {
52     std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
53     return DoGetFrameInfoAtIndex(frame_idx, cfa, pc, behaves_like_zeroth_frame);
54   }
55 
56   lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) {
57     std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex);
58     return DoCreateRegisterContextForFrame(frame);
59   }
60 
61   Thread &GetThread() { return m_thread; }
62 
63 protected:
64   // Classes that inherit from Unwind can see and modify these
65   virtual void DoClear() = 0;
66 
67   virtual uint32_t DoGetFrameCount() = 0;
68 
69   virtual bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
70                                      lldb::addr_t &pc,
71                                      bool &behaves_like_zeroth_frame) = 0;
72 
73   virtual lldb::RegisterContextSP
74   DoCreateRegisterContextForFrame(StackFrame *frame) = 0;
75 
76   Thread &m_thread;
77   std::recursive_mutex m_unwind_mutex;
78 
79 private:
80   Unwind(const Unwind &) = delete;
81   const Unwind &operator=(const Unwind &) = delete;
82 };
83 
84 } // namespace lldb_private
85 
86 #endif // LLDB_TARGET_UNWIND_H
87