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 <string>
17 
18 // Other libraries and framework includes
19 // Project includes
20 #include "lldb/lldb-private.h"
21 #include "lldb/Core/Communication.h"
22 #include "lldb/Core/Listener.h"
23 #include "lldb/Core/StreamBuffer.h"
24 #include "lldb/Host/Mutex.h"
25 #include "lldb/Host/Predicate.h"
26 #include "lldb/Host/TimeValue.h"
27 
28 class CommunicationKDP : public lldb_private::Communication
29 {
30 public:
31     enum
32     {
33         eBroadcastBitRunPacketSent = kLoUserBroadcastBit
34     };
35 
36     const static uint32_t kMaxPacketSize = 1200;
37     const static uint32_t kMaxDataSize = 1024;
38     typedef lldb_private::StreamBuffer<1024> PacketStreamType;
39     typedef enum
40     {
41         KDP_CONNECT = 0u,
42         KDP_DISCONNECT,
43         KDP_HOSTINFO,
44         KDP_VERSION,
45         KDP_MAXBYTES,
46         KDP_READMEM,
47         KDP_WRITEMEM,
48         KDP_READREGS,
49         KDP_WRITEREGS,
50         KDP_LOAD,
51         KDP_IMAGEPATH,
52         KDP_SUSPEND,
53         KDP_RESUMECPUS,
54         KDP_EXCEPTION,
55         KDP_TERMINATION,
56         KDP_BREAKPOINT_SET,
57         KDP_BREAKPOINT_REMOVE,
58         KDP_REGIONS,
59         KDP_REATTACH,
60         KDP_HOSTREBOOT,
61         KDP_READMEM64,
62         KDP_WRITEMEM64,
63         KDP_BREAKPOINT_SET64,
64         KDP_BREAKPOINT_REMOVE64,
65         KDP_KERNELVERSION
66     } CommandType;
67 
68     enum
69     {
70         KDP_FEATURE_BP = (1u << 0)
71     };
72 
73     typedef enum
74     {
75         KDP_PROTERR_SUCCESS = 0,
76         KDP_PROTERR_ALREADY_CONNECTED,
77         KDP_PROTERR_BAD_NBYTES,
78         KDP_PROTERR_BADFLAVOR
79     } KDPError;
80 
81     typedef enum
82     {
83         ePacketTypeRequest  = 0x00u,
84         ePacketTypeReply    = 0x80u,
85         ePacketTypeMask     = 0x80u,
86         eCommandTypeMask    = 0x7fu
87     } PacketType;
88     //------------------------------------------------------------------
89     // Constructors and Destructors
90     //------------------------------------------------------------------
91     CommunicationKDP (const char *comm_name);
92 
93     virtual
94     ~CommunicationKDP();
95 
96     bool
97     SendRequestPacket (const PacketStreamType &request_packet);
98 
99     // Wait for a packet within 'nsec' seconds
100     size_t
101     WaitForPacketWithTimeoutMicroSeconds (lldb_private::DataExtractor &response,
102                                           uint32_t usec);
103 
104     bool
105     GetSequenceMutex(lldb_private::Mutex::Locker& locker);
106 
107     bool
108     CheckForPacket (const uint8_t *src,
109                     size_t src_len,
110                     lldb_private::DataExtractor &packet);
111     bool
112     IsRunning() const
113     {
114         return m_is_running.GetValue();
115     }
116 
117     //------------------------------------------------------------------
118     // Set the global packet timeout.
119     //
120     // For clients, this is the timeout that gets used when sending
121     // packets and waiting for responses. For servers, this might not
122     // get used, and if it doesn't this should be moved to the
123     // CommunicationKDPClient.
124     //------------------------------------------------------------------
125     uint32_t
126     SetPacketTimeout (uint32_t packet_timeout)
127     {
128         const uint32_t old_packet_timeout = m_packet_timeout;
129         m_packet_timeout = packet_timeout;
130         return old_packet_timeout;
131     }
132 
133     uint32_t
134     GetPacketTimeoutInMicroSeconds () const
135     {
136         return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec;
137     }
138     //------------------------------------------------------------------
139     // Start a debugserver instance on the current host using the
140     // supplied connection URL.
141     //------------------------------------------------------------------
142     lldb_private::Error
143     StartDebugserverProcess (const char *connect_url,
144                              const char *unix_socket_name,
145                              lldb_private::ProcessLaunchInfo &launch_info);
146 
147 
148     //------------------------------------------------------------------
149     // Public Request Packets
150     //------------------------------------------------------------------
151     bool
152     SendRequestConnect (uint16_t reply_port,
153                         uint16_t exc_port,
154                         const char *greeting);
155 
156     bool
157     SendRequestReattach (uint16_t reply_port);
158 
159     bool
160     SendRequestDisconnect ();
161 
162     uint32_t
163     SendRequestReadMemory (lldb::addr_t addr,
164                            void *dst,
165                            uint32_t dst_size,
166                            lldb_private::Error &error);
167 
168     uint32_t
169     SendRequestWriteMemory (lldb::addr_t addr,
170                             const void *src,
171                             uint32_t src_len,
172                             lldb_private::Error &error);
173 
174     bool
175     SendRawRequest (uint8_t command_byte,
176                     const void *src,
177                     uint32_t src_len,
178                     lldb_private::DataExtractor &reply,
179                     lldb_private::Error &error);
180 
181     uint32_t
182     SendRequestReadRegisters (uint32_t cpu,
183                               uint32_t flavor,
184                               void *dst,
185                               uint32_t dst_size,
186                               lldb_private::Error &error);
187 
188     uint32_t
189     SendRequestWriteRegisters (uint32_t cpu,
190                                uint32_t flavor,
191                                const void *src,
192                                uint32_t src_size,
193                                lldb_private::Error &error);
194 
195     const char *
196     GetKernelVersion ();
197 
198     // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
199     // const char *
200     // GetImagePath ();
201 
202     uint32_t
203     GetVersion ();
204 
205     uint32_t
206     GetFeatureFlags ();
207 
208     bool
209     LocalBreakpointsAreSupported ()
210     {
211         return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
212     }
213 
214     uint32_t
215     GetCPUMask ();
216 
217     uint32_t
218     GetCPUType ();
219 
220     uint32_t
221     GetCPUSubtype ();
222 
223     lldb_private::UUID
224     GetUUID ();
225 
226     bool
227     RemoteIsEFI ();
228 
229     lldb::addr_t
230     GetLoadAddress ();
231 
232     bool
233     SendRequestResume ();
234 
235     bool
236     SendRequestSuspend ();
237 
238     bool
239     SendRequestBreakpoint (bool set, lldb::addr_t addr);
240 
241 protected:
242 
243     bool
244     SendRequestPacketNoLock (const PacketStreamType &request_packet);
245 
246     size_t
247     WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
248                                                 uint32_t timeout_usec);
249 
250     bool
251     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
252 
253     void
254     MakeRequestPacketHeader (CommandType request_type,
255                              PacketStreamType &request_packet,
256                              uint16_t request_length);
257 
258     //------------------------------------------------------------------
259     // Protected Request Packets (use public accessors which will cache
260     // results.
261     //------------------------------------------------------------------
262     bool
263     SendRequestVersion ();
264 
265     bool
266     SendRequestHostInfo ();
267 
268     bool
269     SendRequestKernelVersion ();
270 
271     // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
272     //bool
273     //SendRequestImagePath ();
274 
275     void
276     DumpPacket (lldb_private::Stream &s,
277                 const void *data,
278                 uint32_t data_len);
279 
280     void
281     DumpPacket (lldb_private::Stream &s,
282                 const lldb_private::DataExtractor& extractor);
283 
284     bool
285     VersionIsValid() const
286     {
287         return m_kdp_version_version != 0;
288     }
289 
290     bool
291     HostInfoIsValid() const
292     {
293         return m_kdp_hostinfo_cpu_type != 0;
294     }
295 
296     bool
297     ExtractIsReply (uint8_t first_packet_byte) const
298     {
299         // TODO: handle big endian...
300         return (first_packet_byte & ePacketTypeMask) != 0;
301     }
302 
303     CommandType
304     ExtractCommand (uint8_t first_packet_byte) const
305     {
306         // TODO: handle big endian...
307         return (CommandType)(first_packet_byte & eCommandTypeMask);
308     }
309 
310     static const char *
311     GetCommandAsCString (uint8_t command);
312 
313     void
314     ClearKDPSettings ();
315 
316     bool
317     SendRequestAndGetReply (const CommandType command,
318                             const uint8_t request_sequence_id,
319                             const PacketStreamType &request_packet,
320                             lldb_private::DataExtractor &reply_packet);
321     //------------------------------------------------------------------
322     // Classes that inherit from CommunicationKDP can see and modify these
323     //------------------------------------------------------------------
324     uint32_t m_addr_byte_size;
325     lldb::ByteOrder m_byte_order;
326     uint32_t m_packet_timeout;
327     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
328     lldb_private::Predicate<bool> m_is_running;
329     uint32_t m_session_key;
330     uint8_t m_request_sequence_id;
331     uint8_t m_exception_sequence_id;
332     uint32_t m_kdp_version_version;
333     uint32_t m_kdp_version_feature;
334     uint32_t m_kdp_hostinfo_cpu_mask;
335     uint32_t m_kdp_hostinfo_cpu_type;
336     uint32_t m_kdp_hostinfo_cpu_subtype;
337     std::string m_kernel_version;
338     //std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
339     lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
340 private:
341     //------------------------------------------------------------------
342     // For CommunicationKDP only
343     //------------------------------------------------------------------
344     DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
345 };
346 
347 #endif  // liblldb_CommunicationKDP_h_
348