blob: 6e02cb22d5167597756e46b54f0f554ead87c0e0 [file] [log] [blame]
Greg Clayton59ec5122011-07-15 18:02:58 +00001//===-- CommunicationKDP.h --------------------------------------*- C++ -*-===//
Greg Claytonf9765ac2011-07-15 03:27:12 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef liblldb_CommunicationKDP_h_
11#define liblldb_CommunicationKDP_h_
12
13// C Includes
14// C++ Includes
15#include <list>
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +000016#include <mutex>
Greg Claytonf9765ac2011-07-15 03:27:12 +000017#include <string>
18
19// Other libraries and framework includes
20// Project includes
Greg Claytonf9765ac2011-07-15 03:27:12 +000021#include "lldb/Core/Communication.h"
22#include "lldb/Core/Listener.h"
Greg Clayton4df8ddf2011-07-16 03:19:08 +000023#include "lldb/Core/StreamBuffer.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000024#include "lldb/Host/Predicate.h"
25#include "lldb/Host/TimeValue.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000026#include "lldb/lldb-private.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000027
Kate Stoneb9c1b512016-09-06 20:57:50 +000028class CommunicationKDP : public lldb_private::Communication {
Greg Claytonf9765ac2011-07-15 03:27:12 +000029public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000030 enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit };
Greg Clayton57508022011-07-15 16:31:38 +000031
Kate Stoneb9c1b512016-09-06 20:57:50 +000032 const static uint32_t kMaxPacketSize = 1200;
33 const static uint32_t kMaxDataSize = 1024;
34 typedef lldb_private::StreamBuffer<1024> PacketStreamType;
35 typedef enum {
36 KDP_CONNECT = 0u,
37 KDP_DISCONNECT,
38 KDP_HOSTINFO,
39 KDP_VERSION,
40 KDP_MAXBYTES,
41 KDP_READMEM,
42 KDP_WRITEMEM,
43 KDP_READREGS,
44 KDP_WRITEREGS,
45 KDP_LOAD,
46 KDP_IMAGEPATH,
47 KDP_SUSPEND,
48 KDP_RESUMECPUS,
49 KDP_EXCEPTION,
50 KDP_TERMINATION,
51 KDP_BREAKPOINT_SET,
52 KDP_BREAKPOINT_REMOVE,
53 KDP_REGIONS,
54 KDP_REATTACH,
55 KDP_HOSTREBOOT,
56 KDP_READMEM64,
57 KDP_WRITEMEM64,
58 KDP_BREAKPOINT_SET64,
59 KDP_BREAKPOINT_REMOVE64,
60 KDP_KERNELVERSION,
61 KDP_READPHYSMEM64,
62 KDP_WRITEPHYSMEM64,
63 KDP_READIOPORT,
64 KDP_WRITEIOPORT,
65 KDP_READMSR64,
66 KDP_WRITEMSR64,
67 KDP_DUMPINFO
68 } CommandType;
Greg Clayton07e66e32011-07-20 03:41:06 +000069
Kate Stoneb9c1b512016-09-06 20:57:50 +000070 enum { KDP_FEATURE_BP = (1u << 0) };
Greg Claytonf9765ac2011-07-15 03:27:12 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 typedef enum {
73 KDP_PROTERR_SUCCESS = 0,
74 KDP_PROTERR_ALREADY_CONNECTED,
75 KDP_PROTERR_BAD_NBYTES,
76 KDP_PROTERR_BADFLAVOR
77 } KDPError;
Greg Claytonf9765ac2011-07-15 03:27:12 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 typedef enum {
80 ePacketTypeRequest = 0x00u,
81 ePacketTypeReply = 0x80u,
82 ePacketTypeMask = 0x80u,
83 eCommandTypeMask = 0x7fu
84 } PacketType;
85 //------------------------------------------------------------------
86 // Constructors and Destructors
87 //------------------------------------------------------------------
88 CommunicationKDP(const char *comm_name);
Greg Claytonf9765ac2011-07-15 03:27:12 +000089
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 virtual ~CommunicationKDP();
Greg Claytonf9765ac2011-07-15 03:27:12 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 bool SendRequestPacket(const PacketStreamType &request_packet);
Greg Claytonf9765ac2011-07-15 03:27:12 +000093
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 // Wait for a packet within 'nsec' seconds
95 size_t
96 WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
97 uint32_t usec);
Greg Claytonf9765ac2011-07-15 03:27:12 +000098
Kate Stoneb9c1b512016-09-06 20:57:50 +000099 bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101 bool CheckForPacket(const uint8_t *src, size_t src_len,
102 lldb_private::DataExtractor &packet);
103 bool IsRunning() const { return m_is_running.GetValue(); }
Greg Clayton57508022011-07-15 16:31:38 +0000104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105 //------------------------------------------------------------------
106 // Set the global packet timeout.
107 //
108 // For clients, this is the timeout that gets used when sending
109 // packets and waiting for responses. For servers, this might not
110 // get used, and if it doesn't this should be moved to the
111 // CommunicationKDPClient.
112 //------------------------------------------------------------------
113 uint32_t SetPacketTimeout(uint32_t packet_timeout) {
114 const uint32_t old_packet_timeout = m_packet_timeout;
115 m_packet_timeout = packet_timeout;
116 return old_packet_timeout;
117 }
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 uint32_t GetPacketTimeoutInMicroSeconds() const {
120 return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
121 }
Greg Claytona63d08c2011-07-19 03:57:15 +0000122
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 //------------------------------------------------------------------
124 // Public Request Packets
125 //------------------------------------------------------------------
126 bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
127 const char *greeting);
Greg Clayton0c54d8a2011-07-20 01:32:50 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 bool SendRequestReattach(uint16_t reply_port);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 bool SendRequestDisconnect();
Greg Clayton4b1b8b32012-09-21 01:55:30 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
134 uint32_t dst_size, lldb_private::Error &error);
Greg Clayton4b1b8b32012-09-21 01:55:30 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
137 uint32_t src_len, lldb_private::Error &error);
Greg Clayton5b882162011-07-21 01:12:01 +0000138
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
140 lldb_private::DataExtractor &reply,
141 lldb_private::Error &error);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
144 uint32_t dst_size,
145 lldb_private::Error &error);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
148 const void *src, uint32_t src_size,
149 lldb_private::Error &error);
Greg Clayton07e66e32011-07-20 03:41:06 +0000150
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 const char *GetKernelVersion();
Greg Clayton57508022011-07-15 16:31:38 +0000152
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
154 // const char *
155 // GetImagePath ();
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000156
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 uint32_t GetVersion();
Jason Molenda840f12c2012-10-25 00:25:13 +0000158
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 uint32_t GetFeatureFlags();
Jason Molendaca2ffa72013-05-09 23:52:21 +0000160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 bool LocalBreakpointsAreSupported() {
162 return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
163 }
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 uint32_t GetCPUMask();
Greg Clayton07e66e32011-07-20 03:41:06 +0000166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 uint32_t GetCPUType();
Greg Clayton07e66e32011-07-20 03:41:06 +0000168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 uint32_t GetCPUSubtype();
170
171 lldb_private::UUID GetUUID();
172
173 bool RemoteIsEFI();
174
175 bool RemoteIsDarwinKernel();
176
177 lldb::addr_t GetLoadAddress();
178
179 bool SendRequestResume();
180
181 bool SendRequestSuspend();
182
183 bool SendRequestBreakpoint(bool set, lldb::addr_t addr);
Greg Clayton07e66e32011-07-20 03:41:06 +0000184
Greg Claytonf9765ac2011-07-15 03:27:12 +0000185protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000186 bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
189 lldb_private::DataExtractor &response, uint32_t timeout_usec);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 void MakeRequestPacketHeader(CommandType request_type,
194 PacketStreamType &request_packet,
195 uint16_t request_length);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 //------------------------------------------------------------------
198 // Protected Request Packets (use public accessors which will cache
199 // results.
200 //------------------------------------------------------------------
201 bool SendRequestVersion();
Greg Clayton57508022011-07-15 16:31:38 +0000202
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203 bool SendRequestHostInfo();
Greg Claytona63d08c2011-07-19 03:57:15 +0000204
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 bool SendRequestKernelVersion();
Greg Clayton5b882162011-07-21 01:12:01 +0000206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
208 // bool
209 // SendRequestImagePath ();
Greg Claytona63d08c2011-07-19 03:57:15 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 void DumpPacket(lldb_private::Stream &s,
214 const lldb_private::DataExtractor &extractor);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000215
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 bool VersionIsValid() const { return m_kdp_version_version != 0; }
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000217
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
Greg Claytona63d08c2011-07-19 03:57:15 +0000219
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 bool ExtractIsReply(uint8_t first_packet_byte) const {
221 // TODO: handle big endian...
222 return (first_packet_byte & ePacketTypeMask) != 0;
223 }
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000224
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 CommandType ExtractCommand(uint8_t first_packet_byte) const {
226 // TODO: handle big endian...
227 return (CommandType)(first_packet_byte & eCommandTypeMask);
228 }
229
230 static const char *GetCommandAsCString(uint8_t command);
231
232 void ClearKDPSettings();
233
234 bool SendRequestAndGetReply(const CommandType command,
235 const PacketStreamType &request_packet,
236 lldb_private::DataExtractor &reply_packet);
237 //------------------------------------------------------------------
238 // Classes that inherit from CommunicationKDP can see and modify these
239 //------------------------------------------------------------------
240 uint32_t m_addr_byte_size;
241 lldb::ByteOrder m_byte_order;
242 uint32_t m_packet_timeout;
243 std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
244 // packets to a single thread at a time
245 lldb_private::Predicate<bool> m_is_running;
246 uint32_t m_session_key;
247 uint8_t m_request_sequence_id;
248 uint8_t m_exception_sequence_id;
249 uint32_t m_kdp_version_version;
250 uint32_t m_kdp_version_feature;
251 uint32_t m_kdp_hostinfo_cpu_mask;
252 uint32_t m_kdp_hostinfo_cpu_type;
253 uint32_t m_kdp_hostinfo_cpu_subtype;
254 std::string m_kernel_version;
255 // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to
256 // hang the KDP connection...
257 lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
Greg Claytonf9765ac2011-07-15 03:27:12 +0000258private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 //------------------------------------------------------------------
260 // For CommunicationKDP only
261 //------------------------------------------------------------------
262 DISALLOW_COPY_AND_ASSIGN(CommunicationKDP);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000263};
264
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265#endif // liblldb_CommunicationKDP_h_