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