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