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/Utility/Listener.h"
18#include "lldb/Utility/Predicate.h"
19#include "lldb/Utility/StreamBuffer.h"
20#include "lldb/lldb-private.h"
21
22class CommunicationKDP : public lldb_private::Communication {
23public:
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);
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.
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
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
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
171protected:
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
200 bool VersionIsValid() const { return m_kdp_version_version != 0; }
201
202 bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
203
204 bool ExtractIsReply(uint8_t first_packet_byte) const {
205 // TODO: handle big endian...
206 return (first_packet_byte & ePacketTypeMask) != 0;
207 }
208
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
242private:
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

source code of lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h