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