1 //===-- CommunicationKDP.h --------------------------------------*- C++ -*-===//
2 //
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>
16 #include <mutex>
17 #include <string>
18 
19 // Other libraries and framework includes
20 // Project includes
21 #include "lldb/Core/Communication.h"
22 #include "lldb/Core/Listener.h"
23 #include "lldb/Core/StreamBuffer.h"
24 #include "lldb/Host/Predicate.h"
25 #include "lldb/lldb-private.h"
26 
27 class CommunicationKDP : public lldb_private::Communication {
28 public:
29   enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit };
30 
31   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;
68 
69   enum { KDP_FEATURE_BP = (1u << 0) };
70 
71   typedef enum {
72     KDP_PROTERR_SUCCESS = 0,
73     KDP_PROTERR_ALREADY_CONNECTED,
74     KDP_PROTERR_BAD_NBYTES,
75     KDP_PROTERR_BADFLAVOR
76   } KDPError;
77 
78   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);
88 
89   virtual ~CommunicationKDP();
90 
91   bool SendRequestPacket(const PacketStreamType &request_packet);
92 
93   // Wait for a packet within 'nsec' seconds
94   size_t
95   WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
96                                        uint32_t usec);
97 
98   bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
99 
100   bool CheckForPacket(const uint8_t *src, size_t src_len,
101                       lldb_private::DataExtractor &packet);
102   bool IsRunning() const { return m_is_running.GetValue(); }
103 
104   //------------------------------------------------------------------
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   //------------------------------------------------------------------
112   std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
113     const auto old_packet_timeout = m_packet_timeout;
114     m_packet_timeout = packet_timeout;
115     return old_packet_timeout;
116   }
117 
118   std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
119 
120   //------------------------------------------------------------------
121   // Public Request Packets
122   //------------------------------------------------------------------
123   bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
124                           const char *greeting);
125 
126   bool SendRequestReattach(uint16_t reply_port);
127 
128   bool SendRequestDisconnect();
129 
130   uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
131                                  uint32_t dst_size, lldb_private::Error &error);
132 
133   uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
134                                   uint32_t src_len, lldb_private::Error &error);
135 
136   bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
137                       lldb_private::DataExtractor &reply,
138                       lldb_private::Error &error);
139 
140   uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
141                                     uint32_t dst_size,
142                                     lldb_private::Error &error);
143 
144   uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
145                                      const void *src, uint32_t src_size,
146                                      lldb_private::Error &error);
147 
148   const char *GetKernelVersion();
149 
150   // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
151   // const char *
152   // GetImagePath ();
153 
154   uint32_t GetVersion();
155 
156   uint32_t GetFeatureFlags();
157 
158   bool LocalBreakpointsAreSupported() {
159     return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
160   }
161 
162   uint32_t GetCPUMask();
163 
164   uint32_t GetCPUType();
165 
166   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);
181 
182 protected:
183   bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
184 
185   size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
186       lldb_private::DataExtractor &response, uint32_t timeout_usec);
187 
188   bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
189 
190   void MakeRequestPacketHeader(CommandType request_type,
191                                PacketStreamType &request_packet,
192                                uint16_t request_length);
193 
194   //------------------------------------------------------------------
195   // Protected Request Packets (use public accessors which will cache
196   // results.
197   //------------------------------------------------------------------
198   bool SendRequestVersion();
199 
200   bool SendRequestHostInfo();
201 
202   bool SendRequestKernelVersion();
203 
204   // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
205   // bool
206   // SendRequestImagePath ();
207 
208   void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
209 
210   void DumpPacket(lldb_private::Stream &s,
211                   const lldb_private::DataExtractor &extractor);
212 
213   bool VersionIsValid() const { return m_kdp_version_version != 0; }
214 
215   bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
216 
217   bool ExtractIsReply(uint8_t first_packet_byte) const {
218     // TODO: handle big endian...
219     return (first_packet_byte & ePacketTypeMask) != 0;
220   }
221 
222   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;
239   std::chrono::seconds m_packet_timeout;
240   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
255 private:
256   //------------------------------------------------------------------
257   // For CommunicationKDP only
258   //------------------------------------------------------------------
259   DISALLOW_COPY_AND_ASSIGN(CommunicationKDP);
260 };
261 
262 #endif // liblldb_CommunicationKDP_h_
263