1 | //===-- MessageObjects.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_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H |
10 | #define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H |
11 | |
12 | #include "lldb/Host/Host.h" |
13 | #include "lldb/Utility/RegisterValue.h" |
14 | #include "lldb/Utility/StructuredData.h" |
15 | #include "lldb/lldb-types.h" |
16 | #include "llvm/ADT/DenseMap.h" |
17 | #include "llvm/ADT/SmallString.h" |
18 | #include "llvm/Support/Endian.h" |
19 | #include "llvm/Support/Error.h" |
20 | #include "llvm/Support/FormatVariadic.h" |
21 | #include <string> |
22 | |
23 | namespace llgs_tests { |
24 | class ThreadInfo; |
25 | typedef llvm::DenseMap<uint64_t, ThreadInfo> ThreadInfoMap; |
26 | typedef llvm::DenseMap<unsigned int, lldb_private::RegisterValue> RegisterMap; |
27 | |
28 | template <typename T> struct Parser { using result_type = T; }; |
29 | |
30 | class ProcessInfo : public Parser<ProcessInfo> { |
31 | public: |
32 | static llvm::Expected<ProcessInfo> create(llvm::StringRef response); |
33 | lldb::pid_t GetPid() const; |
34 | llvm::endianness GetEndian() const; |
35 | |
36 | private: |
37 | ProcessInfo() = default; |
38 | lldb::pid_t m_pid; |
39 | lldb::pid_t m_parent_pid; |
40 | uint32_t m_real_uid; |
41 | uint32_t m_real_gid; |
42 | uint32_t m_effective_uid; |
43 | uint32_t m_effective_gid; |
44 | std::string m_triple; |
45 | llvm::SmallString<16> m_ostype; |
46 | llvm::endianness m_endian; |
47 | unsigned int m_ptrsize; |
48 | }; |
49 | |
50 | class ThreadInfo { |
51 | public: |
52 | ThreadInfo() = default; |
53 | ThreadInfo(llvm::StringRef name, llvm::StringRef reason, |
54 | RegisterMap registers, unsigned int signal); |
55 | |
56 | const lldb_private::RegisterValue *ReadRegister(unsigned int Id) const; |
57 | |
58 | private: |
59 | std::string m_name; |
60 | std::string m_reason; |
61 | RegisterMap m_registers; |
62 | }; |
63 | |
64 | class JThreadsInfo : public Parser<JThreadsInfo> { |
65 | public: |
66 | static llvm::Expected<JThreadsInfo> |
67 | create(llvm::StringRef Response, |
68 | llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos); |
69 | |
70 | const ThreadInfoMap &GetThreadInfos() const; |
71 | |
72 | private: |
73 | static llvm::Expected<RegisterMap> |
74 | parseRegisters(const lldb_private::StructuredData::Dictionary &Dict, |
75 | llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos); |
76 | |
77 | JThreadsInfo() = default; |
78 | ThreadInfoMap m_thread_infos; |
79 | }; |
80 | |
81 | struct RegisterInfoParser : public Parser<lldb_private::RegisterInfo> { |
82 | static llvm::Expected<lldb_private::RegisterInfo> |
83 | create(llvm::StringRef Response); |
84 | }; |
85 | |
86 | llvm::Expected<lldb_private::RegisterValue> |
87 | parseRegisterValue(const lldb_private::RegisterInfo &Info, |
88 | llvm::StringRef HexValue, llvm::endianness Endian, |
89 | bool ZeroPad = false); |
90 | |
91 | class StopReply : public Parser<std::unique_ptr<StopReply>> { |
92 | public: |
93 | StopReply() = default; |
94 | virtual ~StopReply() = default; |
95 | |
96 | static llvm::Expected<std::unique_ptr<StopReply>> |
97 | create(llvm::StringRef Response, llvm::endianness Endian, |
98 | llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos); |
99 | |
100 | // for llvm::cast<> |
101 | virtual lldb_private::WaitStatus getKind() const = 0; |
102 | |
103 | StopReply(const StopReply &) = delete; |
104 | void operator=(const StopReply &) = delete; |
105 | }; |
106 | |
107 | class StopReplyStop : public StopReply { |
108 | public: |
109 | StopReplyStop(uint8_t Signal, lldb::tid_t ThreadId, llvm::StringRef Name, |
110 | RegisterMap ThreadPcs, RegisterMap Registers, |
111 | llvm::StringRef Reason) |
112 | : Signal(Signal), ThreadId(ThreadId), Name(Name), |
113 | ThreadPcs(std::move(ThreadPcs)), Registers(std::move(Registers)), |
114 | Reason(Reason) {} |
115 | |
116 | static llvm::Expected<std::unique_ptr<StopReplyStop>> |
117 | create(llvm::StringRef Response, llvm::endianness Endian, |
118 | llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos); |
119 | |
120 | const RegisterMap &getThreadPcs() const { return ThreadPcs; } |
121 | lldb::tid_t getThreadId() const { return ThreadId; } |
122 | |
123 | // for llvm::cast<> |
124 | lldb_private::WaitStatus getKind() const override { |
125 | return lldb_private::WaitStatus{lldb_private::WaitStatus::Stop, Signal}; |
126 | } |
127 | static bool classof(const StopReply *R) { |
128 | return R->getKind().type == lldb_private::WaitStatus::Stop; |
129 | } |
130 | |
131 | private: |
132 | static llvm::Expected<RegisterMap> parseRegisters( |
133 | const llvm::StringMap<llvm::SmallVector<llvm::StringRef, 2>> &Elements, |
134 | llvm::endianness Endian, |
135 | llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos); |
136 | |
137 | uint8_t Signal; |
138 | lldb::tid_t ThreadId; |
139 | std::string Name; |
140 | RegisterMap ThreadPcs; |
141 | RegisterMap Registers; |
142 | std::string Reason; |
143 | }; |
144 | |
145 | class StopReplyExit : public StopReply { |
146 | public: |
147 | explicit StopReplyExit(uint8_t Status) : Status(Status) {} |
148 | |
149 | static llvm::Expected<std::unique_ptr<StopReplyExit>> |
150 | create(llvm::StringRef response); |
151 | |
152 | // for llvm::cast<> |
153 | lldb_private::WaitStatus getKind() const override { |
154 | return lldb_private::WaitStatus{lldb_private::WaitStatus::Exit, Status}; |
155 | } |
156 | static bool classof(const StopReply *R) { |
157 | return R->getKind().type == lldb_private::WaitStatus::Exit; |
158 | } |
159 | |
160 | private: |
161 | uint8_t Status; |
162 | }; |
163 | |
164 | // Common functions for parsing packet data. |
165 | llvm::Expected<llvm::StringMap<llvm::StringRef>> |
166 | SplitUniquePairList(llvm::StringRef caller, llvm::StringRef s); |
167 | |
168 | llvm::StringMap<llvm::SmallVector<llvm::StringRef, 2>> |
169 | SplitPairList(llvm::StringRef s); |
170 | |
171 | template <typename... Args> |
172 | llvm::Error make_parsing_error(llvm::StringRef format, Args &&... args) { |
173 | std::string error = |
174 | "Unable to parse " + |
175 | llvm::formatv(format.data(), std::forward<Args>(args)...).str(); |
176 | return llvm::make_error<llvm::StringError>(Args&: error, |
177 | Args: llvm::inconvertibleErrorCode()); |
178 | } |
179 | |
180 | } // namespace llgs_tests |
181 | |
182 | namespace lldb_private { |
183 | std::ostream &operator<<(std::ostream &OS, const RegisterValue &RegVal); |
184 | } |
185 | |
186 | #endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_MESSAGEOBJECTS_H |
187 | |