1 //===-- CommunicationKDP.cpp ----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CommunicationKDP.h"
15 #include "lldb/Core/DumpDataExtractor.h"
16 #include "lldb/Host/Host.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Utility/DataBufferHeap.h"
19 #include "lldb/Utility/DataExtractor.h"
20 #include "lldb/Utility/FileSpec.h"
21 #include "lldb/Utility/Log.h"
22 #include "lldb/Utility/State.h"
23 #include "lldb/Utility/UUID.h"
25 #include "ProcessKDPLog.h"
28 using namespace lldb_private
;
30 // CommunicationKDP constructor
31 CommunicationKDP::CommunicationKDP(const char *comm_name
)
32 : Communication(), m_addr_byte_size(4),
33 m_byte_order(eByteOrderLittle
), m_packet_timeout(5), m_sequence_mutex(),
34 m_is_running(false), m_session_key(0u), m_request_sequence_id(0u),
35 m_exception_sequence_id(0u), m_kdp_version_version(0u),
36 m_kdp_version_feature(0u), m_kdp_hostinfo_cpu_mask(0u),
37 m_kdp_hostinfo_cpu_type(0u), m_kdp_hostinfo_cpu_subtype(0u) {}
40 CommunicationKDP::~CommunicationKDP() {
46 bool CommunicationKDP::SendRequestPacket(
47 const PacketStreamType
&request_packet
) {
48 std::lock_guard
<std::recursive_mutex
> guard(m_sequence_mutex
);
49 return SendRequestPacketNoLock(request_packet
);
52 void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type
,
53 PacketStreamType
&request_packet
,
54 uint16_t request_length
) {
55 request_packet
.Clear();
56 request_packet
.PutHex8(request_type
|
57 ePacketTypeRequest
); // Set the request type
58 request_packet
.PutHex8(m_request_sequence_id
++); // Sequence number
59 request_packet
.PutHex16(
60 request_length
); // Length of the packet including this header
61 request_packet
.PutHex32(m_session_key
); // Session key
64 bool CommunicationKDP::SendRequestAndGetReply(
65 const CommandType command
, const PacketStreamType
&request_packet
,
66 DataExtractor
&reply_packet
) {
68 Log
*log
= GetLog(KDPLog::Packets
);
70 PacketStreamType log_strm
;
71 DumpPacket(log_strm
, request_packet
.GetData(), request_packet
.GetSize());
72 LLDB_LOGF(log
, "error: kdp running, not sending packet: %.*s",
73 (uint32_t)log_strm
.GetSize(), log_strm
.GetData());
78 std::lock_guard
<std::recursive_mutex
> guard(m_sequence_mutex
);
79 // NOTE: this only works for packets that are in native endian byte order
80 assert(request_packet
.GetSize() ==
81 *((const uint16_t *)(request_packet
.GetData() + 2)));
82 lldb::offset_t offset
= 1;
83 const uint32_t num_retries
= 3;
84 for (uint32_t i
= 0; i
< num_retries
; ++i
) {
85 if (SendRequestPacketNoLock(request_packet
)) {
86 const uint8_t request_sequence_id
= (uint8_t)request_packet
.GetData()[1];
88 if (WaitForPacketWithTimeoutMicroSecondsNoLock(
90 std::chrono::microseconds(GetPacketTimeout()).count())) {
92 const uint8_t reply_command
= reply_packet
.GetU8(&offset
);
93 const uint8_t reply_sequence_id
= reply_packet
.GetU8(&offset
);
94 if (request_sequence_id
== reply_sequence_id
) {
95 // The sequent ID was correct, now verify we got the response we
97 if ((reply_command
& eCommandTypeMask
) == command
) {
99 if (command
== KDP_RESUMECPUS
)
100 m_is_running
.SetValue(true, eBroadcastAlways
);
103 // Failed to get the correct response, bail
104 reply_packet
.Clear();
107 } else if (reply_sequence_id
> request_sequence_id
) {
108 // Sequence ID was greater than the sequence ID of the packet we
109 // sent, something is really wrong...
110 reply_packet
.Clear();
113 // The reply sequence ID was less than our current packet's
114 // sequence ID so we should keep trying to get a response because
115 // this was a response for a previous packet that we must have
119 // Break and retry sending the packet as we didn't get a response due
126 reply_packet
.Clear();
130 bool CommunicationKDP::SendRequestPacketNoLock(
131 const PacketStreamType
&request_packet
) {
133 const char *packet_data
= request_packet
.GetData();
134 const size_t packet_size
= request_packet
.GetSize();
136 Log
*log
= GetLog(KDPLog::Packets
);
138 PacketStreamType log_strm
;
139 DumpPacket(log_strm
, packet_data
, packet_size
);
140 LLDB_LOGF(log
, "%.*s", (uint32_t)log_strm
.GetSize(), log_strm
.GetData());
142 ConnectionStatus status
= eConnectionStatusSuccess
;
144 size_t bytes_written
= Write(packet_data
, packet_size
, status
, NULL
);
146 if (bytes_written
== packet_size
)
150 "error: failed to send packet entire packet %" PRIu64
151 " of %" PRIu64
" bytes sent",
152 (uint64_t)bytes_written
, (uint64_t)packet_size
);
157 bool CommunicationKDP::GetSequenceMutex(
158 std::unique_lock
<std::recursive_mutex
> &lock
) {
159 return (lock
= std::unique_lock
<std::recursive_mutex
>(m_sequence_mutex
,
164 bool CommunicationKDP::WaitForNotRunningPrivate(
165 const std::chrono::microseconds
&timeout
) {
166 return m_is_running
.WaitForValueEqualTo(false, timeout
);
170 CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds(DataExtractor
&packet
,
171 uint32_t timeout_usec
) {
172 std::lock_guard
<std::recursive_mutex
> guard(m_sequence_mutex
);
173 return WaitForPacketWithTimeoutMicroSecondsNoLock(packet
, timeout_usec
);
176 size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock(
177 DataExtractor
&packet
, uint32_t timeout_usec
) {
178 uint8_t buffer
[8192];
181 Log
*log
= GetLog(KDPLog::Packets
);
183 // Check for a packet from our cache first without trying any reading...
184 if (CheckForPacket(NULL
, 0, packet
))
185 return packet
.GetByteSize();
187 bool timed_out
= false;
188 while (IsConnected() && !timed_out
) {
189 lldb::ConnectionStatus status
= eConnectionStatusNoConnection
;
190 size_t bytes_read
= Read(buffer
, sizeof(buffer
),
191 timeout_usec
== UINT32_MAX
192 ? Timeout
<std::micro
>(std::nullopt
)
193 : std::chrono::microseconds(timeout_usec
),
197 "Read (buffer, sizeof(buffer), timeout_usec = 0x{0:x}, "
198 "status = {1}, error = {2}) => bytes_read = {4}",
199 timeout_usec
, Communication::ConnectionStatusAsString(status
),
202 if (bytes_read
> 0) {
203 if (CheckForPacket(buffer
, bytes_read
, packet
))
204 return packet
.GetByteSize();
207 case eConnectionStatusInterrupted
:
208 case eConnectionStatusTimedOut
:
211 case eConnectionStatusSuccess
:
212 // printf ("status = success but error = %s\n",
213 // error.AsCString("<invalid>"));
216 case eConnectionStatusEndOfFile
:
217 case eConnectionStatusNoConnection
:
218 case eConnectionStatusLostConnection
:
219 case eConnectionStatusError
:
229 bool CommunicationKDP::CheckForPacket(const uint8_t *src
, size_t src_len
,
230 DataExtractor
&packet
) {
231 // Put the packet data into the buffer in a thread safe fashion
232 std::lock_guard
<std::recursive_mutex
> guard(m_bytes_mutex
);
234 Log
*log
= GetLog(KDPLog::Packets
);
236 if (src
&& src_len
> 0) {
237 if (log
&& log
->GetVerbose()) {
238 PacketStreamType log_strm
;
239 DumpHexBytes(&log_strm
, src
, src_len
, UINT32_MAX
, LLDB_INVALID_ADDRESS
);
240 log_strm
.PutChar('\0');
241 LLDB_LOGF(log
, "CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__
,
242 (uint32_t)src_len
, log_strm
.GetData());
244 m_bytes
.append((const char *)src
, src_len
);
247 // Make sure we at least have enough bytes for a packet header
248 const size_t bytes_available
= m_bytes
.size();
249 if (bytes_available
>= 8) {
250 packet
.SetData(&m_bytes
[0], bytes_available
, m_byte_order
);
251 lldb::offset_t offset
= 0;
252 uint8_t reply_command
= packet
.GetU8(&offset
);
253 switch (reply_command
) {
254 case ePacketTypeRequest
| KDP_EXCEPTION
:
255 case ePacketTypeRequest
| KDP_TERMINATION
:
256 // We got an exception request, so be sure to send an ACK
258 PacketStreamType
request_ack_packet(Stream::eBinary
, m_addr_byte_size
,
260 // Set the reply but and make the ACK packet
261 request_ack_packet
.PutHex8(reply_command
| ePacketTypeReply
);
262 request_ack_packet
.PutHex8(packet
.GetU8(&offset
));
263 request_ack_packet
.PutHex16(packet
.GetU16(&offset
));
264 request_ack_packet
.PutHex32(packet
.GetU32(&offset
));
265 m_is_running
.SetValue(false, eBroadcastAlways
);
266 // Ack to the exception or termination
267 SendRequestPacketNoLock(request_ack_packet
);
269 // Fall through to case below to get packet contents
271 case ePacketTypeReply
| KDP_CONNECT
:
272 case ePacketTypeReply
| KDP_DISCONNECT
:
273 case ePacketTypeReply
| KDP_HOSTINFO
:
274 case ePacketTypeReply
| KDP_VERSION
:
275 case ePacketTypeReply
| KDP_MAXBYTES
:
276 case ePacketTypeReply
| KDP_READMEM
:
277 case ePacketTypeReply
| KDP_WRITEMEM
:
278 case ePacketTypeReply
| KDP_READREGS
:
279 case ePacketTypeReply
| KDP_WRITEREGS
:
280 case ePacketTypeReply
| KDP_LOAD
:
281 case ePacketTypeReply
| KDP_IMAGEPATH
:
282 case ePacketTypeReply
| KDP_SUSPEND
:
283 case ePacketTypeReply
| KDP_RESUMECPUS
:
284 case ePacketTypeReply
| KDP_BREAKPOINT_SET
:
285 case ePacketTypeReply
| KDP_BREAKPOINT_REMOVE
:
286 case ePacketTypeReply
| KDP_REGIONS
:
287 case ePacketTypeReply
| KDP_REATTACH
:
288 case ePacketTypeReply
| KDP_HOSTREBOOT
:
289 case ePacketTypeReply
| KDP_READMEM64
:
290 case ePacketTypeReply
| KDP_WRITEMEM64
:
291 case ePacketTypeReply
| KDP_BREAKPOINT_SET64
:
292 case ePacketTypeReply
| KDP_BREAKPOINT_REMOVE64
:
293 case ePacketTypeReply
| KDP_KERNELVERSION
:
294 case ePacketTypeReply
| KDP_READPHYSMEM64
:
295 case ePacketTypeReply
| KDP_WRITEPHYSMEM64
:
296 case ePacketTypeReply
| KDP_READIOPORT
:
297 case ePacketTypeReply
| KDP_WRITEIOPORT
:
298 case ePacketTypeReply
| KDP_READMSR64
:
299 case ePacketTypeReply
| KDP_WRITEMSR64
:
300 case ePacketTypeReply
| KDP_DUMPINFO
: {
302 const uint16_t length
= packet
.GetU16(&offset
);
303 if (length
<= bytes_available
) {
304 // We have an entire packet ready, we need to copy the data bytes into
305 // a buffer that will be owned by the packet and erase the bytes from
306 // our communication buffer "m_bytes"
307 packet
.SetData(DataBufferSP(new DataBufferHeap(&m_bytes
[0], length
)));
308 m_bytes
.erase(0, length
);
311 PacketStreamType log_strm
;
312 DumpPacket(log_strm
, packet
);
314 LLDB_LOGF(log
, "%.*s", (uint32_t)log_strm
.GetSize(),
322 // Unrecognized reply command byte, erase this byte and try to get back
324 LLDB_LOGF(log
, "CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
325 __FUNCTION__
, (uint8_t)m_bytes
[0]);
334 bool CommunicationKDP::SendRequestConnect(uint16_t reply_port
,
336 const char *greeting
) {
337 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
339 if (greeting
== NULL
)
342 const CommandType command
= KDP_CONNECT
;
343 // Length is 82 uint16_t and the length of the greeting C string with the
345 const uint32_t command_length
= 8 + 2 + 2 + ::strlen(greeting
) + 1;
346 MakeRequestPacketHeader(command
, request_packet
, command_length
);
347 // Always send connect ports as little endian
348 request_packet
.SetByteOrder(eByteOrderLittle
);
349 request_packet
.PutHex16(htons(reply_port
));
350 request_packet
.PutHex16(htons(exc_port
));
351 request_packet
.SetByteOrder(m_byte_order
);
352 request_packet
.PutCString(greeting
);
353 DataExtractor reply_packet
;
354 return SendRequestAndGetReply(command
, request_packet
, reply_packet
);
357 void CommunicationKDP::ClearKDPSettings() {
358 m_request_sequence_id
= 0;
359 m_kdp_version_version
= 0;
360 m_kdp_version_feature
= 0;
361 m_kdp_hostinfo_cpu_mask
= 0;
362 m_kdp_hostinfo_cpu_type
= 0;
363 m_kdp_hostinfo_cpu_subtype
= 0;
366 bool CommunicationKDP::SendRequestReattach(uint16_t reply_port
) {
367 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
369 const CommandType command
= KDP_REATTACH
;
370 // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
371 const uint32_t command_length
= 8 + 2;
372 MakeRequestPacketHeader(command
, request_packet
, command_length
);
373 // Always send connect ports as little endian
374 request_packet
.SetByteOrder(eByteOrderLittle
);
375 request_packet
.PutHex16(htons(reply_port
));
376 request_packet
.SetByteOrder(m_byte_order
);
377 DataExtractor reply_packet
;
378 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
379 // Reset the sequence ID to zero for reattach
381 lldb::offset_t offset
= 4;
382 m_session_key
= reply_packet
.GetU32(&offset
);
388 uint32_t CommunicationKDP::GetVersion() {
389 if (!VersionIsValid())
390 SendRequestVersion();
391 return m_kdp_version_version
;
394 uint32_t CommunicationKDP::GetFeatureFlags() {
395 if (!VersionIsValid())
396 SendRequestVersion();
397 return m_kdp_version_feature
;
400 bool CommunicationKDP::SendRequestVersion() {
401 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
403 const CommandType command
= KDP_VERSION
;
404 const uint32_t command_length
= 8;
405 MakeRequestPacketHeader(command
, request_packet
, command_length
);
406 DataExtractor reply_packet
;
407 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
408 lldb::offset_t offset
= 8;
409 m_kdp_version_version
= reply_packet
.GetU32(&offset
);
410 m_kdp_version_feature
= reply_packet
.GetU32(&offset
);
416 uint32_t CommunicationKDP::GetCPUMask() {
417 if (!HostInfoIsValid())
418 SendRequestHostInfo();
419 return m_kdp_hostinfo_cpu_mask
;
422 uint32_t CommunicationKDP::GetCPUType() {
423 if (!HostInfoIsValid())
424 SendRequestHostInfo();
425 return m_kdp_hostinfo_cpu_type
;
428 uint32_t CommunicationKDP::GetCPUSubtype() {
429 if (!HostInfoIsValid())
430 SendRequestHostInfo();
431 return m_kdp_hostinfo_cpu_subtype
;
434 lldb_private::UUID
CommunicationKDP::GetUUID() {
436 if (GetKernelVersion() == NULL
)
439 if (m_kernel_version
.find("UUID=") == std::string::npos
)
442 size_t p
= m_kernel_version
.find("UUID=") + strlen("UUID=");
443 std::string uuid_str
= m_kernel_version
.substr(p
, 36);
444 if (uuid_str
.size() < 32)
447 if (!uuid
.SetFromStringRef(uuid_str
)) {
455 bool CommunicationKDP::RemoteIsEFI() {
456 if (GetKernelVersion() == NULL
)
458 return strncmp(m_kernel_version
.c_str(), "EFI", 3) == 0;
461 bool CommunicationKDP::RemoteIsDarwinKernel() {
462 if (GetKernelVersion() == NULL
)
464 return m_kernel_version
.find("Darwin Kernel") != std::string::npos
;
467 lldb::addr_t
CommunicationKDP::GetLoadAddress() {
468 if (GetKernelVersion() == NULL
)
469 return LLDB_INVALID_ADDRESS
;
471 if (m_kernel_version
.find("stext=") == std::string::npos
)
472 return LLDB_INVALID_ADDRESS
;
473 size_t p
= m_kernel_version
.find("stext=") + strlen("stext=");
474 if (m_kernel_version
[p
] != '0' || m_kernel_version
[p
+ 1] != 'x')
475 return LLDB_INVALID_ADDRESS
;
477 addr_t kernel_load_address
;
479 kernel_load_address
= ::strtoul(m_kernel_version
.c_str() + p
, NULL
, 16);
480 if (errno
!= 0 || kernel_load_address
== 0)
481 return LLDB_INVALID_ADDRESS
;
483 return kernel_load_address
;
486 bool CommunicationKDP::SendRequestHostInfo() {
487 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
489 const CommandType command
= KDP_HOSTINFO
;
490 const uint32_t command_length
= 8;
491 MakeRequestPacketHeader(command
, request_packet
, command_length
);
492 DataExtractor reply_packet
;
493 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
494 lldb::offset_t offset
= 8;
495 m_kdp_hostinfo_cpu_mask
= reply_packet
.GetU32(&offset
);
496 m_kdp_hostinfo_cpu_type
= reply_packet
.GetU32(&offset
);
497 m_kdp_hostinfo_cpu_subtype
= reply_packet
.GetU32(&offset
);
499 ArchSpec kernel_arch
;
500 kernel_arch
.SetArchitecture(eArchTypeMachO
, m_kdp_hostinfo_cpu_type
,
501 m_kdp_hostinfo_cpu_subtype
);
503 m_addr_byte_size
= kernel_arch
.GetAddressByteSize();
504 m_byte_order
= kernel_arch
.GetByteOrder();
510 const char *CommunicationKDP::GetKernelVersion() {
511 if (m_kernel_version
.empty())
512 SendRequestKernelVersion();
513 return m_kernel_version
.c_str();
516 bool CommunicationKDP::SendRequestKernelVersion() {
517 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
519 const CommandType command
= KDP_KERNELVERSION
;
520 const uint32_t command_length
= 8;
521 MakeRequestPacketHeader(command
, request_packet
, command_length
);
522 DataExtractor reply_packet
;
523 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
524 const char *kernel_version_cstr
= reply_packet
.PeekCStr(8);
525 if (kernel_version_cstr
&& kernel_version_cstr
[0])
526 m_kernel_version
.assign(kernel_version_cstr
);
532 bool CommunicationKDP::SendRequestDisconnect() {
533 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
535 const CommandType command
= KDP_DISCONNECT
;
536 const uint32_t command_length
= 8;
537 MakeRequestPacketHeader(command
, request_packet
, command_length
);
538 DataExtractor reply_packet
;
539 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
540 // Are we supposed to get a reply for disconnect?
546 uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr
, void *dst
,
549 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
551 bool use_64
= (GetVersion() >= 11);
552 uint32_t command_addr_byte_size
= use_64
? 8 : 4;
553 const CommandType command
= use_64
? KDP_READMEM64
: KDP_READMEM
;
554 // Size is header + address size + uint32_t length
555 const uint32_t command_length
= 8 + command_addr_byte_size
+ 4;
556 MakeRequestPacketHeader(command
, request_packet
, command_length
);
557 request_packet
.PutMaxHex64(addr
, command_addr_byte_size
);
558 request_packet
.PutHex32(dst_len
);
559 DataExtractor reply_packet
;
560 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
561 lldb::offset_t offset
= 8;
562 uint32_t kdp_error
= reply_packet
.GetU32(&offset
);
563 uint32_t src_len
= reply_packet
.GetByteSize() - 12;
566 const void *src
= reply_packet
.GetData(&offset
, src_len
);
568 ::memcpy(dst
, src
, src_len
);
574 error
.SetErrorStringWithFormat("kdp read memory failed (error %u)",
577 error
.SetErrorString("kdp read memory failed");
579 error
.SetErrorString("failed to send packet");
584 uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr
,
588 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
590 bool use_64
= (GetVersion() >= 11);
591 uint32_t command_addr_byte_size
= use_64
? 8 : 4;
592 const CommandType command
= use_64
? KDP_WRITEMEM64
: KDP_WRITEMEM
;
593 // Size is header + address size + uint32_t length
594 const uint32_t command_length
= 8 + command_addr_byte_size
+ 4 + src_len
;
595 MakeRequestPacketHeader(command
, request_packet
, command_length
);
596 request_packet
.PutMaxHex64(addr
, command_addr_byte_size
);
597 request_packet
.PutHex32(src_len
);
598 request_packet
.PutRawBytes(src
, src_len
);
600 DataExtractor reply_packet
;
601 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
602 lldb::offset_t offset
= 8;
603 uint32_t kdp_error
= reply_packet
.GetU32(&offset
);
605 error
.SetErrorStringWithFormat("kdp write memory failed (error %u)",
612 error
.SetErrorString("failed to send packet");
617 bool CommunicationKDP::SendRawRequest(
618 uint8_t command_byte
,
619 const void *src
, // Raw packet payload bytes
620 uint32_t src_len
, // Raw packet payload length
621 DataExtractor
&reply_packet
, Status
&error
) {
622 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
624 // Size is header + address size + uint32_t length
625 const uint32_t command_length
= 8 + src_len
;
626 const CommandType command
= (CommandType
)command_byte
;
627 MakeRequestPacketHeader(command
, request_packet
, command_length
);
628 request_packet
.PutRawBytes(src
, src_len
);
630 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
631 lldb::offset_t offset
= 8;
632 uint32_t kdp_error
= reply_packet
.GetU32(&offset
);
633 if (kdp_error
&& (command_byte
!= KDP_DUMPINFO
))
634 error
.SetErrorStringWithFormat("request packet 0x%8.8x failed (error %u)",
635 command_byte
, kdp_error
);
641 error
.SetErrorString("failed to send packet");
646 const char *CommunicationKDP::GetCommandAsCString(uint8_t command
) {
649 return "KDP_CONNECT";
651 return "KDP_DISCONNECT";
653 return "KDP_HOSTINFO";
655 return "KDP_VERSION";
657 return "KDP_MAXBYTES";
659 return "KDP_READMEM";
661 return "KDP_WRITEMEM";
663 return "KDP_READREGS";
665 return "KDP_WRITEREGS";
669 return "KDP_IMAGEPATH";
671 return "KDP_SUSPEND";
673 return "KDP_RESUMECPUS";
675 return "KDP_EXCEPTION";
676 case KDP_TERMINATION
:
677 return "KDP_TERMINATION";
678 case KDP_BREAKPOINT_SET
:
679 return "KDP_BREAKPOINT_SET";
680 case KDP_BREAKPOINT_REMOVE
:
681 return "KDP_BREAKPOINT_REMOVE";
683 return "KDP_REGIONS";
685 return "KDP_REATTACH";
687 return "KDP_HOSTREBOOT";
689 return "KDP_READMEM64";
691 return "KDP_WRITEMEM64";
692 case KDP_BREAKPOINT_SET64
:
693 return "KDP_BREAKPOINT64_SET";
694 case KDP_BREAKPOINT_REMOVE64
:
695 return "KDP_BREAKPOINT64_REMOVE";
696 case KDP_KERNELVERSION
:
697 return "KDP_KERNELVERSION";
698 case KDP_READPHYSMEM64
:
699 return "KDP_READPHYSMEM64";
700 case KDP_WRITEPHYSMEM64
:
701 return "KDP_WRITEPHYSMEM64";
703 return "KDP_READIOPORT";
704 case KDP_WRITEIOPORT
:
705 return "KDP_WRITEIOPORT";
707 return "KDP_READMSR64";
709 return "KDP_WRITEMSR64";
711 return "KDP_DUMPINFO";
716 void CommunicationKDP::DumpPacket(Stream
&s
, const void *data
,
718 DataExtractor
extractor(data
, data_len
, m_byte_order
, m_addr_byte_size
);
719 DumpPacket(s
, extractor
);
722 void CommunicationKDP::DumpPacket(Stream
&s
, const DataExtractor
&packet
) {
723 const char *error_desc
= NULL
;
724 if (packet
.GetByteSize() < 8) {
725 error_desc
= "error: invalid packet (too short): ";
727 lldb::offset_t offset
= 0;
728 const uint8_t first_packet_byte
= packet
.GetU8(&offset
);
729 const uint8_t sequence_id
= packet
.GetU8(&offset
);
730 const uint16_t length
= packet
.GetU16(&offset
);
731 const uint32_t key
= packet
.GetU32(&offset
);
732 const CommandType command
= ExtractCommand(first_packet_byte
);
733 const char *command_name
= GetCommandAsCString(command
);
735 const bool is_reply
= ExtractIsReply(first_packet_byte
);
736 s
.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
737 IsRunning(), is_reply
? "<--" : "-->", command_name
,
738 first_packet_byte
, sequence_id
, length
, key
);
741 // Dump request reply packets
743 // Commands that return a single 32 bit error
747 case KDP_BREAKPOINT_SET
:
748 case KDP_BREAKPOINT_REMOVE
:
749 case KDP_BREAKPOINT_SET64
:
750 case KDP_BREAKPOINT_REMOVE64
:
753 case KDP_WRITEIOPORT
:
754 case KDP_WRITEMSR64
: {
755 const uint32_t error
= packet
.GetU32(&offset
);
756 s
.Printf(" (error=0x%8.8x)", error
);
765 case KDP_TERMINATION
:
766 // No return value for the reply, just the header to ack
771 const uint32_t cpu_mask
= packet
.GetU32(&offset
);
772 const uint32_t cpu_type
= packet
.GetU32(&offset
);
773 const uint32_t cpu_subtype
= packet
.GetU32(&offset
);
774 s
.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)",
775 cpu_mask
, cpu_type
, cpu_subtype
);
779 const uint32_t version
= packet
.GetU32(&offset
);
780 const uint32_t feature
= packet
.GetU32(&offset
);
781 s
.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version
, feature
);
785 const uint32_t region_count
= packet
.GetU32(&offset
);
786 s
.Printf(" (count = %u", region_count
);
787 for (uint32_t i
= 0; i
< region_count
; ++i
) {
788 const addr_t region_addr
= packet
.GetAddress(&offset
);
789 const uint32_t region_size
= packet
.GetU32(&offset
);
790 const uint32_t region_prot
= packet
.GetU32(&offset
);
791 s
.Printf("\n\tregion[%" PRIu64
"] = { range = [0x%16.16" PRIx64
792 " - 0x%16.16" PRIx64
"), size = 0x%8.8x, prot = %s }",
793 region_addr
, region_addr
, region_addr
+ region_size
,
794 region_size
, GetPermissionsAsCString(region_prot
));
800 case KDP_READPHYSMEM64
: {
801 const uint32_t error
= packet
.GetU32(&offset
);
802 const uint32_t count
= packet
.GetByteSize() - offset
;
803 s
.Printf(" (error = 0x%8.8x:\n", error
);
805 DumpDataExtractor(packet
,
806 &s
, // Stream to dump to
807 offset
, // Offset within "packet"
808 eFormatBytesWithASCII
, // Format to use
809 1, // Size of each item
811 count
, // Number of items
812 16, // Number per line
813 m_last_read_memory_addr
, // Don't show addresses
815 0, 0); // No bitfields
819 const uint32_t error
= packet
.GetU32(&offset
);
820 const uint32_t count
= packet
.GetByteSize() - offset
;
821 s
.Printf(" (error = 0x%8.8x regs:\n", error
);
823 DumpDataExtractor(packet
,
824 &s
, // Stream to dump to
825 offset
, // Offset within "packet"
826 eFormatHex
, // Format to use
827 m_addr_byte_size
, // Size of each item
829 count
/ m_addr_byte_size
, // Number of items
830 16 / m_addr_byte_size
, // Number per line
831 LLDB_INVALID_ADDRESS
,
833 // show addresses before
835 0, 0); // No bitfields
838 case KDP_KERNELVERSION
: {
839 const char *kernel_version
= packet
.PeekCStr(8);
840 s
.Printf(" (version = \"%s\")", kernel_version
);
844 const uint32_t max_bytes
= packet
.GetU32(&offset
);
845 s
.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes
, max_bytes
);
847 case KDP_IMAGEPATH
: {
848 const char *path
= packet
.GetCStr(&offset
);
849 s
.Printf(" (path = \"%s\")", path
);
853 case KDP_READMSR64
: {
854 const uint32_t error
= packet
.GetU32(&offset
);
855 const uint32_t count
= packet
.GetByteSize() - offset
;
856 s
.Printf(" (error = 0x%8.8x io:\n", error
);
858 DumpDataExtractor(packet
,
859 &s
, // Stream to dump to
860 offset
, // Offset within "packet"
861 eFormatHex
, // Format to use
862 1, // Size of each item in bytes
863 count
, // Number of items
864 16, // Number per line
865 LLDB_INVALID_ADDRESS
, // Don't show addresses
867 0, 0); // No bitfields
870 const uint32_t count
= packet
.GetByteSize() - offset
;
871 s
.Printf(" (count = %u, bytes = \n", count
);
873 DumpDataExtractor(packet
,
874 &s
, // Stream to dump to
875 offset
, // Offset within "packet"
876 eFormatHex
, // Format to use
877 1, // Size of each item in
879 count
, // Number of items
880 16, // Number per line
881 LLDB_INVALID_ADDRESS
, // Don't show addresses
883 0, 0); // No bitfields
888 s
.Printf(" (add support for dumping this packet reply!!!");
892 // Dump request packets
895 const uint16_t reply_port
= ntohs(packet
.GetU16(&offset
));
896 const uint16_t exc_port
= ntohs(packet
.GetU16(&offset
));
897 s
.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")",
898 reply_port
, exc_port
, packet
.GetCStr(&offset
));
906 case KDP_KERNELVERSION
:
910 // No args, just the header in the request...
914 case KDP_RESUMECPUS
: {
915 const uint32_t cpu_mask
= packet
.GetU32(&offset
);
916 s
.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask
);
920 const uint32_t addr
= packet
.GetU32(&offset
);
921 const uint32_t size
= packet
.GetU32(&offset
);
922 s
.Printf(" (addr = 0x%8.8x, size = %u)", addr
, size
);
923 m_last_read_memory_addr
= addr
;
927 const uint32_t addr
= packet
.GetU32(&offset
);
928 const uint32_t size
= packet
.GetU32(&offset
);
929 s
.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr
, size
);
931 DumpHexBytes(&s
, packet
.GetData(&offset
, size
), size
, 32, addr
);
934 case KDP_READMEM64
: {
935 const uint64_t addr
= packet
.GetU64(&offset
);
936 const uint32_t size
= packet
.GetU32(&offset
);
937 s
.Printf(" (addr = 0x%16.16" PRIx64
", size = %u)", addr
, size
);
938 m_last_read_memory_addr
= addr
;
941 case KDP_READPHYSMEM64
: {
942 const uint64_t addr
= packet
.GetU64(&offset
);
943 const uint32_t size
= packet
.GetU32(&offset
);
944 const uint32_t lcpu
= packet
.GetU16(&offset
);
945 s
.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr
, size
,
947 m_last_read_memory_addr
= addr
;
950 case KDP_WRITEMEM64
: {
951 const uint64_t addr
= packet
.GetU64(&offset
);
952 const uint32_t size
= packet
.GetU32(&offset
);
953 s
.Printf(" (addr = 0x%16.16" PRIx64
", size = %u, bytes = \n", addr
,
956 DumpHexBytes(&s
, packet
.GetData(&offset
, size
), size
, 32, addr
);
959 case KDP_WRITEPHYSMEM64
: {
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, bytes = \n",
966 DumpHexBytes(&s
, packet
.GetData(&offset
, size
), size
, 32, addr
);
970 const uint32_t cpu
= packet
.GetU32(&offset
);
971 const uint32_t flavor
= packet
.GetU32(&offset
);
972 s
.Printf(" (cpu = %u, flavor = %u)", cpu
, flavor
);
975 case KDP_WRITEREGS
: {
976 const uint32_t cpu
= packet
.GetU32(&offset
);
977 const uint32_t flavor
= packet
.GetU32(&offset
);
978 const uint32_t nbytes
= packet
.GetByteSize() - offset
;
979 s
.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu
, flavor
);
981 DumpDataExtractor(packet
,
982 &s
, // Stream to dump to
983 offset
, // Offset within
985 eFormatHex
, // Format to use
986 m_addr_byte_size
, // Size of each item in
988 nbytes
/ m_addr_byte_size
, // Number of items
989 16 / m_addr_byte_size
, // Number per line
990 LLDB_INVALID_ADDRESS
, // Don't show addresses
992 0, 0); // No bitfields
995 case KDP_BREAKPOINT_SET
:
996 case KDP_BREAKPOINT_REMOVE
: {
997 const uint32_t addr
= packet
.GetU32(&offset
);
998 s
.Printf(" (addr = 0x%8.8x)", addr
);
1001 case KDP_BREAKPOINT_SET64
:
1002 case KDP_BREAKPOINT_REMOVE64
: {
1003 const uint64_t addr
= packet
.GetU64(&offset
);
1004 s
.Printf(" (addr = 0x%16.16" PRIx64
")", addr
);
1008 const char *path
= packet
.GetCStr(&offset
);
1009 s
.Printf(" (path = \"%s\")", path
);
1012 case KDP_EXCEPTION
: {
1013 const uint32_t count
= packet
.GetU32(&offset
);
1015 for (uint32_t i
= 0; i
< count
; ++i
) {
1016 const uint32_t cpu
= packet
.GetU32(&offset
);
1017 const uint32_t exc
= packet
.GetU32(&offset
);
1018 const uint32_t code
= packet
.GetU32(&offset
);
1019 const uint32_t subcode
= packet
.GetU32(&offset
);
1020 const char *exc_cstr
= NULL
;
1023 exc_cstr
= "EXC_BAD_ACCESS";
1026 exc_cstr
= "EXC_BAD_INSTRUCTION";
1029 exc_cstr
= "EXC_ARITHMETIC";
1032 exc_cstr
= "EXC_EMULATION";
1035 exc_cstr
= "EXC_SOFTWARE";
1038 exc_cstr
= "EXC_BREAKPOINT";
1041 exc_cstr
= "EXC_SYSCALL";
1044 exc_cstr
= "EXC_MACH_SYSCALL";
1047 exc_cstr
= "EXC_RPC_ALERT";
1050 exc_cstr
= "EXC_CRASH";
1056 s
.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), "
1057 "subcode = %u (0x%8.8x)} ",
1058 cpu
, exc_cstr
, exc
, code
, code
, subcode
, subcode
);
1062 case KDP_TERMINATION
: {
1063 const uint32_t term_code
= packet
.GetU32(&offset
);
1064 const uint32_t exit_code
= packet
.GetU32(&offset
);
1065 s
.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))",
1066 term_code
, term_code
, exit_code
, exit_code
);
1069 case KDP_REATTACH
: {
1070 const uint16_t reply_port
= ntohs(packet
.GetU16(&offset
));
1071 s
.Printf(" (reply_port = %u)", reply_port
);
1074 case KDP_READMSR64
: {
1075 const uint32_t address
= packet
.GetU32(&offset
);
1076 const uint16_t lcpu
= packet
.GetU16(&offset
);
1077 s
.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address
, lcpu
);
1080 case KDP_WRITEMSR64
: {
1081 const uint32_t address
= packet
.GetU32(&offset
);
1082 const uint16_t lcpu
= packet
.GetU16(&offset
);
1083 const uint32_t nbytes
= packet
.GetByteSize() - offset
;
1084 s
.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu
,
1087 DumpDataExtractor(packet
,
1088 &s
, // Stream to dump to
1089 offset
, // Offset within "packet"
1090 eFormatHex
, // Format to use
1091 1, // Size of each item in
1093 nbytes
, // Number of items
1094 16, // Number per line
1095 LLDB_INVALID_ADDRESS
, // Don't show addresses
1097 0, 0); // No bitfields
1100 case KDP_READIOPORT
: {
1101 const uint16_t lcpu
= packet
.GetU16(&offset
);
1102 const uint16_t address
= packet
.GetU16(&offset
);
1103 const uint16_t nbytes
= packet
.GetU16(&offset
);
1104 s
.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu
, address
,
1108 case KDP_WRITEIOPORT
: {
1109 const uint16_t lcpu
= packet
.GetU16(&offset
);
1110 const uint16_t address
= packet
.GetU16(&offset
);
1111 const uint16_t nbytes
= packet
.GetU16(&offset
);
1112 s
.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu
,
1115 DumpDataExtractor(packet
,
1116 &s
, // Stream to dump to
1117 offset
, // Offset within "packet"
1118 eFormatHex
, // Format to use
1119 1, // Size of each item in
1121 nbytes
, // Number of items
1122 16, // Number per line
1123 LLDB_INVALID_ADDRESS
, // Don't show addresses
1125 0, 0); // No bitfields
1128 case KDP_DUMPINFO
: {
1129 const uint32_t count
= packet
.GetByteSize() - offset
;
1130 s
.Printf(" (count = %u, bytes = \n", count
);
1132 DumpDataExtractor(packet
,
1133 &s
, // Stream to dump to
1134 offset
, // Offset within "packet"
1135 eFormatHex
, // Format to use
1136 1, // Size of each item in bytes
1137 count
, // Number of items
1138 16, // Number per line
1139 LLDB_INVALID_ADDRESS
, // Don't show addresses before each line
1140 0, 0); // No bitfields
1146 error_desc
= "error: invalid packet command: ";
1151 s
.PutCString(error_desc
);
1153 DumpDataExtractor(packet
,
1154 &s
, // Stream to dump to
1155 0, // Offset into "packet"
1156 eFormatBytes
, // Dump as hex bytes
1157 1, // Size of each item is 1 for
1159 packet
.GetByteSize(), // Number of bytes
1160 UINT32_MAX
, // Num bytes per line
1161 LLDB_INVALID_ADDRESS
, // Base address
1162 0, 0); // Bitfield info set to not do
1163 // anything bitfield related
1167 uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu
,
1168 uint32_t flavor
, void *dst
,
1171 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
1173 const CommandType command
= KDP_READREGS
;
1174 // Size is header + 4 byte cpu and 4 byte flavor
1175 const uint32_t command_length
= 8 + 4 + 4;
1176 MakeRequestPacketHeader(command
, request_packet
, command_length
);
1177 request_packet
.PutHex32(cpu
);
1178 request_packet
.PutHex32(flavor
);
1179 DataExtractor reply_packet
;
1180 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
1181 lldb::offset_t offset
= 8;
1182 uint32_t kdp_error
= reply_packet
.GetU32(&offset
);
1183 uint32_t src_len
= reply_packet
.GetByteSize() - 12;
1186 const uint32_t bytes_to_copy
= std::min
<uint32_t>(src_len
, dst_len
);
1187 const void *src
= reply_packet
.GetData(&offset
, bytes_to_copy
);
1189 ::memcpy(dst
, src
, bytes_to_copy
);
1191 // Return the number of bytes we could have returned regardless if we
1192 // copied them or not, just so we know when things don't match up
1197 error
.SetErrorStringWithFormat(
1198 "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu
,
1201 error
.SetErrorStringWithFormat(
1202 "failed to read kdp registers for cpu %u flavor %u", cpu
, flavor
);
1204 error
.SetErrorString("failed to send packet");
1209 uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu
,
1214 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
1216 const CommandType command
= KDP_WRITEREGS
;
1217 // Size is header + 4 byte cpu and 4 byte flavor
1218 const uint32_t command_length
= 8 + 4 + 4 + src_len
;
1219 MakeRequestPacketHeader(command
, request_packet
, command_length
);
1220 request_packet
.PutHex32(cpu
);
1221 request_packet
.PutHex32(flavor
);
1222 request_packet
.Write(src
, src_len
);
1223 DataExtractor reply_packet
;
1224 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
1225 lldb::offset_t offset
= 8;
1226 uint32_t kdp_error
= reply_packet
.GetU32(&offset
);
1229 error
.SetErrorStringWithFormat(
1230 "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu
,
1233 error
.SetErrorString("failed to send packet");
1238 bool CommunicationKDP::SendRequestResume() {
1239 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
1241 const CommandType command
= KDP_RESUMECPUS
;
1242 const uint32_t command_length
= 12;
1243 MakeRequestPacketHeader(command
, request_packet
, command_length
);
1244 request_packet
.PutHex32(GetCPUMask());
1246 DataExtractor reply_packet
;
1247 return SendRequestAndGetReply(command
, request_packet
, reply_packet
);
1250 bool CommunicationKDP::SendRequestBreakpoint(bool set
, addr_t addr
) {
1251 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
1253 bool use_64
= (GetVersion() >= 11);
1254 uint32_t command_addr_byte_size
= use_64
? 8 : 4;
1255 const CommandType command
=
1256 set
? (use_64
? KDP_BREAKPOINT_SET64
: KDP_BREAKPOINT_SET
)
1257 : (use_64
? KDP_BREAKPOINT_REMOVE64
: KDP_BREAKPOINT_REMOVE
);
1259 const uint32_t command_length
= 8 + command_addr_byte_size
;
1260 MakeRequestPacketHeader(command
, request_packet
, command_length
);
1261 request_packet
.PutMaxHex64(addr
, command_addr_byte_size
);
1263 DataExtractor reply_packet
;
1264 if (SendRequestAndGetReply(command
, request_packet
, reply_packet
)) {
1265 lldb::offset_t offset
= 8;
1266 uint32_t kdp_error
= reply_packet
.GetU32(&offset
);
1273 bool CommunicationKDP::SendRequestSuspend() {
1274 PacketStreamType
request_packet(Stream::eBinary
, m_addr_byte_size
,
1276 const CommandType command
= KDP_SUSPEND
;
1277 const uint32_t command_length
= 8;
1278 MakeRequestPacketHeader(command
, request_packet
, command_length
);
1279 DataExtractor reply_packet
;
1280 return SendRequestAndGetReply(command
, request_packet
, reply_packet
);