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