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