1 //===-- CommunicationKDP.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_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H
11 
12 #include <list>
13 #include <mutex>
14 #include <string>
15 
16 #include "lldb/Core/Communication.h"
17 #include "lldb/Core/StreamBuffer.h"
18 #include "lldb/Utility/Listener.h"
19 #include "lldb/Utility/Predicate.h"
20 #include "lldb/lldb-private.h"
21 
22 class CommunicationKDP : public lldb_private::Communication {
23 public:
24   const static uint32_t kMaxPacketSize = 1200;
25   const static uint32_t kMaxDataSize = 1024;
26   typedef lldb_private::StreamBuffer<4096> PacketStreamType;
27   enum CommandType {
28     KDP_CONNECT = 0u,
29     KDP_DISCONNECT,
30     KDP_HOSTINFO,
31     KDP_VERSION,
32     KDP_MAXBYTES,
33     KDP_READMEM,
34     KDP_WRITEMEM,
35     KDP_READREGS,
36     KDP_WRITEREGS,
37     KDP_LOAD,
38     KDP_IMAGEPATH,
39     KDP_SUSPEND,
40     KDP_RESUMECPUS,
41     KDP_EXCEPTION,
42     KDP_TERMINATION,
43     KDP_BREAKPOINT_SET,
44     KDP_BREAKPOINT_REMOVE,
45     KDP_REGIONS,
46     KDP_REATTACH,
47     KDP_HOSTREBOOT,
48     KDP_READMEM64,
49     KDP_WRITEMEM64,
50     KDP_BREAKPOINT_SET64,
51     KDP_BREAKPOINT_REMOVE64,
52     KDP_KERNELVERSION,
53     KDP_READPHYSMEM64,
54     KDP_WRITEPHYSMEM64,
55     KDP_READIOPORT,
56     KDP_WRITEIOPORT,
57     KDP_READMSR64,
58     KDP_WRITEMSR64,
59     KDP_DUMPINFO
60   };
61 
62   enum { KDP_FEATURE_BP = (1u << 0) };
63 
64   enum KDPError {
65     KDP_PROTERR_SUCCESS = 0,
66     KDP_PROTERR_ALREADY_CONNECTED,
67     KDP_PROTERR_BAD_NBYTES,
68     KDP_PROTERR_BADFLAVOR
69   };
70 
71   enum PacketType {
72     ePacketTypeRequest = 0x00u,
73     ePacketTypeReply = 0x80u,
74     ePacketTypeMask = 0x80u,
75     eCommandTypeMask = 0x7fu
76   };
77   // Constructors and Destructors
78   CommunicationKDP(const char *comm_name);
79 
80   ~CommunicationKDP() override;
81 
82   bool SendRequestPacket(const PacketStreamType &request_packet);
83 
84   // Wait for a packet within 'nsec' seconds
85   size_t
86   WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
87                                        uint32_t usec);
88 
89   bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
90 
91   bool CheckForPacket(const uint8_t *src, size_t src_len,
92                       lldb_private::DataExtractor &packet);
IsRunning()93   bool IsRunning() const { return m_is_running.GetValue(); }
94 
95   // Set the global packet timeout.
96   //
97   // For clients, this is the timeout that gets used when sending
98   // packets and waiting for responses. For servers, this might not
99   // get used, and if it doesn't this should be moved to the
100   // CommunicationKDPClient.
SetPacketTimeout(std::chrono::seconds packet_timeout)101   std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
102     const auto old_packet_timeout = m_packet_timeout;
103     m_packet_timeout = packet_timeout;
104     return old_packet_timeout;
105   }
106 
GetPacketTimeout()107   std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
108 
109   // Public Request Packets
110   bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
111                           const char *greeting);
112 
113   bool SendRequestReattach(uint16_t reply_port);
114 
115   bool SendRequestDisconnect();
116 
117   uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
118                                  uint32_t dst_size,
119                                  lldb_private::Status &error);
120 
121   uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
122                                   uint32_t src_len,
123                                   lldb_private::Status &error);
124 
125   bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
126                       lldb_private::DataExtractor &reply,
127                       lldb_private::Status &error);
128 
129   uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
130                                     uint32_t dst_size,
131                                     lldb_private::Status &error);
132 
133   uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
134                                      const void *src, uint32_t src_size,
135                                      lldb_private::Status &error);
136 
137   const char *GetKernelVersion();
138 
139   // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
140   // const char *
141   // GetImagePath ();
142 
143   uint32_t GetVersion();
144 
145   uint32_t GetFeatureFlags();
146 
LocalBreakpointsAreSupported()147   bool LocalBreakpointsAreSupported() {
148     return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
149   }
150 
151   uint32_t GetCPUMask();
152 
153   uint32_t GetCPUType();
154 
155   uint32_t GetCPUSubtype();
156 
157   lldb_private::UUID GetUUID();
158 
159   bool RemoteIsEFI();
160 
161   bool RemoteIsDarwinKernel();
162 
163   lldb::addr_t GetLoadAddress();
164 
165   bool SendRequestResume();
166 
167   bool SendRequestSuspend();
168 
169   bool SendRequestBreakpoint(bool set, lldb::addr_t addr);
170 
171 protected:
172   bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
173 
174   size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
175       lldb_private::DataExtractor &response, uint32_t timeout_usec);
176 
177   bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
178 
179   void MakeRequestPacketHeader(CommandType request_type,
180                                PacketStreamType &request_packet,
181                                uint16_t request_length);
182 
183   // Protected Request Packets (use public accessors which will cache
184   // results.
185   bool SendRequestVersion();
186 
187   bool SendRequestHostInfo();
188 
189   bool SendRequestKernelVersion();
190 
191   // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
192   // bool
193   // SendRequestImagePath ();
194 
195   void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
196 
197   void DumpPacket(lldb_private::Stream &s,
198                   const lldb_private::DataExtractor &extractor);
199 
VersionIsValid()200   bool VersionIsValid() const { return m_kdp_version_version != 0; }
201 
HostInfoIsValid()202   bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
203 
ExtractIsReply(uint8_t first_packet_byte)204   bool ExtractIsReply(uint8_t first_packet_byte) const {
205     // TODO: handle big endian...
206     return (first_packet_byte & ePacketTypeMask) != 0;
207   }
208 
ExtractCommand(uint8_t first_packet_byte)209   CommandType ExtractCommand(uint8_t first_packet_byte) const {
210     // TODO: handle big endian...
211     return (CommandType)(first_packet_byte & eCommandTypeMask);
212   }
213 
214   static const char *GetCommandAsCString(uint8_t command);
215 
216   void ClearKDPSettings();
217 
218   bool SendRequestAndGetReply(const CommandType command,
219                               const PacketStreamType &request_packet,
220                               lldb_private::DataExtractor &reply_packet);
221   // Classes that inherit from CommunicationKDP can see and modify these
222   uint32_t m_addr_byte_size;
223   lldb::ByteOrder m_byte_order;
224   std::string m_bytes;
225   std::recursive_mutex m_bytes_mutex;
226   std::chrono::seconds m_packet_timeout;
227   std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
228                                          // packets to a single thread at a time
229   lldb_private::Predicate<bool> m_is_running;
230   uint32_t m_session_key;
231   uint8_t m_request_sequence_id;
232   uint8_t m_exception_sequence_id;
233   uint32_t m_kdp_version_version;
234   uint32_t m_kdp_version_feature;
235   uint32_t m_kdp_hostinfo_cpu_mask;
236   uint32_t m_kdp_hostinfo_cpu_type;
237   uint32_t m_kdp_hostinfo_cpu_subtype;
238   std::string m_kernel_version;
239   // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to
240   // hang the KDP connection...
241   lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
242 private:
243   // For CommunicationKDP only
244   CommunicationKDP(const CommunicationKDP &) = delete;
245   const CommunicationKDP &operator=(const CommunicationKDP &) = delete;
246 };
247 
248 #endif // LLDB_SOURCE_PLUGINS_PROCESS_MACOSX_KERNEL_COMMUNICATIONKDP_H
249