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