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