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