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