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