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