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_public_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     uint32_t
175     SendRequestReadRegisters (uint32_t cpu,
176                               uint32_t flavor,
177                               void *dst,
178                               uint32_t dst_size,
179                               lldb_private::Error &error);
180 
181     const char *
182     GetKernelVersion ();
183 
184     // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
185     // const char *
186     // GetImagePath ();
187 
188     uint32_t
189     GetVersion ();
190 
191     uint32_t
192     GetFeatureFlags ();
193 
194     bool
195     LocalBreakpointsAreSupported ()
196     {
197         return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
198     }
199 
200     uint32_t
201     GetCPUMask ();
202 
203     uint32_t
204     GetCPUType ();
205 
206     uint32_t
207     GetCPUSubtype ();
208 
209     // If cpu_mask is zero, then we will resume all CPUs
210     bool
211     SendRequestResume (uint32_t cpu_mask = 0);
212 
213     bool
214     SendRequestSuspend ();
215 
216     bool
217     SendRequestBreakpoint (bool set, lldb::addr_t addr);
218 
219 protected:
220 
221     bool
222     SendRequestPacketNoLock (const PacketStreamType &request_packet);
223 
224     size_t
225     WaitForPacketWithTimeoutMicroSecondsNoLock (lldb_private::DataExtractor &response,
226                                                 uint32_t timeout_usec);
227 
228     bool
229     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
230 
231     void
232     MakeRequestPacketHeader (CommandType request_type,
233                              PacketStreamType &request_packet,
234                              uint16_t request_length);
235 
236     //------------------------------------------------------------------
237     // Protected Request Packets (use public accessors which will cache
238     // results.
239     //------------------------------------------------------------------
240     bool
241     SendRequestVersion ();
242 
243     bool
244     SendRequestHostInfo ();
245 
246     bool
247     SendRequestKernelVersion ();
248 
249     // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
250     //bool
251     //SendRequestImagePath ();
252 
253     void
254     DumpPacket (lldb_private::Stream &s,
255                 const void *data,
256                 uint32_t data_len);
257 
258     void
259     DumpPacket (lldb_private::Stream &s,
260                 const lldb_private::DataExtractor& extractor);
261 
262     bool
263     VersionIsValid() const
264     {
265         return m_kdp_version_version != 0;
266     }
267 
268     bool
269     HostInfoIsValid() const
270     {
271         return m_kdp_hostinfo_cpu_type != 0;
272     }
273 
274     bool
275     ExtractIsReply (uint8_t first_packet_byte) const
276     {
277         // TODO: handle big endian...
278         return (first_packet_byte & ePacketTypeMask) != 0;
279     }
280 
281     CommandType
282     ExtractCommand (uint8_t first_packet_byte) const
283     {
284         // TODO: handle big endian...
285         return (CommandType)(first_packet_byte & eCommandTypeMask);
286     }
287 
288     static const char *
289     GetCommandAsCString (uint8_t command);
290 
291     void
292     ClearKDPSettings ();
293 
294     bool
295     SendRequestAndGetReply (const CommandType command,
296                             const uint8_t request_sequence_id,
297                             const PacketStreamType &request_packet,
298                             lldb_private::DataExtractor &reply_packet);
299     //------------------------------------------------------------------
300     // Classes that inherit from CommunicationKDP can see and modify these
301     //------------------------------------------------------------------
302     uint32_t m_addr_byte_size;
303     lldb::ByteOrder m_byte_order;
304     uint32_t m_packet_timeout;
305     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
306     lldb_private::Predicate<bool> m_public_is_running;
307     lldb_private::Predicate<bool> m_private_is_running;
308     uint32_t m_session_key;
309     uint8_t m_request_sequence_id;
310     uint8_t m_exception_sequence_id;
311     uint32_t m_kdp_version_version;
312     uint32_t m_kdp_version_feature;
313     uint32_t m_kdp_hostinfo_cpu_mask;
314     uint32_t m_kdp_hostinfo_cpu_type;
315     uint32_t m_kdp_hostinfo_cpu_subtype;
316     std::string m_kernel_version;
317     //std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
318     lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
319 private:
320     //------------------------------------------------------------------
321     // For CommunicationKDP only
322     //------------------------------------------------------------------
323     DISALLOW_COPY_AND_ASSIGN (CommunicationKDP);
324 };
325 
326 #endif  // liblldb_CommunicationKDP_h_
327