• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::support::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::support::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::support::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::support::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:
StopReplyStop(uint8_t Signal,lldb::tid_t ThreadId,llvm::StringRef Name,RegisterMap ThreadPcs,RegisterMap Registers,llvm::StringRef Reason)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::support::endianness Endian,
118          llvm::ArrayRef<lldb_private::RegisterInfo> RegInfos);
119 
getThreadPcs()120   const RegisterMap &getThreadPcs() const { return ThreadPcs; }
getThreadId()121   lldb::tid_t getThreadId() const { return ThreadId; }
122 
123   // for llvm::cast<>
getKind()124   lldb_private::WaitStatus getKind() const override {
125     return lldb_private::WaitStatus{lldb_private::WaitStatus::Stop, Signal};
126   }
classof(const StopReply * R)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::support::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:
StopReplyExit(uint8_t Status)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<>
getKind()153   lldb_private::WaitStatus getKind() const override {
154     return lldb_private::WaitStatus{lldb_private::WaitStatus::Exit, Status};
155   }
classof(const StopReply * R)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>
make_parsing_error(llvm::StringRef format,Args &&...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>(error,
177                                              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