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