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