1 //===-- CommunicationKDP.cpp ------------------------------------*- 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 
11 #include "CommunicationKDP.h"
12 
13 // C Includes
14 #include <limits.h>
15 #include <string.h>
16 
17 // C++ Includes
18 #include "llvm/Support/MachO.h"
19 
20 // Other libraries and framework includes
21 #include "lldb/Core/DataBufferHeap.h"
22 #include "lldb/Core/DataExtractor.h"
23 #include "lldb/Core/Log.h"
24 #include "lldb/Core/State.h"
25 #include "lldb/Host/FileSpec.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Host/TimeValue.h"
28 #include "lldb/Target/Process.h"
29 
30 // Project includes
31 #include "ProcessKDPLog.h"
32 
33 #define DEBUGSERVER_BASENAME    "debugserver"
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 //----------------------------------------------------------------------
39 // CommunicationKDP constructor
40 //----------------------------------------------------------------------
41 CommunicationKDP::CommunicationKDP (const char *comm_name) :
42     Communication(comm_name),
43     m_addr_byte_size (4),
44     m_byte_order (eByteOrderLittle),
45     m_packet_timeout (1),
46     m_sequence_mutex (Mutex::eMutexTypeRecursive),
47     m_private_is_running (false),
48     m_session_key (0u),
49     m_request_sequence_id (0u),
50     m_exception_sequence_id (0u),
51     m_kdp_version_version (0u),
52     m_kdp_version_feature (0u),
53     m_kdp_hostinfo_cpu_mask (0u),
54     m_kdp_hostinfo_cpu_type (0u),
55     m_kdp_hostinfo_cpu_subtype (0u)
56 {
57 }
58 
59 //----------------------------------------------------------------------
60 // Destructor
61 //----------------------------------------------------------------------
62 CommunicationKDP::~CommunicationKDP()
63 {
64     if (IsConnected())
65     {
66         Disconnect();
67     }
68 }
69 
70 bool
71 CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet)
72 {
73     Mutex::Locker locker(m_sequence_mutex);
74     return SendRequestPacketNoLock (request_packet);
75 }
76 
77 #if 0
78 typedef struct {
79 	uint8_t     request;	// Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply
80 	uint8_t     sequence;
81 	uint16_t    length;		// Length of entire packet including this header
82 	uint32_t	key;		// Session key
83 } kdp_hdr_t;
84 #endif
85 
86 void
87 CommunicationKDP::MakeRequestPacketHeader (CommandType request_type,
88                                            PacketStreamType &request_packet,
89                                            uint16_t request_length)
90 {
91     request_packet.Clear();
92     request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type
93     request_packet.PutHex8 (m_request_sequence_id++);           // Sequence number
94     request_packet.PutHex16 (request_length);                   // Length of the packet including this header
95     request_packet.PutHex32 (m_session_key);                    // Session key
96 }
97 
98 bool
99 CommunicationKDP::SendRequestAndGetReply (const CommandType command,
100                                           const uint8_t request_sequence_id,
101                                           const PacketStreamType &request_packet,
102                                           DataExtractor &reply_packet)
103 {
104 
105     Mutex::Locker locker(m_sequence_mutex);
106     if (SendRequestPacketNoLock(request_packet))
107     {
108         if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
109         {
110             uint32_t offset = 0;
111             const uint8_t reply_command = reply_packet.GetU8 (&offset);
112             const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
113             if ((reply_command & eCommandTypeMask) == command)
114             {
115                 if (request_sequence_id == reply_sequence_id)
116                     return true;
117             }
118         }
119     }
120     reply_packet.Clear();
121     return false;
122 }
123 
124 bool
125 CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet)
126 {
127     if (IsConnected())
128     {
129         const char *packet_data = request_packet.GetData();
130         const size_t packet_size = request_packet.GetSize();
131 
132         LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
133         if (log)
134         {
135             PacketStreamType log_strm;
136             DumpPacket (log_strm, packet_data, packet_size);
137             log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
138         }
139         ConnectionStatus status = eConnectionStatusSuccess;
140 
141         size_t bytes_written = Write (packet_data,
142                                       packet_size,
143                                       status,
144                                       NULL);
145 
146         if (bytes_written == packet_size)
147             return true;
148 
149         if (log)
150             log->Printf ("error: failed to send packet entire packet %zu of %zu bytes sent", bytes_written, packet_size);
151     }
152     return false;
153 }
154 
155 bool
156 CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker)
157 {
158     return locker.TryLock (m_sequence_mutex.GetMutex());
159 }
160 
161 
162 bool
163 CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
164 {
165     return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
166 }
167 
168 size_t
169 CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec)
170 {
171     Mutex::Locker locker(m_sequence_mutex);
172     return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
173 }
174 
175 size_t
176 CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec)
177 {
178     uint8_t buffer[8192];
179     Error error;
180 
181     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
182 
183     // Check for a packet from our cache first without trying any reading...
184     if (CheckForPacket (NULL, 0, packet))
185         return packet.GetByteSize();
186 
187     bool timed_out = false;
188     while (IsConnected() && !timed_out)
189     {
190         lldb::ConnectionStatus status = eConnectionStatusNoConnection;
191         size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
192 
193         if (log)
194             log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %zu",
195                          __PRETTY_FUNCTION__,
196                          timeout_usec,
197                          Communication::ConnectionStatusAsCString (status),
198                          error.AsCString(),
199                          bytes_read);
200 
201         if (bytes_read > 0)
202         {
203             if (CheckForPacket (buffer, bytes_read, packet))
204                 return packet.GetByteSize();
205         }
206         else
207         {
208             switch (status)
209             {
210             case eConnectionStatusTimedOut:
211                 timed_out = true;
212                 break;
213             case eConnectionStatusSuccess:
214                 //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
215                 break;
216 
217             case eConnectionStatusEndOfFile:
218             case eConnectionStatusNoConnection:
219             case eConnectionStatusLostConnection:
220             case eConnectionStatusError:
221                 Disconnect();
222                 break;
223             }
224         }
225     }
226     packet.Clear ();
227     return 0;
228 }
229 
230 bool
231 CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
232 {
233     // Put the packet data into the buffer in a thread safe fashion
234     Mutex::Locker locker(m_bytes_mutex);
235 
236     LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
237 
238     if (src && src_len > 0)
239     {
240         if (log && log->GetVerbose())
241         {
242             PacketStreamType log_strm;
243             DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
244             log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
245                          __FUNCTION__,
246                          (uint32_t)src_len,
247                          log_strm.GetData());
248         }
249         m_bytes.append ((const char *)src, src_len);
250     }
251 
252     // Make sure we at least have enough bytes for a packet header
253     const size_t bytes_available = m_bytes.size();
254     if (bytes_available >= 8)
255     {
256         packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
257         uint32_t offset = 0;
258         uint8_t reply_command = packet.GetU8(&offset);
259         switch (reply_command)
260         {
261         case ePacketTypeReply | KDP_CONNECT:
262         case ePacketTypeReply | KDP_DISCONNECT:
263         case ePacketTypeReply | KDP_HOSTINFO:
264         case ePacketTypeReply | KDP_VERSION:
265         case ePacketTypeReply | KDP_MAXBYTES:
266         case ePacketTypeReply | KDP_READMEM:
267         case ePacketTypeReply | KDP_WRITEMEM:
268         case ePacketTypeReply | KDP_READREGS:
269         case ePacketTypeReply | KDP_WRITEREGS:
270         case ePacketTypeReply | KDP_LOAD:
271         case ePacketTypeReply | KDP_IMAGEPATH:
272         case ePacketTypeReply | KDP_SUSPEND:
273         case ePacketTypeReply | KDP_RESUMECPUS:
274         case ePacketTypeReply | KDP_EXCEPTION:
275         case ePacketTypeReply | KDP_TERMINATION:
276         case ePacketTypeReply | KDP_BREAKPOINT_SET:
277         case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
278         case ePacketTypeReply | KDP_REGIONS:
279         case ePacketTypeReply | KDP_REATTACH:
280         case ePacketTypeReply | KDP_HOSTREBOOT:
281         case ePacketTypeReply | KDP_READMEM64:
282         case ePacketTypeReply | KDP_WRITEMEM64:
283         case ePacketTypeReply | KDP_BREAKPOINT_SET64:
284         case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
285         case ePacketTypeReply | KDP_KERNELVERSION:
286             {
287                 offset = 2;
288                 const uint16_t length = packet.GetU16 (&offset);
289                 if (length <= bytes_available)
290                 {
291                     // We have an entire packet ready, we need to copy the data
292                     // bytes into a buffer that will be owned by the packet and
293                     // erase the bytes from our communcation buffer "m_bytes"
294                     packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
295                     m_bytes.erase (0, length);
296 
297                     if (log)
298                     {
299                         PacketStreamType log_strm;
300                         DumpPacket (log_strm, packet);
301 
302                         log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
303                     }
304                     return true;
305                 }
306             }
307             break;
308 
309         default:
310             // Unrecognized reply command byte, erase this byte and try to get back on track
311             if (log)
312                 log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
313                              __FUNCTION__,
314                              (uint8_t)m_bytes[0]);
315             m_bytes.erase(0, 1);
316             break;
317         }
318     }
319     packet.Clear();
320     return false;
321 }
322 
323 
324 bool
325 CommunicationKDP::SendRequestConnect (uint16_t reply_port,
326                                       uint16_t exc_port,
327                                       const char *greeting)
328 {
329     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
330     if (greeting == NULL)
331         greeting = "";
332 
333     const CommandType command = KDP_CONNECT;
334     // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
335     const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
336     const uint32_t request_sequence_id = m_request_sequence_id;
337     MakeRequestPacketHeader (command, request_packet, command_length);
338     // Always send connect ports as little endian
339     request_packet.SetByteOrder (eByteOrderLittle);
340     request_packet.PutHex16 (reply_port);
341     request_packet.PutHex16 (exc_port);
342     request_packet.SetByteOrder (m_byte_order);
343     request_packet.PutCString (greeting);
344     DataExtractor reply_packet;
345     return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet);
346 }
347 
348 void
349 CommunicationKDP::ClearKDPSettings ()
350 {
351     m_request_sequence_id = 0;
352     m_kdp_version_version = 0;
353     m_kdp_version_feature = 0;
354     m_kdp_hostinfo_cpu_mask = 0;
355     m_kdp_hostinfo_cpu_type = 0;
356     m_kdp_hostinfo_cpu_subtype = 0;
357 }
358 
359 bool
360 CommunicationKDP::SendRequestReattach (uint16_t reply_port)
361 {
362     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
363     const CommandType command = KDP_REATTACH;
364     // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
365     const uint32_t command_length = 8 + 2;
366     const uint32_t request_sequence_id = m_request_sequence_id;
367     MakeRequestPacketHeader (command, request_packet, command_length);
368     // Always send connect ports as little endian
369     request_packet.SetByteOrder (eByteOrderLittle);
370     request_packet.PutHex16(reply_port);
371     request_packet.SetByteOrder (m_byte_order);
372     DataExtractor reply_packet;
373     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
374     {
375         // Reset the sequence ID to zero for reattach
376         ClearKDPSettings ();
377         uint32_t offset = 4;
378         m_session_key = reply_packet.GetU32 (&offset);
379         return true;
380     }
381     return false;
382 }
383 
384 uint32_t
385 CommunicationKDP::GetVersion ()
386 {
387     if (!VersionIsValid())
388         SendRequestVersion();
389     return m_kdp_version_version;
390 }
391 
392 uint32_t
393 CommunicationKDP::GetFeatureFlags ()
394 {
395     if (!VersionIsValid())
396         SendRequestVersion();
397     return m_kdp_version_feature;
398 }
399 
400 bool
401 CommunicationKDP::SendRequestVersion ()
402 {
403     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
404     const CommandType command = KDP_VERSION;
405     const uint32_t command_length = 8;
406     const uint32_t request_sequence_id = m_request_sequence_id;
407     MakeRequestPacketHeader (command, request_packet, command_length);
408     DataExtractor reply_packet;
409     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
410     {
411         uint32_t offset = 8;
412         m_kdp_version_version = reply_packet.GetU32 (&offset);
413         m_kdp_version_feature = reply_packet.GetU32 (&offset);
414         return true;
415     }
416     return false;
417 }
418 
419 #if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
420 const char *
421 CommunicationKDP::GetImagePath ()
422 {
423     if (m_image_path.empty())
424         SendRequestImagePath();
425     return m_image_path.c_str();
426 }
427 
428 bool
429 CommunicationKDP::SendRequestImagePath ()
430 {
431     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
432     const CommandType command = KDP_IMAGEPATH;
433     const uint32_t command_length = 8;
434     const uint32_t request_sequence_id = m_request_sequence_id;
435     MakeRequestPacketHeader (command, request_packet, command_length);
436     DataExtractor reply_packet;
437     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
438     {
439         const char *path = reply_packet.PeekCStr(8);
440         if (path && path[0])
441             m_kernel_version.assign (path);
442         return true;
443     }
444     return false;
445 }
446 #endif
447 
448 uint32_t
449 CommunicationKDP::GetCPUMask ()
450 {
451     if (!HostInfoIsValid())
452         SendRequestHostInfo();
453     return m_kdp_hostinfo_cpu_mask;
454 }
455 
456 uint32_t
457 CommunicationKDP::GetCPUType ()
458 {
459     if (!HostInfoIsValid())
460         SendRequestHostInfo();
461     return m_kdp_hostinfo_cpu_type;
462 }
463 
464 uint32_t
465 CommunicationKDP::GetCPUSubtype ()
466 {
467     if (!HostInfoIsValid())
468         SendRequestHostInfo();
469     return m_kdp_hostinfo_cpu_subtype;
470 }
471 
472 bool
473 CommunicationKDP::SendRequestHostInfo ()
474 {
475     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
476     const CommandType command = KDP_HOSTINFO;
477     const uint32_t command_length = 8;
478     const uint32_t request_sequence_id = m_request_sequence_id;
479     MakeRequestPacketHeader (command, request_packet, command_length);
480     DataExtractor reply_packet;
481     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
482     {
483         uint32_t offset = 8;
484         m_kdp_hostinfo_cpu_mask     = reply_packet.GetU32 (&offset);
485         m_kdp_hostinfo_cpu_type     = reply_packet.GetU32 (&offset);
486         m_kdp_hostinfo_cpu_subtype  = reply_packet.GetU32 (&offset);
487 
488         ArchSpec kernel_arch;
489         kernel_arch.SetArchitecture (eArchTypeMachO,
490                                      m_kdp_hostinfo_cpu_type,
491                                      m_kdp_hostinfo_cpu_subtype);
492 
493         m_addr_byte_size = kernel_arch.GetAddressByteSize();
494         m_byte_order = kernel_arch.GetByteOrder();
495         return true;
496     }
497     return false;
498 }
499 
500 const char *
501 CommunicationKDP::GetKernelVersion ()
502 {
503     if (m_kernel_version.empty())
504         SendRequestKernelVersion ();
505     return m_kernel_version.c_str();
506 }
507 
508 bool
509 CommunicationKDP::SendRequestKernelVersion ()
510 {
511     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
512     const CommandType command = KDP_KERNELVERSION;
513     const uint32_t command_length = 8;
514     const uint32_t request_sequence_id = m_request_sequence_id;
515     MakeRequestPacketHeader (command, request_packet, command_length);
516     DataExtractor reply_packet;
517     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
518     {
519         const char *kernel_version_cstr = reply_packet.PeekCStr(8);
520         if (kernel_version_cstr && kernel_version_cstr[0])
521             m_kernel_version.assign (kernel_version_cstr);
522         return true;
523     }
524     return false;
525 }
526 
527 bool
528 CommunicationKDP::SendRequestDisconnect ()
529 {
530     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
531     const CommandType command = KDP_DISCONNECT;
532     const uint32_t command_length = 8;
533     const uint32_t request_sequence_id = m_request_sequence_id;
534     MakeRequestPacketHeader (command, request_packet, command_length);
535     DataExtractor reply_packet;
536     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
537     {
538         // Are we supposed to get a reply for disconnect?
539     }
540     ClearKDPSettings ();
541     return true;
542 }
543 
544 uint32_t
545 CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr,
546                                          void *dst,
547                                          uint32_t dst_len,
548                                          Error &error)
549 {
550     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
551     bool use_64 = (GetVersion() >= 11);
552     uint32_t command_addr_byte_size = use_64 ? 8 : 4;
553     const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
554     // Size is header + address size + uint32_t length
555     const uint32_t command_length = 8 + command_addr_byte_size + 4;
556     const uint32_t request_sequence_id = m_request_sequence_id;
557     MakeRequestPacketHeader (command, request_packet, command_length);
558     request_packet.PutMaxHex64 (addr, command_addr_byte_size);
559     request_packet.PutHex32 (dst_len);
560     DataExtractor reply_packet;
561     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
562     {
563         uint32_t offset = 8;
564         uint32_t kdp_error = reply_packet.GetU32 (&offset);
565         uint32_t src_len = reply_packet.GetByteSize() - 12;
566 
567         if (src_len > 0)
568         {
569             const void *src = reply_packet.GetData(&offset, src_len);
570             if (src)
571             {
572                 ::memcpy (dst, src, src_len);
573                 error.Clear();
574                 return src_len;
575             }
576         }
577         if (kdp_error)
578             error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error);
579         else
580             error.SetErrorString ("kdp read memory failed");
581     }
582     return 0;
583 }
584 
585 
586 uint32_t
587 CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr,
588                                           const void *src,
589                                           uint32_t src_len,
590                                           Error &error)
591 {
592     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
593     bool use_64 = (GetVersion() >= 11);
594     uint32_t command_addr_byte_size = use_64 ? 8 : 4;
595     const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
596     // Size is header + address size + uint32_t length
597     const uint32_t command_length = 8 + command_addr_byte_size + 4;
598     const uint32_t request_sequence_id = m_request_sequence_id;
599     MakeRequestPacketHeader (command, request_packet, command_length);
600     request_packet.PutMaxHex64 (addr, command_addr_byte_size);
601     request_packet.PutHex32 (src_len);
602     request_packet.PutBytesAsRawHex8(src, src_len);
603 
604     DataExtractor reply_packet;
605     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
606     {
607         uint32_t offset = 8;
608         uint32_t kdp_error = reply_packet.GetU32 (&offset);
609         if (kdp_error)
610             error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
611         else
612         {
613             error.Clear();
614             return src_len;
615         }
616     }
617     return 0;
618 }
619 
620 const char *
621 CommunicationKDP::GetCommandAsCString (uint8_t command)
622 {
623     switch (command)
624     {
625     case KDP_CONNECT:               return "KDP_CONNECT";
626     case KDP_DISCONNECT:            return "KDP_DISCONNECT";
627     case KDP_HOSTINFO:              return "KDP_HOSTINFO";
628     case KDP_VERSION:               return "KDP_VERSION";
629     case KDP_MAXBYTES:              return "KDP_MAXBYTES";
630     case KDP_READMEM:               return "KDP_READMEM";
631     case KDP_WRITEMEM:              return "KDP_WRITEMEM";
632     case KDP_READREGS:              return "KDP_READREGS";
633     case KDP_WRITEREGS:             return "KDP_WRITEREGS";
634     case KDP_LOAD:                  return "KDP_LOAD";
635     case KDP_IMAGEPATH:             return "KDP_IMAGEPATH";
636     case KDP_SUSPEND:               return "KDP_SUSPEND";
637     case KDP_RESUMECPUS:            return "KDP_RESUMECPUS";
638     case KDP_EXCEPTION:             return "KDP_EXCEPTION";
639     case KDP_TERMINATION:           return "KDP_TERMINATION";
640     case KDP_BREAKPOINT_SET:        return "KDP_BREAKPOINT_SET";
641     case KDP_BREAKPOINT_REMOVE:     return "KDP_BREAKPOINT_REMOVE";
642     case KDP_REGIONS:               return "KDP_REGIONS";
643     case KDP_REATTACH:              return "KDP_REATTACH";
644     case KDP_HOSTREBOOT:            return "KDP_HOSTREBOOT";
645     case KDP_READMEM64:             return "KDP_READMEM64";
646     case KDP_WRITEMEM64:            return "KDP_WRITEMEM64";
647     case KDP_BREAKPOINT_SET64:      return "KDP_BREAKPOINT64_SET";
648     case KDP_BREAKPOINT_REMOVE64:   return "KDP_BREAKPOINT64_REMOVE";
649     case KDP_KERNELVERSION:         return "KDP_KERNELVERSION";
650     }
651     return NULL;
652 }
653 
654 void
655 CommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len)
656 {
657     DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size);
658     DumpPacket (s, extractor);
659 }
660 
661 void
662 CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet)
663 {
664     const char *error_desc = NULL;
665     if (packet.GetByteSize() < 8)
666     {
667         error_desc = "error: invalid packet (too short): ";
668     }
669     else
670     {
671         uint32_t offset = 0;
672         const uint8_t first_packet_byte = packet.GetU8 (&offset);
673         const uint8_t sequence_id = packet.GetU8 (&offset);
674         const uint16_t length = packet.GetU16 (&offset);
675         const uint32_t key = packet.GetU32 (&offset);
676         const CommandType command = ExtractCommand (first_packet_byte);
677         const char *command_name = GetCommandAsCString (command);
678         if (command_name)
679         {
680             const bool is_reply = ExtractIsReply(first_packet_byte);
681             s.Printf ("%s {%u:%u} <0x%4.4x> %s",
682                       is_reply ? "<--" : "-->",
683                       key,
684                       sequence_id,
685                       length,
686                       command_name);
687 
688             if (is_reply)
689             {
690                 // Dump request reply packets
691                 switch (command)
692                 {
693                     // Commands that return a single 32 bit error
694                     case KDP_CONNECT:
695                     case KDP_WRITEMEM:
696                     case KDP_WRITEMEM64:
697                     case KDP_BREAKPOINT_SET:
698                     case KDP_BREAKPOINT_REMOVE:
699                     case KDP_BREAKPOINT_SET64:
700                     case KDP_BREAKPOINT_REMOVE64:
701                     case KDP_WRITEREGS:
702                     case KDP_LOAD:
703                         {
704                             const uint32_t error = packet.GetU32 (&offset);
705                             s.Printf(" (error=0x%8.8x)", error);
706                         }
707                         break;
708 
709                     case KDP_DISCONNECT:
710                     case KDP_REATTACH:
711                     case KDP_HOSTREBOOT:
712                     case KDP_SUSPEND:
713                     case KDP_RESUMECPUS:
714                     case KDP_EXCEPTION:
715                     case KDP_TERMINATION:
716                         // No return value for the reply, just the header to ack
717                         s.PutCString(" ()");
718                         break;
719 
720                     case KDP_HOSTINFO:
721                         {
722                             const uint32_t cpu_mask = packet.GetU32 (&offset);
723                             const uint32_t cpu_type = packet.GetU32 (&offset);
724                             const uint32_t cpu_subtype = packet.GetU32 (&offset);
725                             s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype);
726                         }
727                         break;
728 
729                     case KDP_VERSION:
730                         {
731                             const uint32_t version = packet.GetU32 (&offset);
732                             const uint32_t feature = packet.GetU32 (&offset);
733                             s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
734                         }
735                         break;
736 
737                     case KDP_REGIONS:
738                         {
739                             const uint32_t region_count = packet.GetU32 (&offset);
740                             s.Printf(" (count = %u", region_count);
741                             for (uint32_t i=0; i<region_count; ++i)
742                             {
743                                 const addr_t region_addr = packet.GetPointer (&offset);
744                                 const uint32_t region_size = packet.GetU32 (&offset);
745                                 const uint32_t region_prot = packet.GetU32 (&offset);
746                                 s.Printf("\n\tregion[%llu] = { range = [0x%16.16llx - 0x%16.16llx), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
747                             }
748                         }
749                         break;
750 
751                     case KDP_READMEM:
752                     case KDP_READMEM64:
753                         {
754                             const uint32_t error = packet.GetU32 (&offset);
755                             const uint32_t count = packet.GetByteSize() - offset;
756                             s.Printf(" (error = 0x%8.8x:\n", error);
757                             if (count > 0)
758                                 packet.Dump (&s,                        // Stream to dump to
759                                              offset,                    // Offset within "packet"
760                                              eFormatBytesWithASCII,     // Format to use
761                                              1,                         // Size of each item in bytes
762                                              count,                     // Number of items
763                                              16,                        // Number per line
764                                              m_last_read_memory_addr,   // Don't show addresses before each line
765                                              0, 0);                     // No bitfields
766                         }
767                         break;
768 
769                     case KDP_READREGS:
770                         {
771                             const uint32_t error = packet.GetU32 (&offset);
772                             const uint32_t count = packet.GetByteSize() - offset;
773                             s.Printf(" (error = 0x%8.8x regs:\n", error);
774                             if (count > 0)
775                                 packet.Dump (&s,                        // Stream to dump to
776                                              offset,                    // Offset within "packet"
777                                              eFormatHex,                // Format to use
778                                              m_addr_byte_size,          // Size of each item in bytes
779                                              count / m_addr_byte_size,  // Number of items
780                                              16 / m_addr_byte_size,     // Number per line
781                                              LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
782                                              0, 0);                     // No bitfields
783                         }
784                         break;
785 
786                     case KDP_KERNELVERSION:
787                         {
788                             const char *kernel_version = packet.PeekCStr(8);
789                             s.Printf(" (version = \"%s\")", kernel_version);
790                         }
791                         break;
792 
793                     case KDP_MAXBYTES:
794                         {
795                             const uint32_t max_bytes = packet.GetU32 (&offset);
796                             s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
797                         }
798                         break;
799                     case KDP_IMAGEPATH:
800                         {
801                             const char *path = packet.GetCStr(&offset);
802                             s.Printf(" (path = \"%s\")", path);
803                         }
804                         break;
805                     default:
806                         s.Printf(" (add support for dumping this packet reply!!!");
807                         break;
808 
809                 }
810             }
811             else
812             {
813                 // Dump request packets
814                 switch (command)
815                 {
816                     case KDP_CONNECT:
817                         {
818                             const uint16_t reply_port = packet.GetU16 (&offset);
819                             const uint16_t exc_port = packet.GetU16 (&offset);
820                             s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset));
821                         }
822                         break;
823 
824                     case KDP_DISCONNECT:
825                     case KDP_HOSTREBOOT:
826                     case KDP_HOSTINFO:
827                     case KDP_VERSION:
828                     case KDP_REGIONS:
829                     case KDP_KERNELVERSION:
830                     case KDP_MAXBYTES:
831                     case KDP_IMAGEPATH:
832                     case KDP_SUSPEND:
833                         // No args, just the header in the request...
834                         s.PutCString(" ()");
835                         break;
836 
837                     case KDP_RESUMECPUS:
838                         {
839                             const uint32_t cpu_mask = packet.GetU32 (&offset);
840                             s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
841                         }
842                         break;
843 
844                     case KDP_READMEM:
845                         {
846                             const uint32_t addr = packet.GetU32 (&offset);
847                             const uint32_t size = packet.GetU32 (&offset);
848                             s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
849                             m_last_read_memory_addr = addr;
850                         }
851                         break;
852 
853                     case KDP_WRITEMEM:
854                         {
855                             const uint32_t addr = packet.GetU32 (&offset);
856                             const uint32_t size = packet.GetU32 (&offset);
857                             s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
858                             if (size > 0)
859                                 DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
860                         }
861                         break;
862 
863                     case KDP_READMEM64:
864                         {
865                             const uint64_t addr = packet.GetU64 (&offset);
866                             const uint32_t size = packet.GetU32 (&offset);
867                             s.Printf(" (addr = 0x%16.16llx, size = %u)", addr, size);
868                             m_last_read_memory_addr = addr;
869                         }
870                         break;
871 
872                     case KDP_WRITEMEM64:
873                         {
874                             const uint64_t addr = packet.GetU64 (&offset);
875                             const uint32_t size = packet.GetU32 (&offset);
876                             s.Printf(" (addr = 0x%16.16llx, size = %u, bytes = \n", addr, size);
877                             if (size > 0)
878                                 DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
879                         }
880                         break;
881 
882                     case KDP_READREGS:
883                         {
884                             const uint32_t cpu = packet.GetU32 (&offset);
885                             const uint32_t flavor = packet.GetU32 (&offset);
886                             s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
887                         }
888                         break;
889 
890                     case KDP_WRITEREGS:
891                         {
892                             const uint32_t cpu = packet.GetU32 (&offset);
893                             const uint32_t flavor = packet.GetU32 (&offset);
894                             const uint32_t nbytes = packet.GetByteSize() - offset;
895                             s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
896                             if (nbytes > 0)
897                                 packet.Dump (&s,                        // Stream to dump to
898                                              offset,                    // Offset within "packet"
899                                              eFormatHex,                // Format to use
900                                              m_addr_byte_size,          // Size of each item in bytes
901                                              nbytes / m_addr_byte_size, // Number of items
902                                              16 / m_addr_byte_size,     // Number per line
903                                              LLDB_INVALID_ADDRESS,      // Don't show addresses before each line
904                                              0, 0);                     // No bitfields
905                         }
906                         break;
907 
908 
909                     case KDP_BREAKPOINT_SET:
910                     case KDP_BREAKPOINT_REMOVE:
911                         {
912                             const uint32_t addr = packet.GetU32 (&offset);
913                             s.Printf(" (addr = 0x%8.8x)", addr);
914                         }
915                         break;
916 
917                     case KDP_BREAKPOINT_SET64:
918                     case KDP_BREAKPOINT_REMOVE64:
919                         {
920                             const uint64_t addr = packet.GetU64 (&offset);
921                             s.Printf(" (addr = 0x%16.16llx)", addr);
922                         }
923                         break;
924 
925 
926                     case KDP_LOAD:
927                         {
928                             const char *path = packet.GetCStr(&offset);
929                             s.Printf(" (path = \"%s\")", path);
930                         }
931                         break;
932 
933                     case KDP_EXCEPTION:
934                         {
935                             const uint32_t count = packet.GetU32 (&offset);
936 
937                             s.Printf(" (count = %u:", count);
938                             for (uint32_t i=0; i<count; ++i)
939                             {
940                                 const uint32_t cpu = packet.GetU32 (&offset);
941                                 const uint32_t exc = packet.GetU32 (&offset);
942                                 const uint32_t code = packet.GetU32 (&offset);
943                                 const uint32_t subcode = packet.GetU32 (&offset);
944                                 const char *exc_cstr = NULL;
945                                 switch (exc)
946                                 {
947                                     case 1:  exc_cstr = "EXC_BAD_ACCESS"; break;
948                                     case 2:  exc_cstr = "EXC_BAD_INSTRUCTION"; break;
949                                     case 3:  exc_cstr = "EXC_ARITHMETIC"; break;
950                                     case 4:  exc_cstr = "EXC_EMULATION"; break;
951                                     case 5:  exc_cstr = "EXC_SOFTWARE"; break;
952                                     case 6:  exc_cstr = "EXC_BREAKPOINT"; break;
953                                     case 7:  exc_cstr = "EXC_SYSCALL"; break;
954                                     case 8:  exc_cstr = "EXC_MACH_SYSCALL"; break;
955                                     case 9:  exc_cstr = "EXC_RPC_ALERT"; break;
956                                     case 10: exc_cstr = "EXC_CRASH"; break;
957                                     default:
958                                         break;
959                                 }
960 
961                                 s.Printf ("\n  cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)\n",
962                                           cpu, exc_cstr, exc, code, code, subcode, subcode);
963                             }
964                         }
965                         break;
966 
967                     case KDP_TERMINATION:
968                         {
969                             const uint32_t term_code = packet.GetU32 (&offset);
970                             const uint32_t exit_code = packet.GetU32 (&offset);
971                             s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code);
972                         }
973                         break;
974 
975                     case KDP_REATTACH:
976                         {
977                             const uint16_t reply_port = packet.GetU16 (&offset);
978                             s.Printf(" (reply_port = %u)", reply_port);
979                         }
980                         break;
981                 }
982             }
983         }
984         else
985         {
986             error_desc = "error: invalid packet command: ";
987         }
988     }
989 
990     if (error_desc)
991     {
992         s.PutCString (error_desc);
993 
994         packet.Dump (&s,                    // Stream to dump to
995                      0,                     // Offset into "packet"
996                      eFormatBytes,          // Dump as hex bytes
997                      1,                     // Size of each item is 1 for single bytes
998                      packet.GetByteSize(),  // Number of bytes
999                      UINT32_MAX,            // Num bytes per line
1000                      LLDB_INVALID_ADDRESS,  // Base address
1001                      0, 0);                 // Bitfield info set to not do anything bitfield related
1002     }
1003 }
1004 
1005 uint32_t
1006 CommunicationKDP::SendRequestReadRegisters (uint32_t cpu,
1007                                             uint32_t flavor,
1008                                             void *dst,
1009                                             uint32_t dst_len,
1010                                             Error &error)
1011 {
1012     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1013     const CommandType command = KDP_READREGS;
1014     // Size is header + 4 byte cpu and 4 byte flavor
1015     const uint32_t command_length = 8 + 4 + 4;
1016     const uint32_t request_sequence_id = m_request_sequence_id;
1017     MakeRequestPacketHeader (command, request_packet, command_length);
1018     request_packet.PutHex32 (cpu);
1019     request_packet.PutHex32 (flavor);
1020     DataExtractor reply_packet;
1021     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
1022     {
1023         uint32_t offset = 8;
1024         uint32_t kdp_error = reply_packet.GetU32 (&offset);
1025         uint32_t src_len = reply_packet.GetByteSize() - 12;
1026 
1027         if (src_len > 0)
1028         {
1029             const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
1030             const void *src = reply_packet.GetData(&offset, bytes_to_copy);
1031             if (src)
1032             {
1033                 ::memcpy (dst, src, bytes_to_copy);
1034                 error.Clear();
1035                 // Return the number of bytes we could have returned regardless if
1036                 // we copied them or not, just so we know when things don't match up
1037                 return src_len;
1038             }
1039         }
1040         if (kdp_error)
1041             error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error);
1042         else
1043             error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
1044     }
1045     return 0;
1046 }
1047 
1048 
1049 bool
1050 CommunicationKDP::SendRequestResume (uint32_t cpu_mask)
1051 {
1052     if (cpu_mask == 0)
1053         cpu_mask = GetCPUMask();
1054     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1055     const CommandType command = KDP_RESUMECPUS;
1056     const uint32_t command_length = 12;
1057     const uint32_t request_sequence_id = m_request_sequence_id;
1058     MakeRequestPacketHeader (command, request_packet, command_length);
1059     request_packet.PutHex32(cpu_mask);
1060 
1061     DataExtractor reply_packet;
1062     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
1063         return true;
1064     return false;
1065 }
1066 
1067 bool
1068 CommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr)
1069 {
1070     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1071     bool use_64 = (GetVersion() >= 11);
1072     uint32_t command_addr_byte_size = use_64 ? 8 : 4;
1073     const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64    : KDP_BREAKPOINT_SET   ):
1074                                       (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
1075 
1076     const uint32_t command_length = 8 + command_addr_byte_size;
1077     const uint32_t request_sequence_id = m_request_sequence_id;
1078     MakeRequestPacketHeader (command, request_packet, command_length);
1079     request_packet.PutMaxHex64 (addr, command_addr_byte_size);
1080 
1081     DataExtractor reply_packet;
1082     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
1083     {
1084         uint32_t offset = 8;
1085         uint32_t kdp_error = reply_packet.GetU32 (&offset);
1086         if (kdp_error == 0)
1087             return true;
1088     }
1089     return false;
1090 }
1091 
1092 bool
1093 CommunicationKDP::SendRequestSuspend ()
1094 {
1095     PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
1096     const CommandType command = KDP_SUSPEND;
1097     const uint32_t command_length = 8;
1098     const uint32_t request_sequence_id = m_request_sequence_id;
1099     MakeRequestPacketHeader (command, request_packet, command_length);
1100     DataExtractor reply_packet;
1101     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
1102         return true;
1103     return false;
1104 }
1105 
1106