1 //===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 11 #include "CommunicationKDP.h" 12 13 // C Includes 14 #include <limits.h> 15 #include <string.h> 16 17 // C++ Includes 18 #include "llvm/Support/MachO.h" 19 20 // Other libraries and framework includes 21 #include "lldb/Core/DataBufferHeap.h" 22 #include "lldb/Core/DataExtractor.h" 23 #include "lldb/Core/Log.h" 24 #include "lldb/Core/State.h" 25 #include "lldb/Host/FileSpec.h" 26 #include "lldb/Host/Host.h" 27 #include "lldb/Host/TimeValue.h" 28 #include "lldb/Target/Process.h" 29 30 // Project includes 31 #include "ProcessKDPLog.h" 32 33 #define DEBUGSERVER_BASENAME "debugserver" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 //---------------------------------------------------------------------- 39 // CommunicationKDP constructor 40 //---------------------------------------------------------------------- 41 CommunicationKDP::CommunicationKDP (const char *comm_name) : 42 Communication(comm_name), 43 m_addr_byte_size (4), 44 m_byte_order (eByteOrderLittle), 45 m_packet_timeout (1), 46 m_sequence_mutex (Mutex::eMutexTypeRecursive), 47 m_private_is_running (false), 48 m_session_key (0u), 49 m_request_sequence_id (0u), 50 m_exception_sequence_id (0u), 51 m_kdp_version_version (0u), 52 m_kdp_version_feature (0u), 53 m_kdp_hostinfo_cpu_mask (0u), 54 m_kdp_hostinfo_cpu_type (0u), 55 m_kdp_hostinfo_cpu_subtype (0u) 56 { 57 } 58 59 //---------------------------------------------------------------------- 60 // Destructor 61 //---------------------------------------------------------------------- 62 CommunicationKDP::~CommunicationKDP() 63 { 64 if (IsConnected()) 65 { 66 Disconnect(); 67 } 68 } 69 70 bool 71 CommunicationKDP::SendRequestPacket (const PacketStreamType &request_packet) 72 { 73 Mutex::Locker locker(m_sequence_mutex); 74 return SendRequestPacketNoLock (request_packet); 75 } 76 77 #if 0 78 typedef struct { 79 uint8_t request; // Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply 80 uint8_t sequence; 81 uint16_t length; // Length of entire packet including this header 82 uint32_t key; // Session key 83 } kdp_hdr_t; 84 #endif 85 86 void 87 CommunicationKDP::MakeRequestPacketHeader (CommandType request_type, 88 PacketStreamType &request_packet, 89 uint16_t request_length) 90 { 91 request_packet.Clear(); 92 request_packet.PutHex8 (request_type | ePacketTypeRequest); // Set the request type 93 request_packet.PutHex8 (m_request_sequence_id++); // Sequence number 94 request_packet.PutHex16 (request_length); // Length of the packet including this header 95 request_packet.PutHex32 (m_session_key); // Session key 96 } 97 98 bool 99 CommunicationKDP::SendRequestAndGetReply (const CommandType command, 100 const uint8_t request_sequence_id, 101 const PacketStreamType &request_packet, 102 DataExtractor &reply_packet) 103 { 104 105 Mutex::Locker locker(m_sequence_mutex); 106 if (SendRequestPacketNoLock(request_packet)) 107 { 108 if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ())) 109 { 110 uint32_t offset = 0; 111 const uint8_t reply_command = reply_packet.GetU8 (&offset); 112 const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset); 113 if ((reply_command & eCommandTypeMask) == command) 114 { 115 if (request_sequence_id == reply_sequence_id) 116 return true; 117 } 118 } 119 } 120 reply_packet.Clear(); 121 return false; 122 } 123 124 bool 125 CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packet) 126 { 127 if (IsConnected()) 128 { 129 const char *packet_data = request_packet.GetData(); 130 const size_t packet_size = request_packet.GetSize(); 131 132 LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); 133 if (log) 134 { 135 PacketStreamType log_strm; 136 DumpPacket (log_strm, packet_data, packet_size); 137 log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); 138 } 139 ConnectionStatus status = eConnectionStatusSuccess; 140 141 size_t bytes_written = Write (packet_data, 142 packet_size, 143 status, 144 NULL); 145 146 if (bytes_written == packet_size) 147 return true; 148 149 if (log) 150 log->Printf ("error: failed to send packet entire packet %zu of %zu bytes sent", bytes_written, packet_size); 151 } 152 return false; 153 } 154 155 bool 156 CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker) 157 { 158 return locker.TryLock (m_sequence_mutex.GetMutex()); 159 } 160 161 162 bool 163 CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) 164 { 165 return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL); 166 } 167 168 size_t 169 CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec) 170 { 171 Mutex::Locker locker(m_sequence_mutex); 172 return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); 173 } 174 175 size_t 176 CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec) 177 { 178 uint8_t buffer[8192]; 179 Error error; 180 181 LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE)); 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 { 190 lldb::ConnectionStatus status = eConnectionStatusNoConnection; 191 size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); 192 193 if (log) 194 log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %zu", 195 __PRETTY_FUNCTION__, 196 timeout_usec, 197 Communication::ConnectionStatusAsCString (status), 198 error.AsCString(), 199 bytes_read); 200 201 if (bytes_read > 0) 202 { 203 if (CheckForPacket (buffer, bytes_read, packet)) 204 return packet.GetByteSize(); 205 } 206 else 207 { 208 switch (status) 209 { 210 case eConnectionStatusTimedOut: 211 timed_out = true; 212 break; 213 case eConnectionStatusSuccess: 214 //printf ("status = success but error = %s\n", error.AsCString("<invalid>")); 215 break; 216 217 case eConnectionStatusEndOfFile: 218 case eConnectionStatusNoConnection: 219 case eConnectionStatusLostConnection: 220 case eConnectionStatusError: 221 Disconnect(); 222 break; 223 } 224 } 225 } 226 packet.Clear (); 227 return 0; 228 } 229 230 bool 231 CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet) 232 { 233 // Put the packet data into the buffer in a thread safe fashion 234 Mutex::Locker locker(m_bytes_mutex); 235 236 LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); 237 238 if (src && src_len > 0) 239 { 240 if (log && log->GetVerbose()) 241 { 242 PacketStreamType log_strm; 243 DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS); 244 log->Printf ("CommunicationKDP::%s adding %u bytes: %s", 245 __FUNCTION__, 246 (uint32_t)src_len, 247 log_strm.GetData()); 248 } 249 m_bytes.append ((const char *)src, src_len); 250 } 251 252 // Make sure we at least have enough bytes for a packet header 253 const size_t bytes_available = m_bytes.size(); 254 if (bytes_available >= 8) 255 { 256 packet.SetData (&m_bytes[0], bytes_available, m_byte_order); 257 uint32_t offset = 0; 258 uint8_t reply_command = packet.GetU8(&offset); 259 switch (reply_command) 260 { 261 case ePacketTypeReply | KDP_CONNECT: 262 case ePacketTypeReply | KDP_DISCONNECT: 263 case ePacketTypeReply | KDP_HOSTINFO: 264 case ePacketTypeReply | KDP_VERSION: 265 case ePacketTypeReply | KDP_MAXBYTES: 266 case ePacketTypeReply | KDP_READMEM: 267 case ePacketTypeReply | KDP_WRITEMEM: 268 case ePacketTypeReply | KDP_READREGS: 269 case ePacketTypeReply | KDP_WRITEREGS: 270 case ePacketTypeReply | KDP_LOAD: 271 case ePacketTypeReply | KDP_IMAGEPATH: 272 case ePacketTypeReply | KDP_SUSPEND: 273 case ePacketTypeReply | KDP_RESUMECPUS: 274 case ePacketTypeReply | KDP_EXCEPTION: 275 case ePacketTypeReply | KDP_TERMINATION: 276 case ePacketTypeReply | KDP_BREAKPOINT_SET: 277 case ePacketTypeReply | KDP_BREAKPOINT_REMOVE: 278 case ePacketTypeReply | KDP_REGIONS: 279 case ePacketTypeReply | KDP_REATTACH: 280 case ePacketTypeReply | KDP_HOSTREBOOT: 281 case ePacketTypeReply | KDP_READMEM64: 282 case ePacketTypeReply | KDP_WRITEMEM64: 283 case ePacketTypeReply | KDP_BREAKPOINT_SET64: 284 case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64: 285 case ePacketTypeReply | KDP_KERNELVERSION: 286 { 287 offset = 2; 288 const uint16_t length = packet.GetU16 (&offset); 289 if (length <= bytes_available) 290 { 291 // We have an entire packet ready, we need to copy the data 292 // bytes into a buffer that will be owned by the packet and 293 // erase the bytes from our communcation buffer "m_bytes" 294 packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length))); 295 m_bytes.erase (0, length); 296 297 if (log) 298 { 299 PacketStreamType log_strm; 300 DumpPacket (log_strm, packet); 301 302 log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData()); 303 } 304 return true; 305 } 306 } 307 break; 308 309 default: 310 // Unrecognized reply command byte, erase this byte and try to get back on track 311 if (log) 312 log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x", 313 __FUNCTION__, 314 (uint8_t)m_bytes[0]); 315 m_bytes.erase(0, 1); 316 break; 317 } 318 } 319 packet.Clear(); 320 return false; 321 } 322 323 324 bool 325 CommunicationKDP::SendRequestConnect (uint16_t reply_port, 326 uint16_t exc_port, 327 const char *greeting) 328 { 329 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 330 if (greeting == NULL) 331 greeting = ""; 332 333 const CommandType command = KDP_CONNECT; 334 // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL 335 const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1; 336 const uint32_t request_sequence_id = m_request_sequence_id; 337 MakeRequestPacketHeader (command, request_packet, command_length); 338 // Always send connect ports as little endian 339 request_packet.SetByteOrder (eByteOrderLittle); 340 request_packet.PutHex16 (reply_port); 341 request_packet.PutHex16 (exc_port); 342 request_packet.SetByteOrder (m_byte_order); 343 request_packet.PutCString (greeting); 344 DataExtractor reply_packet; 345 return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet); 346 } 347 348 void 349 CommunicationKDP::ClearKDPSettings () 350 { 351 m_request_sequence_id = 0; 352 m_kdp_version_version = 0; 353 m_kdp_version_feature = 0; 354 m_kdp_hostinfo_cpu_mask = 0; 355 m_kdp_hostinfo_cpu_type = 0; 356 m_kdp_hostinfo_cpu_subtype = 0; 357 } 358 359 bool 360 CommunicationKDP::SendRequestReattach (uint16_t reply_port) 361 { 362 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 363 const CommandType command = KDP_REATTACH; 364 // Length is 8 bytes for the header plus 2 bytes for the reply UDP port 365 const uint32_t command_length = 8 + 2; 366 const uint32_t request_sequence_id = m_request_sequence_id; 367 MakeRequestPacketHeader (command, request_packet, command_length); 368 // Always send connect ports as little endian 369 request_packet.SetByteOrder (eByteOrderLittle); 370 request_packet.PutHex16(reply_port); 371 request_packet.SetByteOrder (m_byte_order); 372 DataExtractor reply_packet; 373 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 374 { 375 // Reset the sequence ID to zero for reattach 376 ClearKDPSettings (); 377 uint32_t offset = 4; 378 m_session_key = reply_packet.GetU32 (&offset); 379 return true; 380 } 381 return false; 382 } 383 384 uint32_t 385 CommunicationKDP::GetVersion () 386 { 387 if (!VersionIsValid()) 388 SendRequestVersion(); 389 return m_kdp_version_version; 390 } 391 392 uint32_t 393 CommunicationKDP::GetFeatureFlags () 394 { 395 if (!VersionIsValid()) 396 SendRequestVersion(); 397 return m_kdp_version_feature; 398 } 399 400 bool 401 CommunicationKDP::SendRequestVersion () 402 { 403 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 404 const CommandType command = KDP_VERSION; 405 const uint32_t command_length = 8; 406 const uint32_t request_sequence_id = m_request_sequence_id; 407 MakeRequestPacketHeader (command, request_packet, command_length); 408 DataExtractor reply_packet; 409 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 410 { 411 uint32_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 #if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... 420 const char * 421 CommunicationKDP::GetImagePath () 422 { 423 if (m_image_path.empty()) 424 SendRequestImagePath(); 425 return m_image_path.c_str(); 426 } 427 428 bool 429 CommunicationKDP::SendRequestImagePath () 430 { 431 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 432 const CommandType command = KDP_IMAGEPATH; 433 const uint32_t command_length = 8; 434 const uint32_t request_sequence_id = m_request_sequence_id; 435 MakeRequestPacketHeader (command, request_packet, command_length); 436 DataExtractor reply_packet; 437 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 438 { 439 const char *path = reply_packet.PeekCStr(8); 440 if (path && path[0]) 441 m_kernel_version.assign (path); 442 return true; 443 } 444 return false; 445 } 446 #endif 447 448 uint32_t 449 CommunicationKDP::GetCPUMask () 450 { 451 if (!HostInfoIsValid()) 452 SendRequestHostInfo(); 453 return m_kdp_hostinfo_cpu_mask; 454 } 455 456 uint32_t 457 CommunicationKDP::GetCPUType () 458 { 459 if (!HostInfoIsValid()) 460 SendRequestHostInfo(); 461 return m_kdp_hostinfo_cpu_type; 462 } 463 464 uint32_t 465 CommunicationKDP::GetCPUSubtype () 466 { 467 if (!HostInfoIsValid()) 468 SendRequestHostInfo(); 469 return m_kdp_hostinfo_cpu_subtype; 470 } 471 472 bool 473 CommunicationKDP::SendRequestHostInfo () 474 { 475 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 476 const CommandType command = KDP_HOSTINFO; 477 const uint32_t command_length = 8; 478 const uint32_t request_sequence_id = m_request_sequence_id; 479 MakeRequestPacketHeader (command, request_packet, command_length); 480 DataExtractor reply_packet; 481 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 482 { 483 uint32_t offset = 8; 484 m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset); 485 m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset); 486 m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset); 487 488 ArchSpec kernel_arch; 489 kernel_arch.SetArchitecture (eArchTypeMachO, 490 m_kdp_hostinfo_cpu_type, 491 m_kdp_hostinfo_cpu_subtype); 492 493 m_addr_byte_size = kernel_arch.GetAddressByteSize(); 494 m_byte_order = kernel_arch.GetByteOrder(); 495 return true; 496 } 497 return false; 498 } 499 500 const char * 501 CommunicationKDP::GetKernelVersion () 502 { 503 if (m_kernel_version.empty()) 504 SendRequestKernelVersion (); 505 return m_kernel_version.c_str(); 506 } 507 508 bool 509 CommunicationKDP::SendRequestKernelVersion () 510 { 511 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 512 const CommandType command = KDP_KERNELVERSION; 513 const uint32_t command_length = 8; 514 const uint32_t request_sequence_id = m_request_sequence_id; 515 MakeRequestPacketHeader (command, request_packet, command_length); 516 DataExtractor reply_packet; 517 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 518 { 519 const char *kernel_version_cstr = reply_packet.PeekCStr(8); 520 if (kernel_version_cstr && kernel_version_cstr[0]) 521 m_kernel_version.assign (kernel_version_cstr); 522 return true; 523 } 524 return false; 525 } 526 527 bool 528 CommunicationKDP::SendRequestDisconnect () 529 { 530 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 531 const CommandType command = KDP_DISCONNECT; 532 const uint32_t command_length = 8; 533 const uint32_t request_sequence_id = m_request_sequence_id; 534 MakeRequestPacketHeader (command, request_packet, command_length); 535 DataExtractor reply_packet; 536 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 537 { 538 // Are we supposed to get a reply for disconnect? 539 } 540 ClearKDPSettings (); 541 return true; 542 } 543 544 uint32_t 545 CommunicationKDP::SendRequestReadMemory (lldb::addr_t addr, 546 void *dst, 547 uint32_t dst_len, 548 Error &error) 549 { 550 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, 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 const uint32_t request_sequence_id = m_request_sequence_id; 557 MakeRequestPacketHeader (command, request_packet, command_length); 558 request_packet.PutMaxHex64 (addr, command_addr_byte_size); 559 request_packet.PutHex32 (dst_len); 560 DataExtractor reply_packet; 561 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 562 { 563 uint32_t offset = 8; 564 uint32_t kdp_error = reply_packet.GetU32 (&offset); 565 uint32_t src_len = reply_packet.GetByteSize() - 12; 566 567 if (src_len > 0) 568 { 569 const void *src = reply_packet.GetData(&offset, src_len); 570 if (src) 571 { 572 ::memcpy (dst, src, src_len); 573 error.Clear(); 574 return src_len; 575 } 576 } 577 if (kdp_error) 578 error.SetErrorStringWithFormat ("kdp read memory failed (error %u)", kdp_error); 579 else 580 error.SetErrorString ("kdp read memory failed"); 581 } 582 return 0; 583 } 584 585 586 uint32_t 587 CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr, 588 const void *src, 589 uint32_t src_len, 590 Error &error) 591 { 592 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, 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; 598 const uint32_t request_sequence_id = m_request_sequence_id; 599 MakeRequestPacketHeader (command, request_packet, command_length); 600 request_packet.PutMaxHex64 (addr, command_addr_byte_size); 601 request_packet.PutHex32 (src_len); 602 request_packet.PutBytesAsRawHex8(src, src_len); 603 604 DataExtractor reply_packet; 605 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 606 { 607 uint32_t offset = 8; 608 uint32_t kdp_error = reply_packet.GetU32 (&offset); 609 if (kdp_error) 610 error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error); 611 else 612 { 613 error.Clear(); 614 return src_len; 615 } 616 } 617 return 0; 618 } 619 620 const char * 621 CommunicationKDP::GetCommandAsCString (uint8_t command) 622 { 623 switch (command) 624 { 625 case KDP_CONNECT: return "KDP_CONNECT"; 626 case KDP_DISCONNECT: return "KDP_DISCONNECT"; 627 case KDP_HOSTINFO: return "KDP_HOSTINFO"; 628 case KDP_VERSION: return "KDP_VERSION"; 629 case KDP_MAXBYTES: return "KDP_MAXBYTES"; 630 case KDP_READMEM: return "KDP_READMEM"; 631 case KDP_WRITEMEM: return "KDP_WRITEMEM"; 632 case KDP_READREGS: return "KDP_READREGS"; 633 case KDP_WRITEREGS: return "KDP_WRITEREGS"; 634 case KDP_LOAD: return "KDP_LOAD"; 635 case KDP_IMAGEPATH: return "KDP_IMAGEPATH"; 636 case KDP_SUSPEND: return "KDP_SUSPEND"; 637 case KDP_RESUMECPUS: return "KDP_RESUMECPUS"; 638 case KDP_EXCEPTION: return "KDP_EXCEPTION"; 639 case KDP_TERMINATION: return "KDP_TERMINATION"; 640 case KDP_BREAKPOINT_SET: return "KDP_BREAKPOINT_SET"; 641 case KDP_BREAKPOINT_REMOVE: return "KDP_BREAKPOINT_REMOVE"; 642 case KDP_REGIONS: return "KDP_REGIONS"; 643 case KDP_REATTACH: return "KDP_REATTACH"; 644 case KDP_HOSTREBOOT: return "KDP_HOSTREBOOT"; 645 case KDP_READMEM64: return "KDP_READMEM64"; 646 case KDP_WRITEMEM64: return "KDP_WRITEMEM64"; 647 case KDP_BREAKPOINT_SET64: return "KDP_BREAKPOINT64_SET"; 648 case KDP_BREAKPOINT_REMOVE64: return "KDP_BREAKPOINT64_REMOVE"; 649 case KDP_KERNELVERSION: return "KDP_KERNELVERSION"; 650 } 651 return NULL; 652 } 653 654 void 655 CommunicationKDP::DumpPacket (Stream &s, const void *data, uint32_t data_len) 656 { 657 DataExtractor extractor (data, data_len, m_byte_order, m_addr_byte_size); 658 DumpPacket (s, extractor); 659 } 660 661 void 662 CommunicationKDP::DumpPacket (Stream &s, const DataExtractor& packet) 663 { 664 const char *error_desc = NULL; 665 if (packet.GetByteSize() < 8) 666 { 667 error_desc = "error: invalid packet (too short): "; 668 } 669 else 670 { 671 uint32_t offset = 0; 672 const uint8_t first_packet_byte = packet.GetU8 (&offset); 673 const uint8_t sequence_id = packet.GetU8 (&offset); 674 const uint16_t length = packet.GetU16 (&offset); 675 const uint32_t key = packet.GetU32 (&offset); 676 const CommandType command = ExtractCommand (first_packet_byte); 677 const char *command_name = GetCommandAsCString (command); 678 if (command_name) 679 { 680 const bool is_reply = ExtractIsReply(first_packet_byte); 681 s.Printf ("%s {%u:%u} <0x%4.4x> %s", 682 is_reply ? "<--" : "-->", 683 key, 684 sequence_id, 685 length, 686 command_name); 687 688 if (is_reply) 689 { 690 // Dump request reply packets 691 switch (command) 692 { 693 // Commands that return a single 32 bit error 694 case KDP_CONNECT: 695 case KDP_WRITEMEM: 696 case KDP_WRITEMEM64: 697 case KDP_BREAKPOINT_SET: 698 case KDP_BREAKPOINT_REMOVE: 699 case KDP_BREAKPOINT_SET64: 700 case KDP_BREAKPOINT_REMOVE64: 701 case KDP_WRITEREGS: 702 case KDP_LOAD: 703 { 704 const uint32_t error = packet.GetU32 (&offset); 705 s.Printf(" (error=0x%8.8x)", error); 706 } 707 break; 708 709 case KDP_DISCONNECT: 710 case KDP_REATTACH: 711 case KDP_HOSTREBOOT: 712 case KDP_SUSPEND: 713 case KDP_RESUMECPUS: 714 case KDP_EXCEPTION: 715 case KDP_TERMINATION: 716 // No return value for the reply, just the header to ack 717 s.PutCString(" ()"); 718 break; 719 720 case KDP_HOSTINFO: 721 { 722 const uint32_t cpu_mask = packet.GetU32 (&offset); 723 const uint32_t cpu_type = packet.GetU32 (&offset); 724 const uint32_t cpu_subtype = packet.GetU32 (&offset); 725 s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)", cpu_mask, cpu_type, cpu_subtype); 726 } 727 break; 728 729 case KDP_VERSION: 730 { 731 const uint32_t version = packet.GetU32 (&offset); 732 const uint32_t feature = packet.GetU32 (&offset); 733 s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature); 734 } 735 break; 736 737 case KDP_REGIONS: 738 { 739 const uint32_t region_count = packet.GetU32 (&offset); 740 s.Printf(" (count = %u", region_count); 741 for (uint32_t i=0; i<region_count; ++i) 742 { 743 const addr_t region_addr = packet.GetPointer (&offset); 744 const uint32_t region_size = packet.GetU32 (&offset); 745 const uint32_t region_prot = packet.GetU32 (&offset); 746 s.Printf("\n\tregion[%llu] = { range = [0x%16.16llx - 0x%16.16llx), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot)); 747 } 748 } 749 break; 750 751 case KDP_READMEM: 752 case KDP_READMEM64: 753 { 754 const uint32_t error = packet.GetU32 (&offset); 755 const uint32_t count = packet.GetByteSize() - offset; 756 s.Printf(" (error = 0x%8.8x:\n", error); 757 if (count > 0) 758 packet.Dump (&s, // Stream to dump to 759 offset, // Offset within "packet" 760 eFormatBytesWithASCII, // Format to use 761 1, // Size of each item in bytes 762 count, // Number of items 763 16, // Number per line 764 m_last_read_memory_addr, // Don't show addresses before each line 765 0, 0); // No bitfields 766 } 767 break; 768 769 case KDP_READREGS: 770 { 771 const uint32_t error = packet.GetU32 (&offset); 772 const uint32_t count = packet.GetByteSize() - offset; 773 s.Printf(" (error = 0x%8.8x regs:\n", error); 774 if (count > 0) 775 packet.Dump (&s, // Stream to dump to 776 offset, // Offset within "packet" 777 eFormatHex, // Format to use 778 m_addr_byte_size, // Size of each item in bytes 779 count / m_addr_byte_size, // Number of items 780 16 / m_addr_byte_size, // Number per line 781 LLDB_INVALID_ADDRESS, // Don't show addresses before each line 782 0, 0); // No bitfields 783 } 784 break; 785 786 case KDP_KERNELVERSION: 787 { 788 const char *kernel_version = packet.PeekCStr(8); 789 s.Printf(" (version = \"%s\")", kernel_version); 790 } 791 break; 792 793 case KDP_MAXBYTES: 794 { 795 const uint32_t max_bytes = packet.GetU32 (&offset); 796 s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes); 797 } 798 break; 799 case KDP_IMAGEPATH: 800 { 801 const char *path = packet.GetCStr(&offset); 802 s.Printf(" (path = \"%s\")", path); 803 } 804 break; 805 default: 806 s.Printf(" (add support for dumping this packet reply!!!"); 807 break; 808 809 } 810 } 811 else 812 { 813 // Dump request packets 814 switch (command) 815 { 816 case KDP_CONNECT: 817 { 818 const uint16_t reply_port = packet.GetU16 (&offset); 819 const uint16_t exc_port = packet.GetU16 (&offset); 820 s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")", reply_port, exc_port, packet.GetCStr(&offset)); 821 } 822 break; 823 824 case KDP_DISCONNECT: 825 case KDP_HOSTREBOOT: 826 case KDP_HOSTINFO: 827 case KDP_VERSION: 828 case KDP_REGIONS: 829 case KDP_KERNELVERSION: 830 case KDP_MAXBYTES: 831 case KDP_IMAGEPATH: 832 case KDP_SUSPEND: 833 // No args, just the header in the request... 834 s.PutCString(" ()"); 835 break; 836 837 case KDP_RESUMECPUS: 838 { 839 const uint32_t cpu_mask = packet.GetU32 (&offset); 840 s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask); 841 } 842 break; 843 844 case KDP_READMEM: 845 { 846 const uint32_t addr = packet.GetU32 (&offset); 847 const uint32_t size = packet.GetU32 (&offset); 848 s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size); 849 m_last_read_memory_addr = addr; 850 } 851 break; 852 853 case KDP_WRITEMEM: 854 { 855 const uint32_t addr = packet.GetU32 (&offset); 856 const uint32_t size = packet.GetU32 (&offset); 857 s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size); 858 if (size > 0) 859 DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); 860 } 861 break; 862 863 case KDP_READMEM64: 864 { 865 const uint64_t addr = packet.GetU64 (&offset); 866 const uint32_t size = packet.GetU32 (&offset); 867 s.Printf(" (addr = 0x%16.16llx, size = %u)", addr, size); 868 m_last_read_memory_addr = addr; 869 } 870 break; 871 872 case KDP_WRITEMEM64: 873 { 874 const uint64_t addr = packet.GetU64 (&offset); 875 const uint32_t size = packet.GetU32 (&offset); 876 s.Printf(" (addr = 0x%16.16llx, size = %u, bytes = \n", addr, size); 877 if (size > 0) 878 DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr); 879 } 880 break; 881 882 case KDP_READREGS: 883 { 884 const uint32_t cpu = packet.GetU32 (&offset); 885 const uint32_t flavor = packet.GetU32 (&offset); 886 s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor); 887 } 888 break; 889 890 case KDP_WRITEREGS: 891 { 892 const uint32_t cpu = packet.GetU32 (&offset); 893 const uint32_t flavor = packet.GetU32 (&offset); 894 const uint32_t nbytes = packet.GetByteSize() - offset; 895 s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor); 896 if (nbytes > 0) 897 packet.Dump (&s, // Stream to dump to 898 offset, // Offset within "packet" 899 eFormatHex, // Format to use 900 m_addr_byte_size, // Size of each item in bytes 901 nbytes / m_addr_byte_size, // Number of items 902 16 / m_addr_byte_size, // Number per line 903 LLDB_INVALID_ADDRESS, // Don't show addresses before each line 904 0, 0); // No bitfields 905 } 906 break; 907 908 909 case KDP_BREAKPOINT_SET: 910 case KDP_BREAKPOINT_REMOVE: 911 { 912 const uint32_t addr = packet.GetU32 (&offset); 913 s.Printf(" (addr = 0x%8.8x)", addr); 914 } 915 break; 916 917 case KDP_BREAKPOINT_SET64: 918 case KDP_BREAKPOINT_REMOVE64: 919 { 920 const uint64_t addr = packet.GetU64 (&offset); 921 s.Printf(" (addr = 0x%16.16llx)", addr); 922 } 923 break; 924 925 926 case KDP_LOAD: 927 { 928 const char *path = packet.GetCStr(&offset); 929 s.Printf(" (path = \"%s\")", path); 930 } 931 break; 932 933 case KDP_EXCEPTION: 934 { 935 const uint32_t count = packet.GetU32 (&offset); 936 937 s.Printf(" (count = %u:", count); 938 for (uint32_t i=0; i<count; ++i) 939 { 940 const uint32_t cpu = packet.GetU32 (&offset); 941 const uint32_t exc = packet.GetU32 (&offset); 942 const uint32_t code = packet.GetU32 (&offset); 943 const uint32_t subcode = packet.GetU32 (&offset); 944 const char *exc_cstr = NULL; 945 switch (exc) 946 { 947 case 1: exc_cstr = "EXC_BAD_ACCESS"; break; 948 case 2: exc_cstr = "EXC_BAD_INSTRUCTION"; break; 949 case 3: exc_cstr = "EXC_ARITHMETIC"; break; 950 case 4: exc_cstr = "EXC_EMULATION"; break; 951 case 5: exc_cstr = "EXC_SOFTWARE"; break; 952 case 6: exc_cstr = "EXC_BREAKPOINT"; break; 953 case 7: exc_cstr = "EXC_SYSCALL"; break; 954 case 8: exc_cstr = "EXC_MACH_SYSCALL"; break; 955 case 9: exc_cstr = "EXC_RPC_ALERT"; break; 956 case 10: exc_cstr = "EXC_CRASH"; break; 957 default: 958 break; 959 } 960 961 s.Printf ("\n cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)\n", 962 cpu, exc_cstr, exc, code, code, subcode, subcode); 963 } 964 } 965 break; 966 967 case KDP_TERMINATION: 968 { 969 const uint32_t term_code = packet.GetU32 (&offset); 970 const uint32_t exit_code = packet.GetU32 (&offset); 971 s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))", term_code, term_code, exit_code, exit_code); 972 } 973 break; 974 975 case KDP_REATTACH: 976 { 977 const uint16_t reply_port = packet.GetU16 (&offset); 978 s.Printf(" (reply_port = %u)", reply_port); 979 } 980 break; 981 } 982 } 983 } 984 else 985 { 986 error_desc = "error: invalid packet command: "; 987 } 988 } 989 990 if (error_desc) 991 { 992 s.PutCString (error_desc); 993 994 packet.Dump (&s, // Stream to dump to 995 0, // Offset into "packet" 996 eFormatBytes, // Dump as hex bytes 997 1, // Size of each item is 1 for single bytes 998 packet.GetByteSize(), // Number of bytes 999 UINT32_MAX, // Num bytes per line 1000 LLDB_INVALID_ADDRESS, // Base address 1001 0, 0); // Bitfield info set to not do anything bitfield related 1002 } 1003 } 1004 1005 uint32_t 1006 CommunicationKDP::SendRequestReadRegisters (uint32_t cpu, 1007 uint32_t flavor, 1008 void *dst, 1009 uint32_t dst_len, 1010 Error &error) 1011 { 1012 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 1013 const CommandType command = KDP_READREGS; 1014 // Size is header + 4 byte cpu and 4 byte flavor 1015 const uint32_t command_length = 8 + 4 + 4; 1016 const uint32_t request_sequence_id = m_request_sequence_id; 1017 MakeRequestPacketHeader (command, request_packet, command_length); 1018 request_packet.PutHex32 (cpu); 1019 request_packet.PutHex32 (flavor); 1020 DataExtractor reply_packet; 1021 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 1022 { 1023 uint32_t offset = 8; 1024 uint32_t kdp_error = reply_packet.GetU32 (&offset); 1025 uint32_t src_len = reply_packet.GetByteSize() - 12; 1026 1027 if (src_len > 0) 1028 { 1029 const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len); 1030 const void *src = reply_packet.GetData(&offset, bytes_to_copy); 1031 if (src) 1032 { 1033 ::memcpy (dst, src, bytes_to_copy); 1034 error.Clear(); 1035 // Return the number of bytes we could have returned regardless if 1036 // we copied them or not, just so we know when things don't match up 1037 return src_len; 1038 } 1039 } 1040 if (kdp_error) 1041 error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u (error %u)", cpu, flavor, kdp_error); 1042 else 1043 error.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor); 1044 } 1045 return 0; 1046 } 1047 1048 1049 bool 1050 CommunicationKDP::SendRequestResume (uint32_t cpu_mask) 1051 { 1052 if (cpu_mask == 0) 1053 cpu_mask = GetCPUMask(); 1054 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 1055 const CommandType command = KDP_RESUMECPUS; 1056 const uint32_t command_length = 12; 1057 const uint32_t request_sequence_id = m_request_sequence_id; 1058 MakeRequestPacketHeader (command, request_packet, command_length); 1059 request_packet.PutHex32(cpu_mask); 1060 1061 DataExtractor reply_packet; 1062 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 1063 return true; 1064 return false; 1065 } 1066 1067 bool 1068 CommunicationKDP::SendRequestBreakpoint (bool set, addr_t addr) 1069 { 1070 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 1071 bool use_64 = (GetVersion() >= 11); 1072 uint32_t command_addr_byte_size = use_64 ? 8 : 4; 1073 const CommandType command = set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET ): 1074 (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE); 1075 1076 const uint32_t command_length = 8 + command_addr_byte_size; 1077 const uint32_t request_sequence_id = m_request_sequence_id; 1078 MakeRequestPacketHeader (command, request_packet, command_length); 1079 request_packet.PutMaxHex64 (addr, command_addr_byte_size); 1080 1081 DataExtractor reply_packet; 1082 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 1083 { 1084 uint32_t offset = 8; 1085 uint32_t kdp_error = reply_packet.GetU32 (&offset); 1086 if (kdp_error == 0) 1087 return true; 1088 } 1089 return false; 1090 } 1091 1092 bool 1093 CommunicationKDP::SendRequestSuspend () 1094 { 1095 PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); 1096 const CommandType command = KDP_SUSPEND; 1097 const uint32_t command_length = 8; 1098 const uint32_t request_sequence_id = m_request_sequence_id; 1099 MakeRequestPacketHeader (command, request_packet, command_length); 1100 DataExtractor reply_packet; 1101 if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) 1102 return true; 1103 return false; 1104 } 1105 1106