blob: eed3daa4647e2bd8fe6ea405dc87dabddb3d0cb7 [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"
Kate Stoneb9c1b512016-09-06 20:57:50 +000025#include "lldb/lldb-private.h"
Greg Claytonf9765ac2011-07-15 03:27:12 +000026
Kate Stoneb9c1b512016-09-06 20:57:50 +000027class CommunicationKDP : public lldb_private::Communication {
Greg Claytonf9765ac2011-07-15 03:27:12 +000028public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000029 enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit };
Greg Clayton57508022011-07-15 16:31:38 +000030
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 const static uint32_t kMaxPacketSize = 1200;
32 const static uint32_t kMaxDataSize = 1024;
33 typedef lldb_private::StreamBuffer<1024> PacketStreamType;
34 typedef enum {
35 KDP_CONNECT = 0u,
36 KDP_DISCONNECT,
37 KDP_HOSTINFO,
38 KDP_VERSION,
39 KDP_MAXBYTES,
40 KDP_READMEM,
41 KDP_WRITEMEM,
42 KDP_READREGS,
43 KDP_WRITEREGS,
44 KDP_LOAD,
45 KDP_IMAGEPATH,
46 KDP_SUSPEND,
47 KDP_RESUMECPUS,
48 KDP_EXCEPTION,
49 KDP_TERMINATION,
50 KDP_BREAKPOINT_SET,
51 KDP_BREAKPOINT_REMOVE,
52 KDP_REGIONS,
53 KDP_REATTACH,
54 KDP_HOSTREBOOT,
55 KDP_READMEM64,
56 KDP_WRITEMEM64,
57 KDP_BREAKPOINT_SET64,
58 KDP_BREAKPOINT_REMOVE64,
59 KDP_KERNELVERSION,
60 KDP_READPHYSMEM64,
61 KDP_WRITEPHYSMEM64,
62 KDP_READIOPORT,
63 KDP_WRITEIOPORT,
64 KDP_READMSR64,
65 KDP_WRITEMSR64,
66 KDP_DUMPINFO
67 } CommandType;
Greg Clayton07e66e32011-07-20 03:41:06 +000068
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 enum { KDP_FEATURE_BP = (1u << 0) };
Greg Claytonf9765ac2011-07-15 03:27:12 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 typedef enum {
72 KDP_PROTERR_SUCCESS = 0,
73 KDP_PROTERR_ALREADY_CONNECTED,
74 KDP_PROTERR_BAD_NBYTES,
75 KDP_PROTERR_BADFLAVOR
76 } KDPError;
Greg Claytonf9765ac2011-07-15 03:27:12 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 typedef enum {
79 ePacketTypeRequest = 0x00u,
80 ePacketTypeReply = 0x80u,
81 ePacketTypeMask = 0x80u,
82 eCommandTypeMask = 0x7fu
83 } PacketType;
84 //------------------------------------------------------------------
85 // Constructors and Destructors
86 //------------------------------------------------------------------
87 CommunicationKDP(const char *comm_name);
Greg Claytonf9765ac2011-07-15 03:27:12 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 virtual ~CommunicationKDP();
Greg Claytonf9765ac2011-07-15 03:27:12 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 bool SendRequestPacket(const PacketStreamType &request_packet);
Greg Claytonf9765ac2011-07-15 03:27:12 +000092
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 // Wait for a packet within 'nsec' seconds
94 size_t
95 WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
96 uint32_t usec);
Greg Claytonf9765ac2011-07-15 03:27:12 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
Greg Claytonf9765ac2011-07-15 03:27:12 +000099
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 bool CheckForPacket(const uint8_t *src, size_t src_len,
101 lldb_private::DataExtractor &packet);
102 bool IsRunning() const { return m_is_running.GetValue(); }
Greg Clayton57508022011-07-15 16:31:38 +0000103
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104 //------------------------------------------------------------------
105 // Set the global packet timeout.
106 //
107 // For clients, this is the timeout that gets used when sending
108 // packets and waiting for responses. For servers, this might not
109 // get used, and if it doesn't this should be moved to the
110 // CommunicationKDPClient.
111 //------------------------------------------------------------------
Pavel Labath5cddd602016-11-02 10:13:54 +0000112 std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
113 const auto old_packet_timeout = m_packet_timeout;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 m_packet_timeout = packet_timeout;
115 return old_packet_timeout;
116 }
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000117
Pavel Labath5cddd602016-11-02 10:13:54 +0000118 std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
Greg Claytona63d08c2011-07-19 03:57:15 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 //------------------------------------------------------------------
121 // Public Request Packets
122 //------------------------------------------------------------------
123 bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
124 const char *greeting);
Greg Clayton0c54d8a2011-07-20 01:32:50 +0000125
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126 bool SendRequestReattach(uint16_t reply_port);
Greg Clayton1d19a2f2012-10-19 22:22:57 +0000127
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128 bool SendRequestDisconnect();
Greg Clayton4b1b8b32012-09-21 01:55:30 +0000129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
131 uint32_t dst_size, lldb_private::Error &error);
Greg Clayton4b1b8b32012-09-21 01:55:30 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
134 uint32_t src_len, lldb_private::Error &error);
Greg Clayton5b882162011-07-21 01:12:01 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
137 lldb_private::DataExtractor &reply,
138 lldb_private::Error &error);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
141 uint32_t dst_size,
142 lldb_private::Error &error);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
145 const void *src, uint32_t src_size,
146 lldb_private::Error &error);
Greg Clayton07e66e32011-07-20 03:41:06 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 const char *GetKernelVersion();
Greg Clayton57508022011-07-15 16:31:38 +0000149
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
151 // const char *
152 // GetImagePath ();
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 uint32_t GetVersion();
Jason Molenda840f12c2012-10-25 00:25:13 +0000155
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 uint32_t GetFeatureFlags();
Jason Molendaca2ffa72013-05-09 23:52:21 +0000157
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 bool LocalBreakpointsAreSupported() {
159 return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
160 }
Jason Molenda4bd4e7e2012-09-29 04:02:01 +0000161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 uint32_t GetCPUMask();
Greg Clayton07e66e32011-07-20 03:41:06 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 uint32_t GetCPUType();
Greg Clayton07e66e32011-07-20 03:41:06 +0000165
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 uint32_t GetCPUSubtype();
167
168 lldb_private::UUID GetUUID();
169
170 bool RemoteIsEFI();
171
172 bool RemoteIsDarwinKernel();
173
174 lldb::addr_t GetLoadAddress();
175
176 bool SendRequestResume();
177
178 bool SendRequestSuspend();
179
180 bool SendRequestBreakpoint(bool set, lldb::addr_t addr);
Greg Clayton07e66e32011-07-20 03:41:06 +0000181
Greg Claytonf9765ac2011-07-15 03:27:12 +0000182protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185 size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
186 lldb_private::DataExtractor &response, uint32_t timeout_usec);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 void MakeRequestPacketHeader(CommandType request_type,
191 PacketStreamType &request_packet,
192 uint16_t request_length);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 //------------------------------------------------------------------
195 // Protected Request Packets (use public accessors which will cache
196 // results.
197 //------------------------------------------------------------------
198 bool SendRequestVersion();
Greg Clayton57508022011-07-15 16:31:38 +0000199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 bool SendRequestHostInfo();
Greg Claytona63d08c2011-07-19 03:57:15 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 bool SendRequestKernelVersion();
Greg Clayton5b882162011-07-21 01:12:01 +0000203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
205 // bool
206 // SendRequestImagePath ();
Greg Claytona63d08c2011-07-19 03:57:15 +0000207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208 void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000209
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 void DumpPacket(lldb_private::Stream &s,
211 const lldb_private::DataExtractor &extractor);
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 bool VersionIsValid() const { return m_kdp_version_version != 0; }
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000214
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215 bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
Greg Claytona63d08c2011-07-19 03:57:15 +0000216
Kate Stoneb9c1b512016-09-06 20:57:50 +0000217 bool ExtractIsReply(uint8_t first_packet_byte) const {
218 // TODO: handle big endian...
219 return (first_packet_byte & ePacketTypeMask) != 0;
220 }
Greg Clayton4df8ddf2011-07-16 03:19:08 +0000221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 CommandType ExtractCommand(uint8_t first_packet_byte) const {
223 // TODO: handle big endian...
224 return (CommandType)(first_packet_byte & eCommandTypeMask);
225 }
226
227 static const char *GetCommandAsCString(uint8_t command);
228
229 void ClearKDPSettings();
230
231 bool SendRequestAndGetReply(const CommandType command,
232 const PacketStreamType &request_packet,
233 lldb_private::DataExtractor &reply_packet);
234 //------------------------------------------------------------------
235 // Classes that inherit from CommunicationKDP can see and modify these
236 //------------------------------------------------------------------
237 uint32_t m_addr_byte_size;
238 lldb::ByteOrder m_byte_order;
Pavel Labath5cddd602016-11-02 10:13:54 +0000239 std::chrono::seconds m_packet_timeout;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240 std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
241 // packets to a single thread at a time
242 lldb_private::Predicate<bool> m_is_running;
243 uint32_t m_session_key;
244 uint8_t m_request_sequence_id;
245 uint8_t m_exception_sequence_id;
246 uint32_t m_kdp_version_version;
247 uint32_t m_kdp_version_feature;
248 uint32_t m_kdp_hostinfo_cpu_mask;
249 uint32_t m_kdp_hostinfo_cpu_type;
250 uint32_t m_kdp_hostinfo_cpu_subtype;
251 std::string m_kernel_version;
252 // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to
253 // hang the KDP connection...
254 lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
Greg Claytonf9765ac2011-07-15 03:27:12 +0000255private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256 //------------------------------------------------------------------
257 // For CommunicationKDP only
258 //------------------------------------------------------------------
259 DISALLOW_COPY_AND_ASSIGN(CommunicationKDP);
Greg Claytonf9765ac2011-07-15 03:27:12 +0000260};
261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262#endif // liblldb_CommunicationKDP_h_