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