1 //===-- GDBRemoteCommunication.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 "GDBRemoteCommunication.h" 12 13 // C Includes 14 // C++ Includes 15 // Other libraries and framework includes 16 #include "lldb/Interpreter/Args.h" 17 #include "lldb/Core/ConnectionFileDescriptor.h" 18 #include "lldb/Core/Log.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Core/StreamString.h" 21 #include "lldb/Host/TimeValue.h" 22 23 // Project includes 24 #include "Utility/StringExtractorGDBRemote.h" 25 #include "ProcessGDBRemote.h" 26 #include "ProcessGDBRemoteLog.h" 27 28 using namespace lldb; 29 using namespace lldb_private; 30 31 //---------------------------------------------------------------------- 32 // GDBRemoteCommunication constructor 33 //---------------------------------------------------------------------- 34 GDBRemoteCommunication::GDBRemoteCommunication() : 35 Communication("gdb-remote.packets"), 36 m_send_acks (true), 37 m_thread_suffix_supported (false), 38 m_rx_packet_listener ("gdbremote.rx_packet"), 39 m_sequence_mutex (Mutex::eMutexTypeRecursive), 40 m_is_running (false), 41 m_async_mutex (Mutex::eMutexTypeRecursive), 42 m_async_packet_predicate (false), 43 m_async_packet (), 44 m_async_response (), 45 m_async_timeout (UINT32_MAX), 46 m_async_signal (-1), 47 m_arch(), 48 m_os(), 49 m_vendor(), 50 m_byte_order(eByteOrderHost), 51 m_pointer_byte_size(0) 52 { 53 m_rx_packet_listener.StartListeningForEvents(this, 54 Communication::eBroadcastBitPacketAvailable | 55 Communication::eBroadcastBitReadThreadDidExit); 56 } 57 58 //---------------------------------------------------------------------- 59 // Destructor 60 //---------------------------------------------------------------------- 61 GDBRemoteCommunication::~GDBRemoteCommunication() 62 { 63 m_rx_packet_listener.StopListeningForEvents(this, 64 Communication::eBroadcastBitPacketAvailable | 65 Communication::eBroadcastBitReadThreadDidExit); 66 if (IsConnected()) 67 { 68 StopReadThread(); 69 Disconnect(); 70 } 71 } 72 73 74 char 75 GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length) 76 { 77 int checksum = 0; 78 79 // We only need to compute the checksum if we are sending acks 80 if (m_send_acks) 81 { 82 for (size_t i = 0; i < payload_length; ++i) 83 checksum += payload[i]; 84 } 85 return checksum & 255; 86 } 87 88 size_t 89 GDBRemoteCommunication::SendAck (char ack_char) 90 { 91 Mutex::Locker locker(m_sequence_mutex); 92 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %c", ack_char); 93 ConnectionStatus status = eConnectionStatusSuccess; 94 return Write (&ack_char, 1, status, NULL) == 1; 95 } 96 97 size_t 98 GDBRemoteCommunication::SendPacketAndWaitForResponse 99 ( 100 const char *payload, 101 StringExtractorGDBRemote &response, 102 uint32_t timeout_seconds, 103 bool send_async 104 ) 105 { 106 return SendPacketAndWaitForResponse (payload, 107 ::strlen (payload), 108 response, 109 timeout_seconds, 110 send_async); 111 } 112 113 size_t 114 GDBRemoteCommunication::SendPacketAndWaitForResponse 115 ( 116 const char *payload, 117 size_t payload_length, 118 StringExtractorGDBRemote &response, 119 uint32_t timeout_seconds, 120 bool send_async 121 ) 122 { 123 Mutex::Locker locker; 124 TimeValue timeout_time; 125 timeout_time = TimeValue::Now(); 126 timeout_time.OffsetWithSeconds (timeout_seconds); 127 128 if (GetSequenceMutex (locker)) 129 { 130 if (SendPacketNoLock (payload, strlen(payload))) 131 return WaitForPacketNoLock (response, &timeout_time); 132 } 133 else 134 { 135 if (send_async) 136 { 137 Mutex::Locker async_locker (m_async_mutex); 138 m_async_packet.assign(payload, payload_length); 139 m_async_timeout = timeout_seconds; 140 m_async_packet_predicate.SetValue (true, eBroadcastNever); 141 142 bool timed_out = false; 143 if (SendInterrupt(locker, 1, &timed_out)) 144 { 145 if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) 146 { 147 response = m_async_response; 148 return response.GetStringRef().size(); 149 } 150 } 151 // if (timed_out) 152 // m_error.SetErrorString("Timeout."); 153 // else 154 // m_error.SetErrorString("Unknown error."); 155 } 156 else 157 { 158 // m_error.SetErrorString("Sequence mutex is locked."); 159 } 160 } 161 return 0; 162 } 163 164 //template<typename _Tp> 165 //class ScopedValueChanger 166 //{ 167 //public: 168 // // Take a value reference and the value to assign it to when this class 169 // // instance goes out of scope. 170 // ScopedValueChanger (_Tp &value_ref, _Tp value) : 171 // m_value_ref (value_ref), 172 // m_value (value) 173 // { 174 // } 175 // 176 // // This object is going out of scope, change the value pointed to by 177 // // m_value_ref to the value we got during construction which was stored in 178 // // m_value; 179 // ~ScopedValueChanger () 180 // { 181 // m_value_ref = m_value; 182 // } 183 //protected: 184 // _Tp &m_value_ref; // A reference to the value we will change when this object destructs 185 // _Tp m_value; // The value to assign to m_value_ref when this goes out of scope. 186 //}; 187 188 StateType 189 GDBRemoteCommunication::SendContinuePacketAndWaitForResponse 190 ( 191 ProcessGDBRemote *process, 192 const char *payload, 193 size_t packet_length, 194 StringExtractorGDBRemote &response 195 ) 196 { 197 LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 198 LogSP async_log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC)); 199 if (log) 200 log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__); 201 202 Mutex::Locker locker(m_sequence_mutex); 203 StateType state = eStateRunning; 204 205 if (SendPacket(payload, packet_length) == 0) 206 state = eStateInvalid; 207 208 BroadcastEvent(eBroadcastBitRunPacketSent, NULL); 209 m_is_running.SetValue (true, eBroadcastNever); 210 211 while (state == eStateRunning) 212 { 213 log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); 214 if (log) 215 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...)", __FUNCTION__); 216 217 if (WaitForPacket (response, (TimeValue*)NULL)) 218 { 219 log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); 220 async_log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC); 221 if (response.Empty()) 222 state = eStateInvalid; 223 else 224 { 225 const char stop_type = response.GetChar(); 226 if (log) 227 log->Printf ("GDBRemoteCommunication::%s () got '%c' packet", __FUNCTION__, stop_type); 228 switch (stop_type) 229 { 230 case 'T': 231 case 'S': 232 if (m_async_signal != -1) 233 { 234 if (async_log) 235 async_log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal)); 236 237 // Save off the async signal we are supposed to send 238 const int async_signal = m_async_signal; 239 // Clear the async signal member so we don't end up 240 // sending the signal multiple times... 241 m_async_signal = -1; 242 // Check which signal we stopped with 243 uint8_t signo = response.GetHexU8(255); 244 if (signo == async_signal) 245 { 246 if (async_log) 247 async_log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo)); 248 249 // We already stopped with a signal that we wanted 250 // to stop with, so we are done 251 response.SetFilePos (0); 252 } 253 else 254 { 255 // We stopped with a different signal that the one 256 // we wanted to stop with, so now we must resume 257 // with the signal we want 258 char signal_packet[32]; 259 int signal_packet_len = 0; 260 signal_packet_len = ::snprintf (signal_packet, 261 sizeof (signal_packet), 262 "C%2.2x", 263 async_signal); 264 265 if (async_log) 266 async_log->Printf ("async: stopped with signal %s, resume with %s", 267 Host::GetSignalAsCString (signo), 268 Host::GetSignalAsCString (async_signal)); 269 270 if (SendPacket(signal_packet, signal_packet_len) == 0) 271 { 272 if (async_log) 273 async_log->Printf ("async: error: failed to resume with %s", 274 Host::GetSignalAsCString (async_signal)); 275 state = eStateInvalid; 276 break; 277 } 278 else 279 continue; 280 } 281 } 282 else if (m_async_packet_predicate.GetValue()) 283 { 284 if (async_log) 285 async_log->Printf ("async: send async packet: %s", 286 m_async_packet.c_str()); 287 288 // We are supposed to send an asynchronous packet while 289 // we are running. 290 m_async_response.Clear(); 291 if (!m_async_packet.empty()) 292 { 293 SendPacketAndWaitForResponse (&m_async_packet[0], 294 m_async_packet.size(), 295 m_async_response, 296 m_async_timeout, 297 false); 298 } 299 // Let the other thread that was trying to send the async 300 // packet know that the packet has been sent. 301 m_async_packet_predicate.SetValue(false, eBroadcastAlways); 302 303 if (async_log) 304 async_log->Printf ("async: resume after async response received: %s", 305 m_async_response.GetStringRef().c_str()); 306 307 // Continue again 308 if (SendPacket("c", 1) == 0) 309 { 310 state = eStateInvalid; 311 break; 312 } 313 else 314 continue; 315 } 316 // Stop with signal and thread info 317 state = eStateStopped; 318 break; 319 320 case 'W': 321 // process exited 322 state = eStateExited; 323 break; 324 325 case 'O': 326 // STDOUT 327 { 328 std::string inferior_stdout; 329 inferior_stdout.reserve(response.GetBytesLeft () / 2); 330 char ch; 331 while ((ch = response.GetHexU8()) != '\0') 332 inferior_stdout.append(1, ch); 333 process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size()); 334 } 335 break; 336 337 case 'E': 338 // ERROR 339 state = eStateInvalid; 340 break; 341 342 default: 343 if (log) 344 log->Printf ("GDBRemoteCommunication::%s () got unrecognized async packet: '%s'", __FUNCTION__, stop_type); 345 break; 346 } 347 } 348 } 349 else 350 { 351 log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); 352 if (log) 353 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__); 354 state = eStateInvalid; 355 } 356 } 357 log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); 358 if (log) 359 log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state)); 360 response.SetFilePos(0); 361 m_is_running.SetValue (false, eBroadcastAlways); 362 return state; 363 } 364 365 size_t 366 GDBRemoteCommunication::SendPacket (const char *payload) 367 { 368 Mutex::Locker locker(m_sequence_mutex); 369 return SendPacketNoLock (payload, ::strlen (payload)); 370 } 371 372 size_t 373 GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length) 374 { 375 Mutex::Locker locker(m_sequence_mutex); 376 return SendPacketNoLock (payload, payload_length); 377 } 378 379 size_t 380 GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length) 381 { 382 if (IsConnected()) 383 { 384 StreamString packet(0, 4, eByteOrderBig); 385 386 packet.PutChar('$'); 387 packet.Write (payload, payload_length); 388 packet.PutChar('#'); 389 packet.PutHex8(CalculcateChecksum (payload, payload_length)); 390 391 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: %s", packet.GetData()); 392 ConnectionStatus status = eConnectionStatusSuccess; 393 size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); 394 if (bytes_written == packet.GetSize()) 395 { 396 if (m_send_acks) 397 { 398 if (GetAck (1) != '+') 399 return 0; 400 } 401 } 402 else 403 { 404 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "error: failed to send packet: %s", packet.GetData()); 405 } 406 return bytes_written; 407 } 408 return 0; 409 } 410 411 char 412 GDBRemoteCommunication::GetAck (uint32_t timeout_seconds) 413 { 414 StringExtractorGDBRemote response; 415 if (WaitForPacket (response, timeout_seconds) == 1) 416 return response.GetChar(); 417 return 0; 418 } 419 420 bool 421 GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker) 422 { 423 return locker.TryLock (m_sequence_mutex.GetMutex()); 424 } 425 426 bool 427 GDBRemoteCommunication::SendAsyncSignal (int signo) 428 { 429 m_async_signal = signo; 430 bool timed_out = false; 431 Mutex::Locker locker; 432 if (SendInterrupt (locker, 1, &timed_out)) 433 return true; 434 m_async_signal = -1; 435 return false; 436 } 437 438 // This function takes a mutex locker as a parameter in case the GetSequenceMutex 439 // actually succeeds. If it doesn't succeed in acquiring the sequence mutex 440 // (the expected result), then it will send the halt packet. If it does succeed 441 // then the caller that requested the interrupt will want to keep the sequence 442 // locked down so that no one else can send packets while the caller has control. 443 // This function usually gets called when we are running and need to stop the 444 // target. It can also be used when we are running and and we need to do something 445 // else (like read/write memory), so we need to interrupt the running process 446 // (gdb remote protocol requires this), and do what we need to do, then resume. 447 448 bool 449 GDBRemoteCommunication::SendInterrupt (Mutex::Locker& locker, uint32_t seconds_to_wait_for_stop, bool *timed_out) 450 { 451 if (timed_out) 452 *timed_out = false; 453 454 if (IsConnected() && IsRunning()) 455 { 456 // Only send an interrupt if our debugserver is running... 457 if (GetSequenceMutex (locker) == false) 458 { 459 // Someone has the mutex locked waiting for a response or for the 460 // inferior to stop, so send the interrupt on the down low... 461 char ctrl_c = '\x03'; 462 ConnectionStatus status = eConnectionStatusSuccess; 463 TimeValue timeout; 464 if (seconds_to_wait_for_stop) 465 { 466 timeout = TimeValue::Now(); 467 timeout.OffsetWithSeconds (seconds_to_wait_for_stop); 468 } 469 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "send packet: \\x03"); 470 if (Write (&ctrl_c, 1, status, NULL) > 0) 471 { 472 if (seconds_to_wait_for_stop) 473 m_is_running.WaitForValueEqualTo (false, &timeout, timed_out); 474 return true; 475 } 476 } 477 } 478 return false; 479 } 480 481 size_t 482 GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds) 483 { 484 TimeValue timeout_time; 485 timeout_time = TimeValue::Now(); 486 timeout_time.OffsetWithSeconds (timeout_seconds); 487 return WaitForPacketNoLock (response, &timeout_time); 488 } 489 490 size_t 491 GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, TimeValue* timeout_time_ptr) 492 { 493 Mutex::Locker locker(m_sequence_mutex); 494 return WaitForPacketNoLock (response, timeout_time_ptr); 495 } 496 497 size_t 498 GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, TimeValue* timeout_time_ptr) 499 { 500 bool checksum_error = false; 501 response.Clear (); 502 503 EventSP event_sp; 504 505 if (m_rx_packet_listener.WaitForEvent (timeout_time_ptr, event_sp)) 506 { 507 const uint32_t event_type = event_sp->GetType(); 508 if (event_type | Communication::eBroadcastBitPacketAvailable) 509 { 510 const EventDataBytes *event_bytes = EventDataBytes::GetEventDataFromEvent(event_sp.get()); 511 if (event_bytes) 512 { 513 const char * packet_data = (const char *)event_bytes->GetBytes(); 514 ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS, "read packet: %s", packet_data); 515 const size_t packet_size = event_bytes->GetByteSize(); 516 if (packet_data && packet_size > 0) 517 { 518 std::string &response_str = response.GetStringRef(); 519 if (packet_data[0] == '$') 520 { 521 bool success = false; 522 if (packet_size < 4) 523 ::fprintf (stderr, "Packet that starts with $ is too short: '%s'\n", packet_data); 524 else if (packet_data[packet_size-3] != '#' || 525 !::isxdigit (packet_data[packet_size-2]) || 526 !::isxdigit (packet_data[packet_size-1])) 527 ::fprintf (stderr, "Invalid checksum footer for packet: '%s'\n", packet_data); 528 else 529 success = true; 530 531 if (success) 532 response_str.assign (packet_data + 1, packet_size - 4); 533 if (m_send_acks) 534 { 535 char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16); 536 char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size()); 537 checksum_error = packet_checksum != actual_checksum; 538 // Send the ack or nack if needed 539 if (checksum_error || !success) 540 SendAck('-'); 541 else 542 SendAck('+'); 543 } 544 } 545 else 546 { 547 response_str.assign (packet_data, packet_size); 548 } 549 return response_str.size(); 550 } 551 } 552 } 553 else if (Communication::eBroadcastBitReadThreadDidExit) 554 { 555 // Our read thread exited on us so just fall through and return zero... 556 } 557 } 558 return 0; 559 } 560 561 void 562 GDBRemoteCommunication::AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, 563 ConnectionStatus status) 564 { 565 // Put the packet data into the buffer in a thread safe fashion 566 Mutex::Locker locker(m_bytes_mutex); 567 m_bytes.append ((const char *)src, src_len); 568 569 // Parse up the packets into gdb remote packets 570 while (!m_bytes.empty()) 571 { 572 // end_idx must be one past the last valid packet byte. Start 573 // it off with an invalid value that is the same as the current 574 // index. 575 size_t end_idx = 0; 576 577 switch (m_bytes[0]) 578 { 579 case '+': // Look for ack 580 case '-': // Look for cancel 581 case '\x03': // ^C to halt target 582 end_idx = 1; // The command is one byte long... 583 break; 584 585 case '$': 586 // Look for a standard gdb packet? 587 end_idx = m_bytes.find('#'); 588 if (end_idx != std::string::npos) 589 { 590 if (end_idx + 2 < m_bytes.size()) 591 { 592 end_idx += 3; 593 } 594 else 595 { 596 // Checksum bytes aren't all here yet 597 end_idx = std::string::npos; 598 } 599 } 600 break; 601 602 default: 603 break; 604 } 605 606 if (end_idx == std::string::npos) 607 { 608 //ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE, "GDBRemoteCommunication::%s packet not yet complete: '%s'",__FUNCTION__, m_bytes.c_str()); 609 return; 610 } 611 else if (end_idx > 0) 612 { 613 // We have a valid packet... 614 assert (end_idx <= m_bytes.size()); 615 std::auto_ptr<EventDataBytes> event_bytes_ap (new EventDataBytes (&m_bytes[0], end_idx)); 616 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "got full packet: %s", event_bytes_ap->GetBytes()); 617 BroadcastEvent (eBroadcastBitPacketAvailable, event_bytes_ap.release()); 618 m_bytes.erase(0, end_idx); 619 } 620 else 621 { 622 assert (1 <= m_bytes.size()); 623 ProcessGDBRemoteLog::LogIf (GDBR_LOG_COMM, "GDBRemoteCommunication::%s tossing junk byte at %c",__FUNCTION__, m_bytes[0]); 624 m_bytes.erase(0, 1); 625 } 626 } 627 } 628 629 lldb::pid_t 630 GDBRemoteCommunication::GetCurrentProcessID (uint32_t timeout_seconds) 631 { 632 StringExtractorGDBRemote response; 633 if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, timeout_seconds, false)) 634 { 635 if (response.GetChar() == 'Q') 636 if (response.GetChar() == 'C') 637 return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID); 638 } 639 return LLDB_INVALID_PROCESS_ID; 640 } 641 642 bool 643 GDBRemoteCommunication::GetLaunchSuccess (uint32_t timeout_seconds, std::string &error_str) 644 { 645 error_str.clear(); 646 StringExtractorGDBRemote response; 647 if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, timeout_seconds, false)) 648 { 649 if (response.IsOKPacket()) 650 return true; 651 if (response.GetChar() == 'E') 652 { 653 // A string the describes what failed when launching... 654 error_str = response.GetStringRef().substr(1); 655 } 656 else 657 { 658 error_str.assign ("unknown error occurred launching process"); 659 } 660 } 661 else 662 { 663 error_str.assign ("failed to send the qLaunchSuccess packet"); 664 } 665 return false; 666 } 667 668 int 669 GDBRemoteCommunication::SendArgumentsPacket (char const *argv[], uint32_t timeout_seconds) 670 { 671 if (argv && argv[0]) 672 { 673 StreamString packet; 674 packet.PutChar('A'); 675 const char *arg; 676 for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i) 677 { 678 const int arg_len = strlen(arg); 679 if (i > 0) 680 packet.PutChar(','); 681 packet.Printf("%i,%i,", arg_len * 2, i); 682 packet.PutBytesAsRawHex8(arg, arg_len, eByteOrderHost, eByteOrderHost); 683 } 684 685 StringExtractorGDBRemote response; 686 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false)) 687 { 688 if (response.IsOKPacket()) 689 return 0; 690 uint8_t error = response.GetError(); 691 if (error) 692 return error; 693 } 694 } 695 return -1; 696 } 697 698 int 699 GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value, uint32_t timeout_seconds) 700 { 701 if (name_equal_value && name_equal_value[0]) 702 { 703 StreamString packet; 704 packet.Printf("QEnvironment:%s", name_equal_value); 705 StringExtractorGDBRemote response; 706 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false)) 707 { 708 if (response.IsOKPacket()) 709 return 0; 710 uint8_t error = response.GetError(); 711 if (error) 712 return error; 713 } 714 } 715 return -1; 716 } 717 718 bool 719 GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds) 720 { 721 m_arch.Clear(); 722 m_os.Clear(); 723 m_vendor.Clear(); 724 m_byte_order = eByteOrderHost; 725 m_pointer_byte_size = 0; 726 727 StringExtractorGDBRemote response; 728 if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false)) 729 { 730 if (response.IsUnsupportedPacket()) 731 return false; 732 733 734 std::string name; 735 std::string value; 736 while (response.GetNameColonValue(name, value)) 737 { 738 if (name.compare("cputype") == 0) 739 { 740 // exception type in big endian hex 741 m_arch.SetCPUType(Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0)); 742 } 743 else if (name.compare("cpusubtype") == 0) 744 { 745 // exception count in big endian hex 746 m_arch.SetCPUSubtype(Args::StringToUInt32 (value.c_str(), 0, 0)); 747 } 748 else if (name.compare("ostype") == 0) 749 { 750 // exception data in big endian hex 751 m_os.SetCString(value.c_str()); 752 } 753 else if (name.compare("vendor") == 0) 754 { 755 m_vendor.SetCString(value.c_str()); 756 } 757 else if (name.compare("endian") == 0) 758 { 759 if (value.compare("little") == 0) 760 m_byte_order = eByteOrderLittle; 761 else if (value.compare("big") == 0) 762 m_byte_order = eByteOrderBig; 763 else if (value.compare("pdp") == 0) 764 m_byte_order = eByteOrderPDP; 765 } 766 else if (name.compare("ptrsize") == 0) 767 { 768 m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); 769 } 770 } 771 } 772 return HostInfoIsValid(); 773 } 774 775 int 776 GDBRemoteCommunication::SendAttach 777 ( 778 lldb::pid_t pid, 779 uint32_t timeout_seconds, 780 StringExtractorGDBRemote& response 781 ) 782 { 783 if (pid != LLDB_INVALID_PROCESS_ID) 784 { 785 StreamString packet; 786 packet.Printf("vAttach;%x", pid); 787 788 if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, timeout_seconds, false)) 789 { 790 if (response.IsErrorPacket()) 791 return response.GetError(); 792 return 0; 793 } 794 } 795 return -1; 796 } 797 798 const lldb_private::ArchSpec & 799 GDBRemoteCommunication::GetHostArchitecture () 800 { 801 if (!HostInfoIsValid ()) 802 GetHostInfo (1); 803 return m_arch; 804 } 805 806 const lldb_private::ConstString & 807 GDBRemoteCommunication::GetOSString () 808 { 809 if (!HostInfoIsValid ()) 810 GetHostInfo (1); 811 return m_os; 812 } 813 814 const lldb_private::ConstString & 815 GDBRemoteCommunication::GetVendorString() 816 { 817 if (!HostInfoIsValid ()) 818 GetHostInfo (1); 819 return m_vendor; 820 } 821 822 lldb::ByteOrder 823 GDBRemoteCommunication::GetByteOrder () 824 { 825 if (!HostInfoIsValid ()) 826 GetHostInfo (1); 827 return m_byte_order; 828 } 829 830 uint32_t 831 GDBRemoteCommunication::GetAddressByteSize () 832 { 833 if (!HostInfoIsValid ()) 834 GetHostInfo (1); 835 return m_pointer_byte_size; 836 } 837 838 addr_t 839 GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions, uint32_t timeout_seconds) 840 { 841 char packet[64]; 842 ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size, 843 permissions & lldb::ePermissionsReadable ? "r" : "", 844 permissions & lldb::ePermissionsWritable ? "w" : "", 845 permissions & lldb::ePermissionsExecutable ? "x" : ""); 846 StringExtractorGDBRemote response; 847 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false)) 848 { 849 if (!response.IsErrorPacket()) 850 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 851 } 852 return LLDB_INVALID_ADDRESS; 853 } 854 855 bool 856 GDBRemoteCommunication::DeallocateMemory (addr_t addr, uint32_t timeout_seconds) 857 { 858 char packet[64]; 859 snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr); 860 StringExtractorGDBRemote response; 861 if (SendPacketAndWaitForResponse (packet, response, timeout_seconds, false)) 862 { 863 if (response.IsOKPacket()) 864 return true; 865 } 866 return false; 867 } 868 869