1 //===-- CommunicationKDP.cpp ----------------------------------------------===// 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 <cerrno> 12 #include <climits> 13 #include <cstring> 14 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" 24 25 #include "ProcessKDPLog.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 // CommunicationKDP constructor 31 CommunicationKDP::CommunicationKDP(const char *comm_name) 32 : Communication(comm_name), 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) {} 38 39 // Destructor 40 CommunicationKDP::~CommunicationKDP() { 41 if (IsConnected()) { 42 Disconnect(); 43 } 44 } 45 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); 50 } 51 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 62 } 63 64 bool CommunicationKDP::SendRequestAndGetReply( 65 const CommandType command, const PacketStreamType &request_packet, 66 DataExtractor &reply_packet) { 67 if (IsRunning()) { 68 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); 69 if (log) { 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()); 74 } 75 return false; 76 } 77 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]; 87 while (true) { 88 if (WaitForPacketWithTimeoutMicroSecondsNoLock( 89 reply_packet, 90 std::chrono::microseconds(GetPacketTimeout()).count())) { 91 offset = 0; 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 96 // were looking for 97 if ((reply_command & eCommandTypeMask) == command) { 98 // Success 99 if (command == KDP_RESUMECPUS) 100 m_is_running.SetValue(true, eBroadcastAlways); 101 return true; 102 } else { 103 // Failed to get the correct response, bail 104 reply_packet.Clear(); 105 return false; 106 } 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(); 111 return false; 112 } else { 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 116 // retried. 117 } 118 } else { 119 // Break and retry sending the packet as we didn't get a response due 120 // to timeout 121 break; 122 } 123 } 124 } 125 } 126 reply_packet.Clear(); 127 return false; 128 } 129 130 bool CommunicationKDP::SendRequestPacketNoLock( 131 const PacketStreamType &request_packet) { 132 if (IsConnected()) { 133 const char *packet_data = request_packet.GetData(); 134 const size_t packet_size = request_packet.GetSize(); 135 136 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); 137 if (log) { 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()); 141 } 142 ConnectionStatus status = eConnectionStatusSuccess; 143 144 size_t bytes_written = Write(packet_data, packet_size, status, NULL); 145 146 if (bytes_written == packet_size) 147 return true; 148 149 LLDB_LOGF(log, 150 "error: failed to send packet entire packet %" PRIu64 151 " of %" PRIu64 " bytes sent", 152 (uint64_t)bytes_written, (uint64_t)packet_size); 153 } 154 return false; 155 } 156 157 bool CommunicationKDP::GetSequenceMutex( 158 std::unique_lock<std::recursive_mutex> &lock) { 159 return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex, 160 std::try_to_lock)) 161 .owns_lock(); 162 } 163 164 bool CommunicationKDP::WaitForNotRunningPrivate( 165 const std::chrono::microseconds &timeout) { 166 return m_is_running.WaitForValueEqualTo(false, timeout); 167 } 168 169 size_t 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); 174 } 175 176 size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock( 177 DataExtractor &packet, uint32_t timeout_usec) { 178 uint8_t buffer[8192]; 179 Status error; 180 181 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); 182 183 // Check for a packet from our cache first without trying any reading... 184 if (CheckForPacket(NULL, 0, packet)) 185 return packet.GetByteSize(); 186 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>(llvm::None) 193 : std::chrono::microseconds(timeout_usec), 194 status, &error); 195 196 LLDB_LOGV(log, 197 "Read (buffer, sizeof(buffer), timeout_usec = 0x{0:x}, " 198 "status = {1}, error = {2}) => bytes_read = {4}", 199 timeout_usec, Communication::ConnectionStatusAsString(status), 200 error, bytes_read); 201 202 if (bytes_read > 0) { 203 if (CheckForPacket(buffer, bytes_read, packet)) 204 return packet.GetByteSize(); 205 } else { 206 switch (status) { 207 case eConnectionStatusInterrupted: 208 case eConnectionStatusTimedOut: 209 timed_out = true; 210 break; 211 case eConnectionStatusSuccess: 212 // printf ("status = success but error = %s\n", 213 // error.AsCString("<invalid>")); 214 break; 215 216 case eConnectionStatusEndOfFile: 217 case eConnectionStatusNoConnection: 218 case eConnectionStatusLostConnection: 219 case eConnectionStatusError: 220 Disconnect(); 221 break; 222 } 223 } 224 } 225 packet.Clear(); 226 return 0; 227 } 228 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); 233 234 Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS)); 235 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()); 243 } 244 m_bytes.append((const char *)src, src_len); 245 } 246 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 257 { 258 PacketStreamType request_ack_packet(Stream::eBinary, m_addr_byte_size, 259 m_byte_order); 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); 268 } 269 // Fall through to case below to get packet contents 270 LLVM_FALLTHROUGH; 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: { 301 offset = 2; 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); 309 310 if (log) { 311 PacketStreamType log_strm; 312 DumpPacket(log_strm, packet); 313 314 LLDB_LOGF(log, "%.*s", (uint32_t)log_strm.GetSize(), 315 log_strm.GetData()); 316 } 317 return true; 318 } 319 } break; 320 321 default: 322 // Unrecognized reply command byte, erase this byte and try to get back 323 // on track 324 LLDB_LOGF(log, "CommunicationKDP::%s: tossing junk byte: 0x%2.2x", 325 __FUNCTION__, (uint8_t)m_bytes[0]); 326 m_bytes.erase(0, 1); 327 break; 328 } 329 } 330 packet.Clear(); 331 return false; 332 } 333 334 bool CommunicationKDP::SendRequestConnect(uint16_t reply_port, 335 uint16_t exc_port, 336 const char *greeting) { 337 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 338 m_byte_order); 339 if (greeting == NULL) 340 greeting = ""; 341 342 const CommandType command = KDP_CONNECT; 343 // Length is 82 uint16_t and the length of the greeting C string with the 344 // terminating NULL 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); 355 } 356 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; 364 } 365 366 bool CommunicationKDP::SendRequestReattach(uint16_t reply_port) { 367 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 368 m_byte_order); 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 380 ClearKDPSettings(); 381 lldb::offset_t offset = 4; 382 m_session_key = reply_packet.GetU32(&offset); 383 return true; 384 } 385 return false; 386 } 387 388 uint32_t CommunicationKDP::GetVersion() { 389 if (!VersionIsValid()) 390 SendRequestVersion(); 391 return m_kdp_version_version; 392 } 393 394 uint32_t CommunicationKDP::GetFeatureFlags() { 395 if (!VersionIsValid()) 396 SendRequestVersion(); 397 return m_kdp_version_feature; 398 } 399 400 bool CommunicationKDP::SendRequestVersion() { 401 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 402 m_byte_order); 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); 411 return true; 412 } 413 return false; 414 } 415 416 uint32_t CommunicationKDP::GetCPUMask() { 417 if (!HostInfoIsValid()) 418 SendRequestHostInfo(); 419 return m_kdp_hostinfo_cpu_mask; 420 } 421 422 uint32_t CommunicationKDP::GetCPUType() { 423 if (!HostInfoIsValid()) 424 SendRequestHostInfo(); 425 return m_kdp_hostinfo_cpu_type; 426 } 427 428 uint32_t CommunicationKDP::GetCPUSubtype() { 429 if (!HostInfoIsValid()) 430 SendRequestHostInfo(); 431 return m_kdp_hostinfo_cpu_subtype; 432 } 433 434 lldb_private::UUID CommunicationKDP::GetUUID() { 435 UUID uuid; 436 if (GetKernelVersion() == NULL) 437 return uuid; 438 439 if (m_kernel_version.find("UUID=") == std::string::npos) 440 return uuid; 441 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) 445 return uuid; 446 447 if (!uuid.SetFromStringRef(uuid_str)) { 448 UUID invalid_uuid; 449 return invalid_uuid; 450 } 451 452 return uuid; 453 } 454 455 bool CommunicationKDP::RemoteIsEFI() { 456 if (GetKernelVersion() == NULL) 457 return false; 458 return strncmp(m_kernel_version.c_str(), "EFI", 3) == 0; 459 } 460 461 bool CommunicationKDP::RemoteIsDarwinKernel() { 462 if (GetKernelVersion() == NULL) 463 return false; 464 return m_kernel_version.find("Darwin Kernel") != std::string::npos; 465 } 466 467 lldb::addr_t CommunicationKDP::GetLoadAddress() { 468 if (GetKernelVersion() == NULL) 469 return LLDB_INVALID_ADDRESS; 470 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; 476 477 addr_t kernel_load_address; 478 errno = 0; 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; 482 483 return kernel_load_address; 484 } 485 486 bool CommunicationKDP::SendRequestHostInfo() { 487 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 488 m_byte_order); 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); 498 499 ArchSpec kernel_arch; 500 kernel_arch.SetArchitecture(eArchTypeMachO, m_kdp_hostinfo_cpu_type, 501 m_kdp_hostinfo_cpu_subtype); 502 503 m_addr_byte_size = kernel_arch.GetAddressByteSize(); 504 m_byte_order = kernel_arch.GetByteOrder(); 505 return true; 506 } 507 return false; 508 } 509 510 const char *CommunicationKDP::GetKernelVersion() { 511 if (m_kernel_version.empty()) 512 SendRequestKernelVersion(); 513 return m_kernel_version.c_str(); 514 } 515 516 bool CommunicationKDP::SendRequestKernelVersion() { 517 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 518 m_byte_order); 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); 527 return true; 528 } 529 return false; 530 } 531 532 bool CommunicationKDP::SendRequestDisconnect() { 533 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 534 m_byte_order); 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? 541 } 542 ClearKDPSettings(); 543 return true; 544 } 545 546 uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst, 547 uint32_t dst_len, 548 Status &error) { 549 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 550 m_byte_order); 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; 564 565 if (src_len > 0) { 566 const void *src = reply_packet.GetData(&offset, src_len); 567 if (src) { 568 ::memcpy(dst, src, src_len); 569 error.Clear(); 570 return src_len; 571 } 572 } 573 if (kdp_error) 574 error.SetErrorStringWithFormat("kdp read memory failed (error %u)", 575 kdp_error); 576 else 577 error.SetErrorString("kdp read memory failed"); 578 } else { 579 error.SetErrorString("failed to send packet"); 580 } 581 return 0; 582 } 583 584 uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr, 585 const void *src, 586 uint32_t src_len, 587 Status &error) { 588 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 589 m_byte_order); 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); 599 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); 604 if (kdp_error) 605 error.SetErrorStringWithFormat("kdp write memory failed (error %u)", 606 kdp_error); 607 else { 608 error.Clear(); 609 return src_len; 610 } 611 } else { 612 error.SetErrorString("failed to send packet"); 613 } 614 return 0; 615 } 616 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, 623 m_byte_order); 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); 629 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); 636 else { 637 error.Clear(); 638 return true; 639 } 640 } else { 641 error.SetErrorString("failed to send packet"); 642 } 643 return false; 644 } 645 646 const char *CommunicationKDP::GetCommandAsCString(uint8_t command) { 647 switch (command) { 648 case KDP_CONNECT: 649 return "KDP_CONNECT"; 650 case KDP_DISCONNECT: 651 return "KDP_DISCONNECT"; 652 case KDP_HOSTINFO: 653 return "KDP_HOSTINFO"; 654 case KDP_VERSION: 655 return "KDP_VERSION"; 656 case KDP_MAXBYTES: 657 return "KDP_MAXBYTES"; 658 case KDP_READMEM: 659 return "KDP_READMEM"; 660 case KDP_WRITEMEM: 661 return "KDP_WRITEMEM"; 662 case KDP_READREGS: 663 return "KDP_READREGS"; 664 case KDP_WRITEREGS: 665 return "KDP_WRITEREGS"; 666 case KDP_LOAD: 667 return "KDP_LOAD"; 668 case KDP_IMAGEPATH: 669 return "KDP_IMAGEPATH"; 670 case KDP_SUSPEND: 671 return "KDP_SUSPEND"; 672 case KDP_RESUMECPUS: 673 return "KDP_RESUMECPUS"; 674 case KDP_EXCEPTION: 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"; 682 case KDP_REGIONS: 683 return "KDP_REGIONS"; 684 case KDP_REATTACH: 685 return "KDP_REATTACH"; 686 case KDP_HOSTREBOOT: 687 return "KDP_HOSTREBOOT"; 688 case KDP_READMEM64: 689 return "KDP_READMEM64"; 690 case KDP_WRITEMEM64: 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"; 702 case KDP_READIOPORT: 703 return "KDP_READIOPORT"; 704 case KDP_WRITEIOPORT: 705 return "KDP_WRITEIOPORT"; 706 case KDP_READMSR64: 707 return "KDP_READMSR64"; 708 case KDP_WRITEMSR64: 709 return "KDP_WRITEMSR64"; 710 case KDP_DUMPINFO: 711 return "KDP_DUMPINFO"; 712 } 713 return NULL; 714 } 715 716 void CommunicationKDP::DumpPacket(Stream &s, const void *data, 717 uint32_t data_len) { 718 DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size); 719 DumpPacket(s, extractor); 720 } 721 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): "; 726 } else { 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); 734 if (command_name) { 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); 739 740 if (is_reply) { 741 // Dump request reply packets 742 switch (command) { 743 // Commands that return a single 32 bit error 744 case KDP_CONNECT: 745 case KDP_WRITEMEM: 746 case KDP_WRITEMEM64: 747 case KDP_BREAKPOINT_SET: 748 case KDP_BREAKPOINT_REMOVE: 749 case KDP_BREAKPOINT_SET64: 750 case KDP_BREAKPOINT_REMOVE64: 751 case KDP_WRITEREGS: 752 case KDP_LOAD: 753 case KDP_WRITEIOPORT: 754 case KDP_WRITEMSR64: { 755 const uint32_t error = packet.GetU32(&offset); 756 s.Printf(" (error=0x%8.8x)", error); 757 } break; 758 759 case KDP_DISCONNECT: 760 case KDP_REATTACH: 761 case KDP_HOSTREBOOT: 762 case KDP_SUSPEND: 763 case KDP_RESUMECPUS: 764 case KDP_EXCEPTION: 765 case KDP_TERMINATION: 766 // No return value for the reply, just the header to ack 767 s.PutCString(" ()"); 768 break; 769 770 case KDP_HOSTINFO: { 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); 776 } break; 777 778 case KDP_VERSION: { 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); 782 } break; 783 784 case KDP_REGIONS: { 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)); 795 } 796 } break; 797 798 case KDP_READMEM: 799 case KDP_READMEM64: 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); 804 if (count > 0) 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 810 // in bytes 811 count, // Number of items 812 16, // Number per line 813 m_last_read_memory_addr, // Don't show addresses 814 // before each line 815 0, 0); // No bitfields 816 } break; 817 818 case KDP_READREGS: { 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); 822 if (count > 0) 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 828 // in bytes 829 count / m_addr_byte_size, // Number of items 830 16 / m_addr_byte_size, // Number per line 831 LLDB_INVALID_ADDRESS, 832 // Don't 833 // show addresses before 834 // each line 835 0, 0); // No bitfields 836 } break; 837 838 case KDP_KERNELVERSION: { 839 const char *kernel_version = packet.PeekCStr(8); 840 s.Printf(" (version = \"%s\")", kernel_version); 841 } break; 842 843 case KDP_MAXBYTES: { 844 const uint32_t max_bytes = packet.GetU32(&offset); 845 s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes); 846 } break; 847 case KDP_IMAGEPATH: { 848 const char *path = packet.GetCStr(&offset); 849 s.Printf(" (path = \"%s\")", path); 850 } break; 851 852 case KDP_READIOPORT: 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); 857 if (count > 0) 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 866 // before each line 867 0, 0); // No bitfields 868 } break; 869 case KDP_DUMPINFO: { 870 const uint32_t count = packet.GetByteSize() - offset; 871 s.Printf(" (count = %u, bytes = \n", count); 872 if (count > 0) 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 878 // bytes 879 count, // Number of items 880 16, // Number per line 881 LLDB_INVALID_ADDRESS, // Don't show addresses 882 // before each line 883 0, 0); // No bitfields 884 885 } break; 886 887 default: 888 s.Printf(" (add support for dumping this packet reply!!!"); 889 break; 890 } 891 } else { 892 // Dump request packets 893 switch (command) { 894 case KDP_CONNECT: { 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)); 899 } break; 900 901 case KDP_DISCONNECT: 902 case KDP_HOSTREBOOT: 903 case KDP_HOSTINFO: 904 case KDP_VERSION: 905 case KDP_REGIONS: 906 case KDP_KERNELVERSION: 907 case KDP_MAXBYTES: 908 case KDP_IMAGEPATH: 909 case KDP_SUSPEND: 910 // No args, just the header in the request... 911 s.PutCString(" ()"); 912 break; 913 914 case KDP_RESUMECPUS: { 915 const uint32_t cpu_mask = packet.GetU32(&offset); 916 s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask); 917 } break; 918 919 case KDP_READMEM: { 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; 924 } break; 925 926 case KDP_WRITEMEM: { 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); 930 if (size > 0) 931 DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); 932 } break; 933 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; 939 } break; 940 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, 946 lcpu); 947 m_last_read_memory_addr = addr; 948 } break; 949 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, 954 size); 955 if (size > 0) 956 DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); 957 } break; 958 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", 964 addr, size, lcpu); 965 if (size > 0) 966 DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); 967 } break; 968 969 case KDP_READREGS: { 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); 973 } break; 974 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); 980 if (nbytes > 0) 981 DumpDataExtractor(packet, 982 &s, // Stream to dump to 983 offset, // Offset within 984 // "packet" 985 eFormatHex, // Format to use 986 m_addr_byte_size, // Size of each item in 987 // bytes 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 991 // before each line 992 0, 0); // No bitfields 993 } break; 994 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); 999 } break; 1000 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); 1005 } break; 1006 1007 case KDP_LOAD: { 1008 const char *path = packet.GetCStr(&offset); 1009 s.Printf(" (path = \"%s\")", path); 1010 } break; 1011 1012 case KDP_EXCEPTION: { 1013 const uint32_t count = packet.GetU32(&offset); 1014 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; 1021 switch (exc) { 1022 case 1: 1023 exc_cstr = "EXC_BAD_ACCESS"; 1024 break; 1025 case 2: 1026 exc_cstr = "EXC_BAD_INSTRUCTION"; 1027 break; 1028 case 3: 1029 exc_cstr = "EXC_ARITHMETIC"; 1030 break; 1031 case 4: 1032 exc_cstr = "EXC_EMULATION"; 1033 break; 1034 case 5: 1035 exc_cstr = "EXC_SOFTWARE"; 1036 break; 1037 case 6: 1038 exc_cstr = "EXC_BREAKPOINT"; 1039 break; 1040 case 7: 1041 exc_cstr = "EXC_SYSCALL"; 1042 break; 1043 case 8: 1044 exc_cstr = "EXC_MACH_SYSCALL"; 1045 break; 1046 case 9: 1047 exc_cstr = "EXC_RPC_ALERT"; 1048 break; 1049 case 10: 1050 exc_cstr = "EXC_CRASH"; 1051 break; 1052 default: 1053 break; 1054 } 1055 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); 1059 } 1060 } break; 1061 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); 1067 } break; 1068 1069 case KDP_REATTACH: { 1070 const uint16_t reply_port = ntohs(packet.GetU16(&offset)); 1071 s.Printf(" (reply_port = %u)", reply_port); 1072 } break; 1073 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); 1078 } break; 1079 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, 1085 address, nbytes); 1086 if (nbytes > 0) 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 1092 // bytes 1093 nbytes, // Number of items 1094 16, // Number per line 1095 LLDB_INVALID_ADDRESS, // Don't show addresses 1096 // before each line 1097 0, 0); // No bitfields 1098 } break; 1099 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, 1105 nbytes); 1106 } break; 1107 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, 1113 address, nbytes); 1114 if (nbytes > 0) 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 1120 // bytes 1121 nbytes, // Number of items 1122 16, // Number per line 1123 LLDB_INVALID_ADDRESS, // Don't show addresses 1124 // before each line 1125 0, 0); // No bitfields 1126 } break; 1127 1128 case KDP_DUMPINFO: { 1129 const uint32_t count = packet.GetByteSize() - offset; 1130 s.Printf(" (count = %u, bytes = \n", count); 1131 if (count > 0) 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 1141 1142 } break; 1143 } 1144 } 1145 } else { 1146 error_desc = "error: invalid packet command: "; 1147 } 1148 } 1149 1150 if (error_desc) { 1151 s.PutCString(error_desc); 1152 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 1158 // single bytes 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 1164 } 1165 } 1166 1167 uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu, 1168 uint32_t flavor, void *dst, 1169 uint32_t dst_len, 1170 Status &error) { 1171 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 1172 m_byte_order); 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; 1184 1185 if (src_len > 0) { 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); 1188 if (src) { 1189 ::memcpy(dst, src, bytes_to_copy); 1190 error.Clear(); 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 1193 return src_len; 1194 } 1195 } 1196 if (kdp_error) 1197 error.SetErrorStringWithFormat( 1198 "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, 1199 flavor, kdp_error); 1200 else 1201 error.SetErrorStringWithFormat( 1202 "failed to read kdp registers for cpu %u flavor %u", cpu, flavor); 1203 } else { 1204 error.SetErrorString("failed to send packet"); 1205 } 1206 return 0; 1207 } 1208 1209 uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu, 1210 uint32_t flavor, 1211 const void *src, 1212 uint32_t src_len, 1213 Status &error) { 1214 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 1215 m_byte_order); 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); 1227 if (kdp_error == 0) 1228 return src_len; 1229 error.SetErrorStringWithFormat( 1230 "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, 1231 flavor, kdp_error); 1232 } else { 1233 error.SetErrorString("failed to send packet"); 1234 } 1235 return 0; 1236 } 1237 1238 bool CommunicationKDP::SendRequestResume() { 1239 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 1240 m_byte_order); 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()); 1245 1246 DataExtractor reply_packet; 1247 return SendRequestAndGetReply(command, request_packet, reply_packet); 1248 } 1249 1250 bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) { 1251 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 1252 m_byte_order); 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); 1258 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); 1262 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); 1267 if (kdp_error == 0) 1268 return true; 1269 } 1270 return false; 1271 } 1272 1273 bool CommunicationKDP::SendRequestSuspend() { 1274 PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size, 1275 m_byte_order); 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); 1281 } 1282