1254721Semaste//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste 11254721Semaste#include "GDBRemoteCommunicationClient.h" 12254721Semaste 13254721Semaste// C Includes 14263363Semaste#include <sys/stat.h> 15263363Semaste 16254721Semaste// C++ Includes 17254721Semaste#include <sstream> 18254721Semaste 19254721Semaste// Other libraries and framework includes 20254721Semaste#include "llvm/ADT/Triple.h" 21254721Semaste#include "lldb/Interpreter/Args.h" 22254721Semaste#include "lldb/Core/ConnectionFileDescriptor.h" 23254721Semaste#include "lldb/Core/Log.h" 24254721Semaste#include "lldb/Core/State.h" 25263363Semaste#include "lldb/Core/StreamGDBRemote.h" 26254721Semaste#include "lldb/Core/StreamString.h" 27254721Semaste#include "lldb/Host/Endian.h" 28254721Semaste#include "lldb/Host/Host.h" 29254721Semaste#include "lldb/Host/TimeValue.h" 30254721Semaste 31254721Semaste// Project includes 32254721Semaste#include "Utility/StringExtractorGDBRemote.h" 33254721Semaste#include "ProcessGDBRemote.h" 34254721Semaste#include "ProcessGDBRemoteLog.h" 35263363Semaste#include "lldb/Host/Config.h" 36254721Semaste 37254721Semasteusing namespace lldb; 38254721Semasteusing namespace lldb_private; 39254721Semaste 40263363Semaste#ifdef LLDB_DISABLE_POSIX 41263363Semaste#define SIGSTOP 17 42263363Semaste#endif 43263363Semaste 44254721Semaste//---------------------------------------------------------------------- 45254721Semaste// GDBRemoteCommunicationClient constructor 46254721Semaste//---------------------------------------------------------------------- 47254721SemasteGDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : 48254721Semaste GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform), 49254721Semaste m_supports_not_sending_acks (eLazyBoolCalculate), 50254721Semaste m_supports_thread_suffix (eLazyBoolCalculate), 51254721Semaste m_supports_threads_in_stop_reply (eLazyBoolCalculate), 52254721Semaste m_supports_vCont_all (eLazyBoolCalculate), 53254721Semaste m_supports_vCont_any (eLazyBoolCalculate), 54254721Semaste m_supports_vCont_c (eLazyBoolCalculate), 55254721Semaste m_supports_vCont_C (eLazyBoolCalculate), 56254721Semaste m_supports_vCont_s (eLazyBoolCalculate), 57254721Semaste m_supports_vCont_S (eLazyBoolCalculate), 58254721Semaste m_qHostInfo_is_valid (eLazyBoolCalculate), 59254721Semaste m_qProcessInfo_is_valid (eLazyBoolCalculate), 60254721Semaste m_supports_alloc_dealloc_memory (eLazyBoolCalculate), 61254721Semaste m_supports_memory_region_info (eLazyBoolCalculate), 62254721Semaste m_supports_watchpoint_support_info (eLazyBoolCalculate), 63254721Semaste m_supports_detach_stay_stopped (eLazyBoolCalculate), 64254721Semaste m_watchpoints_trigger_after_instruction(eLazyBoolCalculate), 65254721Semaste m_attach_or_wait_reply(eLazyBoolCalculate), 66254721Semaste m_prepare_for_reg_writing_reply (eLazyBoolCalculate), 67263363Semaste m_supports_p (eLazyBoolCalculate), 68263367Semaste m_supports_QSaveRegisterState (eLazyBoolCalculate), 69269024Semaste m_supports_qXfer_libraries_read (eLazyBoolCalculate), 70269024Semaste m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate), 71269024Semaste m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), 72254721Semaste m_supports_qProcessInfoPID (true), 73254721Semaste m_supports_qfProcessInfo (true), 74254721Semaste m_supports_qUserName (true), 75254721Semaste m_supports_qGroupName (true), 76254721Semaste m_supports_qThreadStopInfo (true), 77254721Semaste m_supports_z0 (true), 78254721Semaste m_supports_z1 (true), 79254721Semaste m_supports_z2 (true), 80254721Semaste m_supports_z3 (true), 81254721Semaste m_supports_z4 (true), 82263363Semaste m_supports_QEnvironment (true), 83263363Semaste m_supports_QEnvironmentHexEncoded (true), 84254721Semaste m_curr_tid (LLDB_INVALID_THREAD_ID), 85254721Semaste m_curr_tid_run (LLDB_INVALID_THREAD_ID), 86254721Semaste m_num_supported_hardware_watchpoints (0), 87254721Semaste m_async_mutex (Mutex::eMutexTypeRecursive), 88254721Semaste m_async_packet_predicate (false), 89254721Semaste m_async_packet (), 90269024Semaste m_async_result (PacketResult::Success), 91254721Semaste m_async_response (), 92254721Semaste m_async_signal (-1), 93254721Semaste m_thread_id_to_used_usec_map (), 94254721Semaste m_host_arch(), 95254721Semaste m_process_arch(), 96254721Semaste m_os_version_major (UINT32_MAX), 97254721Semaste m_os_version_minor (UINT32_MAX), 98263363Semaste m_os_version_update (UINT32_MAX), 99263363Semaste m_os_build (), 100263363Semaste m_os_kernel (), 101263363Semaste m_hostname (), 102269024Semaste m_default_packet_timeout (0), 103269024Semaste m_max_packet_size (0) 104254721Semaste{ 105254721Semaste} 106254721Semaste 107254721Semaste//---------------------------------------------------------------------- 108254721Semaste// Destructor 109254721Semaste//---------------------------------------------------------------------- 110254721SemasteGDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() 111254721Semaste{ 112254721Semaste if (IsConnected()) 113254721Semaste Disconnect(); 114254721Semaste} 115254721Semaste 116254721Semastebool 117254721SemasteGDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr) 118254721Semaste{ 119263367Semaste ResetDiscoverableSettings(); 120263367Semaste 121254721Semaste // Start the read thread after we send the handshake ack since if we 122254721Semaste // fail to send the handshake ack, there is no reason to continue... 123254721Semaste if (SendAck()) 124263367Semaste { 125269024Semaste // Wait for any responses that might have been queued up in the remote 126269024Semaste // GDB server and flush them all 127269024Semaste StringExtractorGDBRemote response; 128269024Semaste PacketResult packet_result = PacketResult::Success; 129269024Semaste const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response 130269024Semaste while (packet_result == PacketResult::Success) 131269024Semaste packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec); 132269024Semaste 133263367Semaste // The return value from QueryNoAckModeSupported() is true if the packet 134263367Semaste // was sent and _any_ response (including UNIMPLEMENTED) was received), 135263367Semaste // or false if no response was received. This quickly tells us if we have 136263367Semaste // a live connection to a remote GDB server... 137263367Semaste if (QueryNoAckModeSupported()) 138263367Semaste { 139269024Semaste#if 0 140269024Semaste // Set above line to "#if 1" to test packet speed if remote GDB server 141269024Semaste // supports the qSpeedTest packet... 142269024Semaste TestPacketSpeed(10000); 143269024Semaste#endif 144263367Semaste return true; 145263367Semaste } 146263367Semaste else 147263367Semaste { 148263367Semaste if (error_ptr) 149263367Semaste error_ptr->SetErrorString("failed to get reply to handshake packet"); 150263367Semaste } 151263367Semaste } 152263367Semaste else 153263367Semaste { 154263367Semaste if (error_ptr) 155263367Semaste error_ptr->SetErrorString("failed to send the handshake ack"); 156263367Semaste } 157254721Semaste return false; 158254721Semaste} 159254721Semaste 160263367Semastebool 161269024SemasteGDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported () 162269024Semaste{ 163269024Semaste if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) 164269024Semaste { 165269024Semaste GetRemoteQSupported(); 166269024Semaste } 167269024Semaste return (m_supports_augmented_libraries_svr4_read == eLazyBoolYes); 168269024Semaste} 169269024Semaste 170269024Semastebool 171269024SemasteGDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported () 172269024Semaste{ 173269024Semaste if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) 174269024Semaste { 175269024Semaste GetRemoteQSupported(); 176269024Semaste } 177269024Semaste return (m_supports_qXfer_libraries_svr4_read == eLazyBoolYes); 178269024Semaste} 179269024Semaste 180269024Semastebool 181269024SemasteGDBRemoteCommunicationClient::GetQXferLibrariesReadSupported () 182269024Semaste{ 183269024Semaste if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) 184269024Semaste { 185269024Semaste GetRemoteQSupported(); 186269024Semaste } 187269024Semaste return (m_supports_qXfer_libraries_read == eLazyBoolYes); 188269024Semaste} 189269024Semaste 190269024Semasteuint64_t 191269024SemasteGDBRemoteCommunicationClient::GetRemoteMaxPacketSize() 192269024Semaste{ 193269024Semaste if (m_max_packet_size == 0) 194269024Semaste { 195269024Semaste GetRemoteQSupported(); 196269024Semaste } 197269024Semaste return m_max_packet_size; 198269024Semaste} 199269024Semaste 200269024Semastebool 201254721SemasteGDBRemoteCommunicationClient::QueryNoAckModeSupported () 202254721Semaste{ 203254721Semaste if (m_supports_not_sending_acks == eLazyBoolCalculate) 204254721Semaste { 205254721Semaste m_send_acks = true; 206254721Semaste m_supports_not_sending_acks = eLazyBoolNo; 207254721Semaste 208254721Semaste StringExtractorGDBRemote response; 209269024Semaste if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success) 210254721Semaste { 211254721Semaste if (response.IsOKResponse()) 212254721Semaste { 213254721Semaste m_send_acks = false; 214254721Semaste m_supports_not_sending_acks = eLazyBoolYes; 215254721Semaste } 216263367Semaste return true; 217254721Semaste } 218254721Semaste } 219263367Semaste return false; 220254721Semaste} 221254721Semaste 222254721Semastevoid 223254721SemasteGDBRemoteCommunicationClient::GetListThreadsInStopReplySupported () 224254721Semaste{ 225254721Semaste if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) 226254721Semaste { 227254721Semaste m_supports_threads_in_stop_reply = eLazyBoolNo; 228254721Semaste 229254721Semaste StringExtractorGDBRemote response; 230269024Semaste if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success) 231254721Semaste { 232254721Semaste if (response.IsOKResponse()) 233254721Semaste m_supports_threads_in_stop_reply = eLazyBoolYes; 234254721Semaste } 235254721Semaste } 236254721Semaste} 237254721Semaste 238254721Semastebool 239254721SemasteGDBRemoteCommunicationClient::GetVAttachOrWaitSupported () 240254721Semaste{ 241254721Semaste if (m_attach_or_wait_reply == eLazyBoolCalculate) 242254721Semaste { 243254721Semaste m_attach_or_wait_reply = eLazyBoolNo; 244254721Semaste 245254721Semaste StringExtractorGDBRemote response; 246269024Semaste if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success) 247254721Semaste { 248254721Semaste if (response.IsOKResponse()) 249254721Semaste m_attach_or_wait_reply = eLazyBoolYes; 250254721Semaste } 251254721Semaste } 252254721Semaste if (m_attach_or_wait_reply == eLazyBoolYes) 253254721Semaste return true; 254254721Semaste else 255254721Semaste return false; 256254721Semaste} 257254721Semaste 258254721Semastebool 259254721SemasteGDBRemoteCommunicationClient::GetSyncThreadStateSupported () 260254721Semaste{ 261254721Semaste if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) 262254721Semaste { 263254721Semaste m_prepare_for_reg_writing_reply = eLazyBoolNo; 264254721Semaste 265254721Semaste StringExtractorGDBRemote response; 266269024Semaste if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success) 267254721Semaste { 268254721Semaste if (response.IsOKResponse()) 269254721Semaste m_prepare_for_reg_writing_reply = eLazyBoolYes; 270254721Semaste } 271254721Semaste } 272254721Semaste if (m_prepare_for_reg_writing_reply == eLazyBoolYes) 273254721Semaste return true; 274254721Semaste else 275254721Semaste return false; 276254721Semaste} 277254721Semaste 278254721Semaste 279254721Semastevoid 280254721SemasteGDBRemoteCommunicationClient::ResetDiscoverableSettings() 281254721Semaste{ 282254721Semaste m_supports_not_sending_acks = eLazyBoolCalculate; 283254721Semaste m_supports_thread_suffix = eLazyBoolCalculate; 284254721Semaste m_supports_threads_in_stop_reply = eLazyBoolCalculate; 285254721Semaste m_supports_vCont_c = eLazyBoolCalculate; 286254721Semaste m_supports_vCont_C = eLazyBoolCalculate; 287254721Semaste m_supports_vCont_s = eLazyBoolCalculate; 288254721Semaste m_supports_vCont_S = eLazyBoolCalculate; 289263363Semaste m_supports_p = eLazyBoolCalculate; 290263367Semaste m_supports_QSaveRegisterState = eLazyBoolCalculate; 291254721Semaste m_qHostInfo_is_valid = eLazyBoolCalculate; 292254721Semaste m_qProcessInfo_is_valid = eLazyBoolCalculate; 293254721Semaste m_supports_alloc_dealloc_memory = eLazyBoolCalculate; 294254721Semaste m_supports_memory_region_info = eLazyBoolCalculate; 295254721Semaste m_prepare_for_reg_writing_reply = eLazyBoolCalculate; 296254721Semaste m_attach_or_wait_reply = eLazyBoolCalculate; 297269024Semaste m_supports_qXfer_libraries_read = eLazyBoolCalculate; 298269024Semaste m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; 299269024Semaste m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; 300254721Semaste 301254721Semaste m_supports_qProcessInfoPID = true; 302254721Semaste m_supports_qfProcessInfo = true; 303254721Semaste m_supports_qUserName = true; 304254721Semaste m_supports_qGroupName = true; 305254721Semaste m_supports_qThreadStopInfo = true; 306254721Semaste m_supports_z0 = true; 307254721Semaste m_supports_z1 = true; 308254721Semaste m_supports_z2 = true; 309254721Semaste m_supports_z3 = true; 310254721Semaste m_supports_z4 = true; 311263363Semaste m_supports_QEnvironment = true; 312263363Semaste m_supports_QEnvironmentHexEncoded = true; 313254721Semaste m_host_arch.Clear(); 314254721Semaste m_process_arch.Clear(); 315269024Semaste 316269024Semaste m_max_packet_size = 0; 317254721Semaste} 318254721Semaste 319269024Semastevoid 320269024SemasteGDBRemoteCommunicationClient::GetRemoteQSupported () 321269024Semaste{ 322269024Semaste // Clear out any capabilities we expect to see in the qSupported response 323269024Semaste m_supports_qXfer_libraries_svr4_read = eLazyBoolNo; 324269024Semaste m_supports_qXfer_libraries_read = eLazyBoolNo; 325269024Semaste m_supports_augmented_libraries_svr4_read = eLazyBoolNo; 326269024Semaste m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit 327254721Semaste 328269024Semaste StringExtractorGDBRemote response; 329269024Semaste if (SendPacketAndWaitForResponse("qSupported", 330269024Semaste response, 331269024Semaste /*send_async=*/false) == PacketResult::Success) 332269024Semaste { 333269024Semaste const char *response_cstr = response.GetStringRef().c_str(); 334269024Semaste if (::strstr (response_cstr, "qXfer:libraries-svr4:read+")) 335269024Semaste m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; 336269024Semaste if (::strstr (response_cstr, "augmented-libraries-svr4-read")) 337269024Semaste { 338269024Semaste m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied 339269024Semaste m_supports_augmented_libraries_svr4_read = eLazyBoolYes; 340269024Semaste } 341269024Semaste if (::strstr (response_cstr, "qXfer:libraries:read+")) 342269024Semaste m_supports_qXfer_libraries_read = eLazyBoolYes; 343269024Semaste 344269024Semaste const char *packet_size_str = ::strstr (response_cstr, "PacketSize="); 345269024Semaste if (packet_size_str) 346269024Semaste { 347269024Semaste StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize=")); 348269024Semaste m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX); 349269024Semaste if (m_max_packet_size == 0) 350269024Semaste { 351269024Semaste m_max_packet_size = UINT64_MAX; // Must have been a garbled response 352269024Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 353269024Semaste if (log) 354269024Semaste log->Printf ("Garbled PacketSize spec in qSupported response"); 355269024Semaste } 356269024Semaste } 357269024Semaste } 358269024Semaste} 359269024Semaste 360254721Semastebool 361254721SemasteGDBRemoteCommunicationClient::GetThreadSuffixSupported () 362254721Semaste{ 363254721Semaste if (m_supports_thread_suffix == eLazyBoolCalculate) 364254721Semaste { 365254721Semaste StringExtractorGDBRemote response; 366254721Semaste m_supports_thread_suffix = eLazyBoolNo; 367269024Semaste if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success) 368254721Semaste { 369254721Semaste if (response.IsOKResponse()) 370254721Semaste m_supports_thread_suffix = eLazyBoolYes; 371254721Semaste } 372254721Semaste } 373254721Semaste return m_supports_thread_suffix; 374254721Semaste} 375254721Semastebool 376254721SemasteGDBRemoteCommunicationClient::GetVContSupported (char flavor) 377254721Semaste{ 378254721Semaste if (m_supports_vCont_c == eLazyBoolCalculate) 379254721Semaste { 380254721Semaste StringExtractorGDBRemote response; 381254721Semaste m_supports_vCont_any = eLazyBoolNo; 382254721Semaste m_supports_vCont_all = eLazyBoolNo; 383254721Semaste m_supports_vCont_c = eLazyBoolNo; 384254721Semaste m_supports_vCont_C = eLazyBoolNo; 385254721Semaste m_supports_vCont_s = eLazyBoolNo; 386254721Semaste m_supports_vCont_S = eLazyBoolNo; 387269024Semaste if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success) 388254721Semaste { 389254721Semaste const char *response_cstr = response.GetStringRef().c_str(); 390254721Semaste if (::strstr (response_cstr, ";c")) 391254721Semaste m_supports_vCont_c = eLazyBoolYes; 392254721Semaste 393254721Semaste if (::strstr (response_cstr, ";C")) 394254721Semaste m_supports_vCont_C = eLazyBoolYes; 395254721Semaste 396254721Semaste if (::strstr (response_cstr, ";s")) 397254721Semaste m_supports_vCont_s = eLazyBoolYes; 398254721Semaste 399254721Semaste if (::strstr (response_cstr, ";S")) 400254721Semaste m_supports_vCont_S = eLazyBoolYes; 401254721Semaste 402254721Semaste if (m_supports_vCont_c == eLazyBoolYes && 403254721Semaste m_supports_vCont_C == eLazyBoolYes && 404254721Semaste m_supports_vCont_s == eLazyBoolYes && 405254721Semaste m_supports_vCont_S == eLazyBoolYes) 406254721Semaste { 407254721Semaste m_supports_vCont_all = eLazyBoolYes; 408254721Semaste } 409254721Semaste 410254721Semaste if (m_supports_vCont_c == eLazyBoolYes || 411254721Semaste m_supports_vCont_C == eLazyBoolYes || 412254721Semaste m_supports_vCont_s == eLazyBoolYes || 413254721Semaste m_supports_vCont_S == eLazyBoolYes) 414254721Semaste { 415254721Semaste m_supports_vCont_any = eLazyBoolYes; 416254721Semaste } 417254721Semaste } 418254721Semaste } 419254721Semaste 420254721Semaste switch (flavor) 421254721Semaste { 422254721Semaste case 'a': return m_supports_vCont_any; 423254721Semaste case 'A': return m_supports_vCont_all; 424254721Semaste case 'c': return m_supports_vCont_c; 425254721Semaste case 'C': return m_supports_vCont_C; 426254721Semaste case 's': return m_supports_vCont_s; 427254721Semaste case 'S': return m_supports_vCont_S; 428254721Semaste default: break; 429254721Semaste } 430254721Semaste return false; 431254721Semaste} 432254721Semaste 433263363Semaste// Check if the target supports 'p' packet. It sends out a 'p' 434263363Semaste// packet and checks the response. A normal packet will tell us 435263363Semaste// that support is available. 436263363Semaste// 437263363Semaste// Takes a valid thread ID because p needs to apply to a thread. 438263363Semastebool 439263363SemasteGDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid) 440263363Semaste{ 441263363Semaste if (m_supports_p == eLazyBoolCalculate) 442263363Semaste { 443263363Semaste StringExtractorGDBRemote response; 444263363Semaste m_supports_p = eLazyBoolNo; 445263363Semaste char packet[256]; 446263363Semaste if (GetThreadSuffixSupported()) 447263363Semaste snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid); 448263363Semaste else 449263363Semaste snprintf(packet, sizeof(packet), "p0"); 450263363Semaste 451269024Semaste if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success) 452263363Semaste { 453263363Semaste if (response.IsNormalResponse()) 454263363Semaste m_supports_p = eLazyBoolYes; 455263363Semaste } 456263363Semaste } 457263363Semaste return m_supports_p; 458263363Semaste} 459254721Semaste 460269024SemasteGDBRemoteCommunicationClient::PacketResult 461269024SemasteGDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses 462269024Semaste( 463269024Semaste const char *payload_prefix, 464269024Semaste std::string &response_string 465269024Semaste) 466269024Semaste{ 467269024Semaste Mutex::Locker locker; 468269024Semaste if (!GetSequenceMutex(locker, 469269024Semaste "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex")) 470269024Semaste { 471269024Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); 472269024Semaste if (log) 473269024Semaste log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'", 474269024Semaste payload_prefix); 475269024Semaste return PacketResult::ErrorNoSequenceLock; 476269024Semaste } 477269024Semaste 478269024Semaste response_string = ""; 479269024Semaste std::string payload_prefix_str(payload_prefix); 480269024Semaste unsigned int response_size = 0x1000; 481269024Semaste if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet 482269024Semaste response_size = GetRemoteMaxPacketSize(); 483269024Semaste } 484269024Semaste 485269024Semaste for (unsigned int offset = 0; true; offset += response_size) 486269024Semaste { 487269024Semaste StringExtractorGDBRemote this_response; 488269024Semaste // Construct payload 489269024Semaste char sizeDescriptor[128]; 490269024Semaste snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size); 491269024Semaste PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(), 492269024Semaste this_response, 493269024Semaste /*send_async=*/false); 494269024Semaste if (result != PacketResult::Success) 495269024Semaste return result; 496269024Semaste 497269024Semaste const std::string &this_string = this_response.GetStringRef(); 498269024Semaste 499269024Semaste // Check for m or l as first character; l seems to mean this is the last chunk 500269024Semaste char first_char = *this_string.c_str(); 501269024Semaste if (first_char != 'm' && first_char != 'l') 502269024Semaste { 503269024Semaste return PacketResult::ErrorReplyInvalid; 504269024Semaste } 505269024Semaste // Skip past m or l 506269024Semaste const char *s = this_string.c_str() + 1; 507269024Semaste 508269024Semaste // Concatenate the result so far 509269024Semaste response_string += s; 510269024Semaste if (first_char == 'l') 511269024Semaste // We're done 512269024Semaste return PacketResult::Success; 513269024Semaste } 514269024Semaste} 515269024Semaste 516269024SemasteGDBRemoteCommunicationClient::PacketResult 517254721SemasteGDBRemoteCommunicationClient::SendPacketAndWaitForResponse 518254721Semaste( 519254721Semaste const char *payload, 520254721Semaste StringExtractorGDBRemote &response, 521254721Semaste bool send_async 522254721Semaste) 523254721Semaste{ 524254721Semaste return SendPacketAndWaitForResponse (payload, 525254721Semaste ::strlen (payload), 526254721Semaste response, 527254721Semaste send_async); 528254721Semaste} 529254721Semaste 530269024SemasteGDBRemoteCommunicationClient::PacketResult 531269024SemasteGDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload, 532269024Semaste size_t payload_length, 533269024Semaste StringExtractorGDBRemote &response) 534269024Semaste{ 535269024Semaste PacketResult packet_result = SendPacketNoLock (payload, payload_length); 536269024Semaste if (packet_result == PacketResult::Success) 537269024Semaste packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()); 538269024Semaste return packet_result; 539269024Semaste} 540269024Semaste 541269024SemasteGDBRemoteCommunicationClient::PacketResult 542254721SemasteGDBRemoteCommunicationClient::SendPacketAndWaitForResponse 543254721Semaste( 544254721Semaste const char *payload, 545254721Semaste size_t payload_length, 546254721Semaste StringExtractorGDBRemote &response, 547254721Semaste bool send_async 548254721Semaste) 549254721Semaste{ 550269024Semaste PacketResult packet_result = PacketResult::ErrorSendFailed; 551254721Semaste Mutex::Locker locker; 552254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 553254721Semaste size_t response_len = 0; 554254721Semaste if (GetSequenceMutex (locker)) 555254721Semaste { 556269024Semaste packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response); 557254721Semaste } 558254721Semaste else 559254721Semaste { 560254721Semaste if (send_async) 561254721Semaste { 562254721Semaste if (IsRunning()) 563254721Semaste { 564254721Semaste Mutex::Locker async_locker (m_async_mutex); 565254721Semaste m_async_packet.assign(payload, payload_length); 566254721Semaste m_async_packet_predicate.SetValue (true, eBroadcastNever); 567254721Semaste 568254721Semaste if (log) 569254721Semaste log->Printf ("async: async packet = %s", m_async_packet.c_str()); 570254721Semaste 571254721Semaste bool timed_out = false; 572254721Semaste if (SendInterrupt(locker, 2, timed_out)) 573254721Semaste { 574254721Semaste if (m_interrupt_sent) 575254721Semaste { 576254721Semaste m_interrupt_sent = false; 577254721Semaste TimeValue timeout_time; 578254721Semaste timeout_time = TimeValue::Now(); 579254721Semaste timeout_time.OffsetWithSeconds (m_packet_timeout); 580254721Semaste 581254721Semaste if (log) 582254721Semaste log->Printf ("async: sent interrupt"); 583254721Semaste 584254721Semaste if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) 585254721Semaste { 586254721Semaste if (log) 587254721Semaste log->Printf ("async: got response"); 588254721Semaste 589254721Semaste // Swap the response buffer to avoid malloc and string copy 590254721Semaste response.GetStringRef().swap (m_async_response.GetStringRef()); 591254721Semaste response_len = response.GetStringRef().size(); 592269024Semaste packet_result = m_async_result; 593254721Semaste } 594254721Semaste else 595254721Semaste { 596254721Semaste if (log) 597254721Semaste log->Printf ("async: timed out waiting for response"); 598254721Semaste } 599254721Semaste 600254721Semaste // Make sure we wait until the continue packet has been sent again... 601254721Semaste if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out)) 602254721Semaste { 603254721Semaste if (log) 604254721Semaste { 605254721Semaste if (timed_out) 606254721Semaste log->Printf ("async: timed out waiting for process to resume, but process was resumed"); 607254721Semaste else 608254721Semaste log->Printf ("async: async packet sent"); 609254721Semaste } 610254721Semaste } 611254721Semaste else 612254721Semaste { 613254721Semaste if (log) 614254721Semaste log->Printf ("async: timed out waiting for process to resume"); 615254721Semaste } 616254721Semaste } 617254721Semaste else 618254721Semaste { 619254721Semaste // We had a racy condition where we went to send the interrupt 620254721Semaste // yet we were able to get the lock, so the process must have 621254721Semaste // just stopped? 622254721Semaste if (log) 623254721Semaste log->Printf ("async: got lock without sending interrupt"); 624254721Semaste // Send the packet normally since we got the lock 625269024Semaste packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response); 626254721Semaste } 627254721Semaste } 628254721Semaste else 629254721Semaste { 630254721Semaste if (log) 631254721Semaste log->Printf ("async: failed to interrupt"); 632254721Semaste } 633254721Semaste } 634254721Semaste else 635254721Semaste { 636254721Semaste if (log) 637254721Semaste log->Printf ("async: not running, async is ignored"); 638254721Semaste } 639254721Semaste } 640254721Semaste else 641254721Semaste { 642254721Semaste if (log) 643254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload); 644254721Semaste } 645254721Semaste } 646269024Semaste return packet_result; 647254721Semaste} 648254721Semaste 649254721Semastestatic const char *end_delimiter = "--end--;"; 650254721Semastestatic const int end_delimiter_len = 8; 651254721Semaste 652254721Semastestd::string 653254721SemasteGDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData 654254721Semaste( ProcessGDBRemote *process, 655254721Semaste StringExtractorGDBRemote& profileDataExtractor 656254721Semaste) 657254721Semaste{ 658254721Semaste std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map; 659254721Semaste std::stringstream final_output; 660254721Semaste std::string name, value; 661254721Semaste 662254721Semaste // Going to assuming thread_used_usec comes first, else bail out. 663254721Semaste while (profileDataExtractor.GetNameColonValue(name, value)) 664254721Semaste { 665254721Semaste if (name.compare("thread_used_id") == 0) 666254721Semaste { 667254721Semaste StringExtractor threadIDHexExtractor(value.c_str()); 668254721Semaste uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0); 669254721Semaste 670254721Semaste bool has_used_usec = false; 671254721Semaste uint32_t curr_used_usec = 0; 672254721Semaste std::string usec_name, usec_value; 673254721Semaste uint32_t input_file_pos = profileDataExtractor.GetFilePos(); 674254721Semaste if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) 675254721Semaste { 676254721Semaste if (usec_name.compare("thread_used_usec") == 0) 677254721Semaste { 678254721Semaste has_used_usec = true; 679254721Semaste curr_used_usec = strtoull(usec_value.c_str(), NULL, 0); 680254721Semaste } 681254721Semaste else 682254721Semaste { 683254721Semaste // We didn't find what we want, it is probably 684254721Semaste // an older version. Bail out. 685254721Semaste profileDataExtractor.SetFilePos(input_file_pos); 686254721Semaste } 687254721Semaste } 688254721Semaste 689254721Semaste if (has_used_usec) 690254721Semaste { 691254721Semaste uint32_t prev_used_usec = 0; 692254721Semaste std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id); 693254721Semaste if (iterator != m_thread_id_to_used_usec_map.end()) 694254721Semaste { 695254721Semaste prev_used_usec = m_thread_id_to_used_usec_map[thread_id]; 696254721Semaste } 697254721Semaste 698254721Semaste uint32_t real_used_usec = curr_used_usec - prev_used_usec; 699254721Semaste // A good first time record is one that runs for at least 0.25 sec 700254721Semaste bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000); 701254721Semaste bool good_subsequent_time = (prev_used_usec > 0) && 702254721Semaste ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id))); 703254721Semaste 704254721Semaste if (good_first_time || good_subsequent_time) 705254721Semaste { 706254721Semaste // We try to avoid doing too many index id reservation, 707254721Semaste // resulting in fast increase of index ids. 708254721Semaste 709254721Semaste final_output << name << ":"; 710254721Semaste int32_t index_id = process->AssignIndexIDToThread(thread_id); 711254721Semaste final_output << index_id << ";"; 712254721Semaste 713254721Semaste final_output << usec_name << ":" << usec_value << ";"; 714254721Semaste } 715254721Semaste else 716254721Semaste { 717254721Semaste // Skip past 'thread_used_name'. 718254721Semaste std::string local_name, local_value; 719254721Semaste profileDataExtractor.GetNameColonValue(local_name, local_value); 720254721Semaste } 721254721Semaste 722254721Semaste // Store current time as previous time so that they can be compared later. 723254721Semaste new_thread_id_to_used_usec_map[thread_id] = curr_used_usec; 724254721Semaste } 725254721Semaste else 726254721Semaste { 727254721Semaste // Bail out and use old string. 728254721Semaste final_output << name << ":" << value << ";"; 729254721Semaste } 730254721Semaste } 731254721Semaste else 732254721Semaste { 733254721Semaste final_output << name << ":" << value << ";"; 734254721Semaste } 735254721Semaste } 736254721Semaste final_output << end_delimiter; 737254721Semaste m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map; 738254721Semaste 739254721Semaste return final_output.str(); 740254721Semaste} 741254721Semaste 742254721SemasteStateType 743254721SemasteGDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse 744254721Semaste( 745254721Semaste ProcessGDBRemote *process, 746254721Semaste const char *payload, 747254721Semaste size_t packet_length, 748254721Semaste StringExtractorGDBRemote &response 749254721Semaste) 750254721Semaste{ 751254721Semaste m_curr_tid = LLDB_INVALID_THREAD_ID; 752254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); 753254721Semaste if (log) 754254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__); 755254721Semaste 756254721Semaste Mutex::Locker locker(m_sequence_mutex); 757254721Semaste StateType state = eStateRunning; 758254721Semaste 759254721Semaste BroadcastEvent(eBroadcastBitRunPacketSent, NULL); 760254721Semaste m_public_is_running.SetValue (true, eBroadcastNever); 761254721Semaste // Set the starting continue packet into "continue_packet". This packet 762254721Semaste // may change if we are interrupted and we continue after an async packet... 763254721Semaste std::string continue_packet(payload, packet_length); 764254721Semaste 765254721Semaste bool got_async_packet = false; 766254721Semaste 767254721Semaste while (state == eStateRunning) 768254721Semaste { 769254721Semaste if (!got_async_packet) 770254721Semaste { 771254721Semaste if (log) 772254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str()); 773269024Semaste if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success) 774254721Semaste state = eStateInvalid; 775254721Semaste 776254721Semaste m_private_is_running.SetValue (true, eBroadcastAlways); 777254721Semaste } 778254721Semaste 779254721Semaste got_async_packet = false; 780254721Semaste 781254721Semaste if (log) 782254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str()); 783254721Semaste 784269024Semaste if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX) == PacketResult::Success) 785254721Semaste { 786254721Semaste if (response.Empty()) 787254721Semaste state = eStateInvalid; 788254721Semaste else 789254721Semaste { 790254721Semaste const char stop_type = response.GetChar(); 791254721Semaste if (log) 792254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str()); 793254721Semaste switch (stop_type) 794254721Semaste { 795254721Semaste case 'T': 796254721Semaste case 'S': 797254721Semaste { 798254721Semaste if (process->GetStopID() == 0) 799254721Semaste { 800254721Semaste if (process->GetID() == LLDB_INVALID_PROCESS_ID) 801254721Semaste { 802254721Semaste lldb::pid_t pid = GetCurrentProcessID (); 803254721Semaste if (pid != LLDB_INVALID_PROCESS_ID) 804254721Semaste process->SetID (pid); 805254721Semaste } 806254721Semaste process->BuildDynamicRegisterInfo (true); 807254721Semaste } 808254721Semaste 809254721Semaste // Privately notify any internal threads that we have stopped 810254721Semaste // in case we wanted to interrupt our process, yet we might 811254721Semaste // send a packet and continue without returning control to the 812254721Semaste // user. 813254721Semaste m_private_is_running.SetValue (false, eBroadcastAlways); 814254721Semaste 815254721Semaste const uint8_t signo = response.GetHexU8 (UINT8_MAX); 816254721Semaste 817254721Semaste bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue(); 818254721Semaste if (continue_after_async || m_interrupt_sent) 819254721Semaste { 820254721Semaste // We sent an interrupt packet to stop the inferior process 821254721Semaste // for an async signal or to send an async packet while running 822254721Semaste // but we might have been single stepping and received the 823254721Semaste // stop packet for the step instead of for the interrupt packet. 824254721Semaste // Typically when an interrupt is sent a SIGINT or SIGSTOP 825254721Semaste // is used, so if we get anything else, we need to try and 826254721Semaste // get another stop reply packet that may have been sent 827254721Semaste // due to sending the interrupt when the target is stopped 828254721Semaste // which will just re-send a copy of the last stop reply 829254721Semaste // packet. If we don't do this, then the reply for our 830254721Semaste // async packet will be the repeat stop reply packet and cause 831254721Semaste // a lot of trouble for us! 832254721Semaste if (signo != SIGINT && signo != SIGSTOP) 833254721Semaste { 834254721Semaste continue_after_async = false; 835254721Semaste 836254721Semaste // We didn't get a a SIGINT or SIGSTOP, so try for a 837254721Semaste // very brief time (1 ms) to get another stop reply 838254721Semaste // packet to make sure it doesn't get in the way 839254721Semaste StringExtractorGDBRemote extra_stop_reply_packet; 840254721Semaste uint32_t timeout_usec = 1000; 841269024Semaste if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec) == PacketResult::Success) 842254721Semaste { 843254721Semaste switch (extra_stop_reply_packet.GetChar()) 844254721Semaste { 845254721Semaste case 'T': 846254721Semaste case 'S': 847254721Semaste // We did get an extra stop reply, which means 848254721Semaste // our interrupt didn't stop the target so we 849254721Semaste // shouldn't continue after the async signal 850254721Semaste // or packet is sent... 851254721Semaste continue_after_async = false; 852254721Semaste break; 853254721Semaste } 854254721Semaste } 855254721Semaste } 856254721Semaste } 857254721Semaste 858254721Semaste if (m_async_signal != -1) 859254721Semaste { 860254721Semaste if (log) 861254721Semaste log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal)); 862254721Semaste 863254721Semaste // Save off the async signal we are supposed to send 864254721Semaste const int async_signal = m_async_signal; 865254721Semaste // Clear the async signal member so we don't end up 866254721Semaste // sending the signal multiple times... 867254721Semaste m_async_signal = -1; 868254721Semaste // Check which signal we stopped with 869254721Semaste if (signo == async_signal) 870254721Semaste { 871254721Semaste if (log) 872254721Semaste log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo)); 873254721Semaste 874254721Semaste // We already stopped with a signal that we wanted 875254721Semaste // to stop with, so we are done 876254721Semaste } 877254721Semaste else 878254721Semaste { 879254721Semaste // We stopped with a different signal that the one 880254721Semaste // we wanted to stop with, so now we must resume 881254721Semaste // with the signal we want 882254721Semaste char signal_packet[32]; 883254721Semaste int signal_packet_len = 0; 884254721Semaste signal_packet_len = ::snprintf (signal_packet, 885254721Semaste sizeof (signal_packet), 886254721Semaste "C%2.2x", 887254721Semaste async_signal); 888254721Semaste 889254721Semaste if (log) 890254721Semaste log->Printf ("async: stopped with signal %s, resume with %s", 891254721Semaste Host::GetSignalAsCString (signo), 892254721Semaste Host::GetSignalAsCString (async_signal)); 893254721Semaste 894254721Semaste // Set the continue packet to resume even if the 895254721Semaste // interrupt didn't cause our stop (ignore continue_after_async) 896254721Semaste continue_packet.assign(signal_packet, signal_packet_len); 897254721Semaste continue; 898254721Semaste } 899254721Semaste } 900254721Semaste else if (m_async_packet_predicate.GetValue()) 901254721Semaste { 902254721Semaste Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); 903254721Semaste 904254721Semaste // We are supposed to send an asynchronous packet while 905269024Semaste // we are running. 906254721Semaste m_async_response.Clear(); 907254721Semaste if (m_async_packet.empty()) 908254721Semaste { 909269024Semaste m_async_result = PacketResult::ErrorSendFailed; 910269024Semaste if (packet_log) 911254721Semaste packet_log->Printf ("async: error: empty async packet"); 912254721Semaste 913254721Semaste } 914254721Semaste else 915254721Semaste { 916254721Semaste if (packet_log) 917254721Semaste packet_log->Printf ("async: sending packet"); 918254721Semaste 919269024Semaste m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0], 920269024Semaste m_async_packet.size(), 921269024Semaste m_async_response, 922269024Semaste false); 923254721Semaste } 924254721Semaste // Let the other thread that was trying to send the async 925254721Semaste // packet know that the packet has been sent and response is 926254721Semaste // ready... 927254721Semaste m_async_packet_predicate.SetValue(false, eBroadcastAlways); 928254721Semaste 929254721Semaste if (packet_log) 930254721Semaste packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async); 931254721Semaste 932254721Semaste // Set the continue packet to resume if our interrupt 933254721Semaste // for the async packet did cause the stop 934254721Semaste if (continue_after_async) 935254721Semaste { 936254721Semaste // Reverting this for now as it is causing deadlocks 937254721Semaste // in programs (<rdar://problem/11529853>). In the future 938254721Semaste // we should check our thread list and "do the right thing" 939254721Semaste // for new threads that show up while we stop and run async 940254721Semaste // packets. Setting the packet to 'c' to continue all threads 941254721Semaste // is the right thing to do 99.99% of the time because if a 942254721Semaste // thread was single stepping, and we sent an interrupt, we 943254721Semaste // will notice above that we didn't stop due to an interrupt 944254721Semaste // but stopped due to stepping and we would _not_ continue. 945254721Semaste continue_packet.assign (1, 'c'); 946254721Semaste continue; 947254721Semaste } 948254721Semaste } 949254721Semaste // Stop with signal and thread info 950254721Semaste state = eStateStopped; 951254721Semaste } 952254721Semaste break; 953254721Semaste 954254721Semaste case 'W': 955254721Semaste case 'X': 956254721Semaste // process exited 957254721Semaste state = eStateExited; 958254721Semaste break; 959254721Semaste 960254721Semaste case 'O': 961254721Semaste // STDOUT 962254721Semaste { 963254721Semaste got_async_packet = true; 964254721Semaste std::string inferior_stdout; 965254721Semaste inferior_stdout.reserve(response.GetBytesLeft () / 2); 966254721Semaste char ch; 967254721Semaste while ((ch = response.GetHexU8()) != '\0') 968254721Semaste inferior_stdout.append(1, ch); 969254721Semaste process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size()); 970254721Semaste } 971254721Semaste break; 972254721Semaste 973254721Semaste case 'A': 974254721Semaste // Async miscellaneous reply. Right now, only profile data is coming through this channel. 975254721Semaste { 976254721Semaste got_async_packet = true; 977254721Semaste std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A' 978254721Semaste if (m_partial_profile_data.length() > 0) 979254721Semaste { 980254721Semaste m_partial_profile_data.append(input); 981254721Semaste input = m_partial_profile_data; 982254721Semaste m_partial_profile_data.clear(); 983254721Semaste } 984254721Semaste 985254721Semaste size_t found, pos = 0, len = input.length(); 986254721Semaste while ((found = input.find(end_delimiter, pos)) != std::string::npos) 987254721Semaste { 988254721Semaste StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str()); 989254721Semaste std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor); 990254721Semaste process->BroadcastAsyncProfileData (profile_data); 991254721Semaste 992254721Semaste pos = found + end_delimiter_len; 993254721Semaste } 994254721Semaste 995254721Semaste if (pos < len) 996254721Semaste { 997254721Semaste // Last incomplete chunk. 998254721Semaste m_partial_profile_data = input.substr(pos); 999254721Semaste } 1000254721Semaste } 1001254721Semaste break; 1002254721Semaste 1003254721Semaste case 'E': 1004254721Semaste // ERROR 1005254721Semaste state = eStateInvalid; 1006254721Semaste break; 1007254721Semaste 1008254721Semaste default: 1009254721Semaste if (log) 1010254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__); 1011254721Semaste state = eStateInvalid; 1012254721Semaste break; 1013254721Semaste } 1014254721Semaste } 1015254721Semaste } 1016254721Semaste else 1017254721Semaste { 1018254721Semaste if (log) 1019254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__); 1020254721Semaste state = eStateInvalid; 1021254721Semaste } 1022254721Semaste } 1023254721Semaste if (log) 1024254721Semaste log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state)); 1025254721Semaste response.SetFilePos(0); 1026254721Semaste m_private_is_running.SetValue (false, eBroadcastAlways); 1027254721Semaste m_public_is_running.SetValue (false, eBroadcastAlways); 1028254721Semaste return state; 1029254721Semaste} 1030254721Semaste 1031254721Semastebool 1032254721SemasteGDBRemoteCommunicationClient::SendAsyncSignal (int signo) 1033254721Semaste{ 1034254721Semaste Mutex::Locker async_locker (m_async_mutex); 1035254721Semaste m_async_signal = signo; 1036254721Semaste bool timed_out = false; 1037254721Semaste Mutex::Locker locker; 1038254721Semaste if (SendInterrupt (locker, 1, timed_out)) 1039254721Semaste return true; 1040254721Semaste m_async_signal = -1; 1041254721Semaste return false; 1042254721Semaste} 1043254721Semaste 1044254721Semaste// This function takes a mutex locker as a parameter in case the GetSequenceMutex 1045254721Semaste// actually succeeds. If it doesn't succeed in acquiring the sequence mutex 1046254721Semaste// (the expected result), then it will send the halt packet. If it does succeed 1047254721Semaste// then the caller that requested the interrupt will want to keep the sequence 1048254721Semaste// locked down so that no one else can send packets while the caller has control. 1049254721Semaste// This function usually gets called when we are running and need to stop the 1050254721Semaste// target. It can also be used when we are running and and we need to do something 1051254721Semaste// else (like read/write memory), so we need to interrupt the running process 1052254721Semaste// (gdb remote protocol requires this), and do what we need to do, then resume. 1053254721Semaste 1054254721Semastebool 1055254721SemasteGDBRemoteCommunicationClient::SendInterrupt 1056254721Semaste( 1057254721Semaste Mutex::Locker& locker, 1058254721Semaste uint32_t seconds_to_wait_for_stop, 1059254721Semaste bool &timed_out 1060254721Semaste) 1061254721Semaste{ 1062254721Semaste timed_out = false; 1063254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); 1064254721Semaste 1065254721Semaste if (IsRunning()) 1066254721Semaste { 1067254721Semaste // Only send an interrupt if our debugserver is running... 1068254721Semaste if (GetSequenceMutex (locker)) 1069254721Semaste { 1070254721Semaste if (log) 1071254721Semaste log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt"); 1072254721Semaste } 1073254721Semaste else 1074254721Semaste { 1075254721Semaste // Someone has the mutex locked waiting for a response or for the 1076254721Semaste // inferior to stop, so send the interrupt on the down low... 1077254721Semaste char ctrl_c = '\x03'; 1078254721Semaste ConnectionStatus status = eConnectionStatusSuccess; 1079254721Semaste size_t bytes_written = Write (&ctrl_c, 1, status, NULL); 1080254721Semaste if (log) 1081254721Semaste log->PutCString("send packet: \\x03"); 1082254721Semaste if (bytes_written > 0) 1083254721Semaste { 1084254721Semaste m_interrupt_sent = true; 1085254721Semaste if (seconds_to_wait_for_stop) 1086254721Semaste { 1087254721Semaste TimeValue timeout; 1088254721Semaste if (seconds_to_wait_for_stop) 1089254721Semaste { 1090254721Semaste timeout = TimeValue::Now(); 1091254721Semaste timeout.OffsetWithSeconds (seconds_to_wait_for_stop); 1092254721Semaste } 1093254721Semaste if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out)) 1094254721Semaste { 1095254721Semaste if (log) 1096254721Semaste log->PutCString ("SendInterrupt () - sent interrupt, private state stopped"); 1097254721Semaste return true; 1098254721Semaste } 1099254721Semaste else 1100254721Semaste { 1101254721Semaste if (log) 1102254721Semaste log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume"); 1103254721Semaste } 1104254721Semaste } 1105254721Semaste else 1106254721Semaste { 1107254721Semaste if (log) 1108254721Semaste log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop..."); 1109254721Semaste return true; 1110254721Semaste } 1111254721Semaste } 1112254721Semaste else 1113254721Semaste { 1114254721Semaste if (log) 1115254721Semaste log->Printf ("SendInterrupt () - failed to write interrupt"); 1116254721Semaste } 1117254721Semaste return false; 1118254721Semaste } 1119254721Semaste } 1120254721Semaste else 1121254721Semaste { 1122254721Semaste if (log) 1123254721Semaste log->Printf ("SendInterrupt () - not running"); 1124254721Semaste } 1125254721Semaste return true; 1126254721Semaste} 1127254721Semaste 1128254721Semastelldb::pid_t 1129254721SemasteGDBRemoteCommunicationClient::GetCurrentProcessID () 1130254721Semaste{ 1131254721Semaste StringExtractorGDBRemote response; 1132269024Semaste if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success) 1133254721Semaste { 1134254721Semaste if (response.GetChar() == 'Q') 1135254721Semaste if (response.GetChar() == 'C') 1136254721Semaste return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID); 1137254721Semaste } 1138254721Semaste return LLDB_INVALID_PROCESS_ID; 1139254721Semaste} 1140254721Semaste 1141254721Semastebool 1142254721SemasteGDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str) 1143254721Semaste{ 1144254721Semaste error_str.clear(); 1145254721Semaste StringExtractorGDBRemote response; 1146269024Semaste if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success) 1147254721Semaste { 1148254721Semaste if (response.IsOKResponse()) 1149254721Semaste return true; 1150254721Semaste if (response.GetChar() == 'E') 1151254721Semaste { 1152254721Semaste // A string the describes what failed when launching... 1153254721Semaste error_str = response.GetStringRef().substr(1); 1154254721Semaste } 1155254721Semaste else 1156254721Semaste { 1157254721Semaste error_str.assign ("unknown error occurred launching process"); 1158254721Semaste } 1159254721Semaste } 1160254721Semaste else 1161254721Semaste { 1162254721Semaste error_str.assign ("timed out waiting for app to launch"); 1163254721Semaste } 1164254721Semaste return false; 1165254721Semaste} 1166254721Semaste 1167254721Semasteint 1168263367SemasteGDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &launch_info) 1169254721Semaste{ 1170263367Semaste // Since we don't get the send argv0 separate from the executable path, we need to 1171263367Semaste // make sure to use the actual exectuable path found in the launch_info... 1172263367Semaste std::vector<const char *> argv; 1173263367Semaste FileSpec exe_file = launch_info.GetExecutableFile(); 1174263367Semaste std::string exe_path; 1175263367Semaste const char *arg = NULL; 1176263367Semaste const Args &launch_args = launch_info.GetArguments(); 1177263367Semaste if (exe_file) 1178263367Semaste exe_path = exe_file.GetPath(); 1179263367Semaste else 1180254721Semaste { 1181263367Semaste arg = launch_args.GetArgumentAtIndex(0); 1182263367Semaste if (arg) 1183263367Semaste exe_path = arg; 1184263367Semaste } 1185263367Semaste if (!exe_path.empty()) 1186263367Semaste { 1187263367Semaste argv.push_back(exe_path.c_str()); 1188263367Semaste for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i) 1189263367Semaste { 1190263367Semaste if (arg) 1191263367Semaste argv.push_back(arg); 1192263367Semaste } 1193263367Semaste } 1194263367Semaste if (!argv.empty()) 1195263367Semaste { 1196254721Semaste StreamString packet; 1197254721Semaste packet.PutChar('A'); 1198263367Semaste for (size_t i = 0, n = argv.size(); i < n; ++i) 1199254721Semaste { 1200263367Semaste arg = argv[i]; 1201254721Semaste const int arg_len = strlen(arg); 1202254721Semaste if (i > 0) 1203254721Semaste packet.PutChar(','); 1204263367Semaste packet.Printf("%i,%i,", arg_len * 2, (int)i); 1205254721Semaste packet.PutBytesAsRawHex8 (arg, arg_len); 1206254721Semaste } 1207254721Semaste 1208254721Semaste StringExtractorGDBRemote response; 1209269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1210254721Semaste { 1211254721Semaste if (response.IsOKResponse()) 1212254721Semaste return 0; 1213254721Semaste uint8_t error = response.GetError(); 1214254721Semaste if (error) 1215254721Semaste return error; 1216254721Semaste } 1217254721Semaste } 1218254721Semaste return -1; 1219254721Semaste} 1220254721Semaste 1221254721Semasteint 1222254721SemasteGDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value) 1223254721Semaste{ 1224254721Semaste if (name_equal_value && name_equal_value[0]) 1225254721Semaste { 1226254721Semaste StreamString packet; 1227263363Semaste bool send_hex_encoding = false; 1228263363Semaste for (const char *p = name_equal_value; *p != '\0' && send_hex_encoding == false; ++p) 1229263363Semaste { 1230263363Semaste if (isprint(*p)) 1231263363Semaste { 1232263363Semaste switch (*p) 1233263363Semaste { 1234263363Semaste case '$': 1235263363Semaste case '#': 1236263363Semaste send_hex_encoding = true; 1237263363Semaste break; 1238263363Semaste default: 1239263363Semaste break; 1240263363Semaste } 1241263363Semaste } 1242263363Semaste else 1243263363Semaste { 1244263363Semaste // We have non printable characters, lets hex encode this... 1245263363Semaste send_hex_encoding = true; 1246263363Semaste } 1247263363Semaste } 1248263363Semaste 1249254721Semaste StringExtractorGDBRemote response; 1250263363Semaste if (send_hex_encoding) 1251254721Semaste { 1252263363Semaste if (m_supports_QEnvironmentHexEncoded) 1253263363Semaste { 1254263363Semaste packet.PutCString("QEnvironmentHexEncoded:"); 1255263363Semaste packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value)); 1256269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1257263363Semaste { 1258263363Semaste if (response.IsOKResponse()) 1259263363Semaste return 0; 1260263363Semaste uint8_t error = response.GetError(); 1261263363Semaste if (error) 1262263363Semaste return error; 1263263363Semaste if (response.IsUnsupportedResponse()) 1264263363Semaste m_supports_QEnvironmentHexEncoded = false; 1265263363Semaste } 1266263363Semaste } 1267263363Semaste 1268254721Semaste } 1269263363Semaste else if (m_supports_QEnvironment) 1270263363Semaste { 1271263363Semaste packet.Printf("QEnvironment:%s", name_equal_value); 1272269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1273263363Semaste { 1274263363Semaste if (response.IsOKResponse()) 1275263363Semaste return 0; 1276263363Semaste uint8_t error = response.GetError(); 1277263363Semaste if (error) 1278263363Semaste return error; 1279263363Semaste if (response.IsUnsupportedResponse()) 1280263363Semaste m_supports_QEnvironment = false; 1281263363Semaste } 1282263363Semaste } 1283254721Semaste } 1284254721Semaste return -1; 1285254721Semaste} 1286254721Semaste 1287254721Semasteint 1288254721SemasteGDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch) 1289254721Semaste{ 1290254721Semaste if (arch && arch[0]) 1291254721Semaste { 1292254721Semaste StreamString packet; 1293254721Semaste packet.Printf("QLaunchArch:%s", arch); 1294254721Semaste StringExtractorGDBRemote response; 1295269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1296254721Semaste { 1297254721Semaste if (response.IsOKResponse()) 1298254721Semaste return 0; 1299254721Semaste uint8_t error = response.GetError(); 1300254721Semaste if (error) 1301254721Semaste return error; 1302254721Semaste } 1303254721Semaste } 1304254721Semaste return -1; 1305254721Semaste} 1306254721Semaste 1307254721Semastebool 1308254721SemasteGDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, 1309254721Semaste uint32_t &minor, 1310254721Semaste uint32_t &update) 1311254721Semaste{ 1312254721Semaste if (GetHostInfo ()) 1313254721Semaste { 1314254721Semaste if (m_os_version_major != UINT32_MAX) 1315254721Semaste { 1316254721Semaste major = m_os_version_major; 1317254721Semaste minor = m_os_version_minor; 1318254721Semaste update = m_os_version_update; 1319254721Semaste return true; 1320254721Semaste } 1321254721Semaste } 1322254721Semaste return false; 1323254721Semaste} 1324254721Semaste 1325254721Semastebool 1326254721SemasteGDBRemoteCommunicationClient::GetOSBuildString (std::string &s) 1327254721Semaste{ 1328254721Semaste if (GetHostInfo ()) 1329254721Semaste { 1330254721Semaste if (!m_os_build.empty()) 1331254721Semaste { 1332254721Semaste s = m_os_build; 1333254721Semaste return true; 1334254721Semaste } 1335254721Semaste } 1336254721Semaste s.clear(); 1337254721Semaste return false; 1338254721Semaste} 1339254721Semaste 1340254721Semaste 1341254721Semastebool 1342254721SemasteGDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s) 1343254721Semaste{ 1344254721Semaste if (GetHostInfo ()) 1345254721Semaste { 1346254721Semaste if (!m_os_kernel.empty()) 1347254721Semaste { 1348254721Semaste s = m_os_kernel; 1349254721Semaste return true; 1350254721Semaste } 1351254721Semaste } 1352254721Semaste s.clear(); 1353254721Semaste return false; 1354254721Semaste} 1355254721Semaste 1356254721Semastebool 1357254721SemasteGDBRemoteCommunicationClient::GetHostname (std::string &s) 1358254721Semaste{ 1359254721Semaste if (GetHostInfo ()) 1360254721Semaste { 1361254721Semaste if (!m_hostname.empty()) 1362254721Semaste { 1363254721Semaste s = m_hostname; 1364254721Semaste return true; 1365254721Semaste } 1366254721Semaste } 1367254721Semaste s.clear(); 1368254721Semaste return false; 1369254721Semaste} 1370254721Semaste 1371254721SemasteArchSpec 1372254721SemasteGDBRemoteCommunicationClient::GetSystemArchitecture () 1373254721Semaste{ 1374254721Semaste if (GetHostInfo ()) 1375254721Semaste return m_host_arch; 1376254721Semaste return ArchSpec(); 1377254721Semaste} 1378254721Semaste 1379254721Semasteconst lldb_private::ArchSpec & 1380254721SemasteGDBRemoteCommunicationClient::GetProcessArchitecture () 1381254721Semaste{ 1382254721Semaste if (m_qProcessInfo_is_valid == eLazyBoolCalculate) 1383254721Semaste GetCurrentProcessInfo (); 1384254721Semaste return m_process_arch; 1385254721Semaste} 1386254721Semaste 1387254721Semaste 1388254721Semastebool 1389254721SemasteGDBRemoteCommunicationClient::GetHostInfo (bool force) 1390254721Semaste{ 1391254721Semaste if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) 1392254721Semaste { 1393254721Semaste m_qHostInfo_is_valid = eLazyBoolNo; 1394254721Semaste StringExtractorGDBRemote response; 1395269024Semaste if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success) 1396254721Semaste { 1397254721Semaste if (response.IsNormalResponse()) 1398254721Semaste { 1399254721Semaste std::string name; 1400254721Semaste std::string value; 1401254721Semaste uint32_t cpu = LLDB_INVALID_CPUTYPE; 1402254721Semaste uint32_t sub = 0; 1403254721Semaste std::string arch_name; 1404254721Semaste std::string os_name; 1405254721Semaste std::string vendor_name; 1406254721Semaste std::string triple; 1407269024Semaste std::string distribution_id; 1408254721Semaste uint32_t pointer_byte_size = 0; 1409254721Semaste StringExtractor extractor; 1410254721Semaste ByteOrder byte_order = eByteOrderInvalid; 1411254721Semaste uint32_t num_keys_decoded = 0; 1412254721Semaste while (response.GetNameColonValue(name, value)) 1413254721Semaste { 1414254721Semaste if (name.compare("cputype") == 0) 1415254721Semaste { 1416254721Semaste // exception type in big endian hex 1417254721Semaste cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); 1418254721Semaste if (cpu != LLDB_INVALID_CPUTYPE) 1419254721Semaste ++num_keys_decoded; 1420254721Semaste } 1421254721Semaste else if (name.compare("cpusubtype") == 0) 1422254721Semaste { 1423254721Semaste // exception count in big endian hex 1424254721Semaste sub = Args::StringToUInt32 (value.c_str(), 0, 0); 1425254721Semaste if (sub != 0) 1426254721Semaste ++num_keys_decoded; 1427254721Semaste } 1428254721Semaste else if (name.compare("arch") == 0) 1429254721Semaste { 1430254721Semaste arch_name.swap (value); 1431254721Semaste ++num_keys_decoded; 1432254721Semaste } 1433254721Semaste else if (name.compare("triple") == 0) 1434254721Semaste { 1435254721Semaste // The triple comes as ASCII hex bytes since it contains '-' chars 1436254721Semaste extractor.GetStringRef().swap(value); 1437254721Semaste extractor.SetFilePos(0); 1438254721Semaste extractor.GetHexByteString (triple); 1439254721Semaste ++num_keys_decoded; 1440254721Semaste } 1441269024Semaste else if (name.compare ("distribution_id") == 0) 1442269024Semaste { 1443269024Semaste extractor.GetStringRef ().swap (value); 1444269024Semaste extractor.SetFilePos (0); 1445269024Semaste extractor.GetHexByteString (distribution_id); 1446269024Semaste ++num_keys_decoded; 1447269024Semaste } 1448254721Semaste else if (name.compare("os_build") == 0) 1449254721Semaste { 1450254721Semaste extractor.GetStringRef().swap(value); 1451254721Semaste extractor.SetFilePos(0); 1452254721Semaste extractor.GetHexByteString (m_os_build); 1453254721Semaste ++num_keys_decoded; 1454254721Semaste } 1455254721Semaste else if (name.compare("hostname") == 0) 1456254721Semaste { 1457254721Semaste extractor.GetStringRef().swap(value); 1458254721Semaste extractor.SetFilePos(0); 1459254721Semaste extractor.GetHexByteString (m_hostname); 1460254721Semaste ++num_keys_decoded; 1461254721Semaste } 1462254721Semaste else if (name.compare("os_kernel") == 0) 1463254721Semaste { 1464254721Semaste extractor.GetStringRef().swap(value); 1465254721Semaste extractor.SetFilePos(0); 1466254721Semaste extractor.GetHexByteString (m_os_kernel); 1467254721Semaste ++num_keys_decoded; 1468254721Semaste } 1469254721Semaste else if (name.compare("ostype") == 0) 1470254721Semaste { 1471254721Semaste os_name.swap (value); 1472254721Semaste ++num_keys_decoded; 1473254721Semaste } 1474254721Semaste else if (name.compare("vendor") == 0) 1475254721Semaste { 1476254721Semaste vendor_name.swap(value); 1477254721Semaste ++num_keys_decoded; 1478254721Semaste } 1479254721Semaste else if (name.compare("endian") == 0) 1480254721Semaste { 1481254721Semaste ++num_keys_decoded; 1482254721Semaste if (value.compare("little") == 0) 1483254721Semaste byte_order = eByteOrderLittle; 1484254721Semaste else if (value.compare("big") == 0) 1485254721Semaste byte_order = eByteOrderBig; 1486254721Semaste else if (value.compare("pdp") == 0) 1487254721Semaste byte_order = eByteOrderPDP; 1488254721Semaste else 1489254721Semaste --num_keys_decoded; 1490254721Semaste } 1491254721Semaste else if (name.compare("ptrsize") == 0) 1492254721Semaste { 1493254721Semaste pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); 1494254721Semaste if (pointer_byte_size != 0) 1495254721Semaste ++num_keys_decoded; 1496254721Semaste } 1497254721Semaste else if (name.compare("os_version") == 0) 1498254721Semaste { 1499254721Semaste Args::StringToVersion (value.c_str(), 1500254721Semaste m_os_version_major, 1501254721Semaste m_os_version_minor, 1502254721Semaste m_os_version_update); 1503254721Semaste if (m_os_version_major != UINT32_MAX) 1504254721Semaste ++num_keys_decoded; 1505254721Semaste } 1506254721Semaste else if (name.compare("watchpoint_exceptions_received") == 0) 1507254721Semaste { 1508254721Semaste ++num_keys_decoded; 1509254721Semaste if (strcmp(value.c_str(),"before") == 0) 1510254721Semaste m_watchpoints_trigger_after_instruction = eLazyBoolNo; 1511254721Semaste else if (strcmp(value.c_str(),"after") == 0) 1512254721Semaste m_watchpoints_trigger_after_instruction = eLazyBoolYes; 1513254721Semaste else 1514254721Semaste --num_keys_decoded; 1515254721Semaste } 1516263363Semaste else if (name.compare("default_packet_timeout") == 0) 1517263363Semaste { 1518263363Semaste m_default_packet_timeout = Args::StringToUInt32(value.c_str(), 0); 1519263363Semaste if (m_default_packet_timeout > 0) 1520263363Semaste { 1521263363Semaste SetPacketTimeout(m_default_packet_timeout); 1522263363Semaste ++num_keys_decoded; 1523263363Semaste } 1524263363Semaste } 1525254721Semaste 1526254721Semaste } 1527254721Semaste 1528254721Semaste if (num_keys_decoded > 0) 1529254721Semaste m_qHostInfo_is_valid = eLazyBoolYes; 1530254721Semaste 1531254721Semaste if (triple.empty()) 1532254721Semaste { 1533254721Semaste if (arch_name.empty()) 1534254721Semaste { 1535254721Semaste if (cpu != LLDB_INVALID_CPUTYPE) 1536254721Semaste { 1537254721Semaste m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub); 1538254721Semaste if (pointer_byte_size) 1539254721Semaste { 1540254721Semaste assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); 1541254721Semaste } 1542254721Semaste if (byte_order != eByteOrderInvalid) 1543254721Semaste { 1544254721Semaste assert (byte_order == m_host_arch.GetByteOrder()); 1545254721Semaste } 1546254721Semaste 1547254721Semaste if (!os_name.empty() && vendor_name.compare("apple") == 0 && os_name.find("darwin") == 0) 1548254721Semaste { 1549254721Semaste switch (m_host_arch.GetMachine()) 1550254721Semaste { 1551254721Semaste case llvm::Triple::arm: 1552254721Semaste case llvm::Triple::thumb: 1553254721Semaste os_name = "ios"; 1554254721Semaste break; 1555254721Semaste default: 1556254721Semaste os_name = "macosx"; 1557254721Semaste break; 1558254721Semaste } 1559254721Semaste } 1560254721Semaste if (!vendor_name.empty()) 1561254721Semaste m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); 1562254721Semaste if (!os_name.empty()) 1563254721Semaste m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name)); 1564254721Semaste 1565254721Semaste } 1566254721Semaste } 1567254721Semaste else 1568254721Semaste { 1569254721Semaste std::string triple; 1570254721Semaste triple += arch_name; 1571254721Semaste if (!vendor_name.empty() || !os_name.empty()) 1572254721Semaste { 1573254721Semaste triple += '-'; 1574254721Semaste if (vendor_name.empty()) 1575254721Semaste triple += "unknown"; 1576254721Semaste else 1577254721Semaste triple += vendor_name; 1578254721Semaste triple += '-'; 1579254721Semaste if (os_name.empty()) 1580254721Semaste triple += "unknown"; 1581254721Semaste else 1582254721Semaste triple += os_name; 1583254721Semaste } 1584254721Semaste m_host_arch.SetTriple (triple.c_str()); 1585254721Semaste 1586254721Semaste llvm::Triple &host_triple = m_host_arch.GetTriple(); 1587254721Semaste if (host_triple.getVendor() == llvm::Triple::Apple && host_triple.getOS() == llvm::Triple::Darwin) 1588254721Semaste { 1589254721Semaste switch (m_host_arch.GetMachine()) 1590254721Semaste { 1591254721Semaste case llvm::Triple::arm: 1592254721Semaste case llvm::Triple::thumb: 1593254721Semaste host_triple.setOS(llvm::Triple::IOS); 1594254721Semaste break; 1595254721Semaste default: 1596254721Semaste host_triple.setOS(llvm::Triple::MacOSX); 1597254721Semaste break; 1598254721Semaste } 1599254721Semaste } 1600254721Semaste if (pointer_byte_size) 1601254721Semaste { 1602254721Semaste assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); 1603254721Semaste } 1604254721Semaste if (byte_order != eByteOrderInvalid) 1605254721Semaste { 1606254721Semaste assert (byte_order == m_host_arch.GetByteOrder()); 1607254721Semaste } 1608254721Semaste 1609254721Semaste } 1610254721Semaste } 1611254721Semaste else 1612254721Semaste { 1613254721Semaste m_host_arch.SetTriple (triple.c_str()); 1614254721Semaste if (pointer_byte_size) 1615254721Semaste { 1616254721Semaste assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); 1617254721Semaste } 1618254721Semaste if (byte_order != eByteOrderInvalid) 1619254721Semaste { 1620254721Semaste assert (byte_order == m_host_arch.GetByteOrder()); 1621254721Semaste } 1622269024Semaste } 1623269024Semaste if (!distribution_id.empty ()) 1624269024Semaste m_host_arch.SetDistributionId (distribution_id.c_str ()); 1625254721Semaste } 1626254721Semaste } 1627254721Semaste } 1628254721Semaste return m_qHostInfo_is_valid == eLazyBoolYes; 1629254721Semaste} 1630254721Semaste 1631254721Semasteint 1632254721SemasteGDBRemoteCommunicationClient::SendAttach 1633254721Semaste( 1634254721Semaste lldb::pid_t pid, 1635254721Semaste StringExtractorGDBRemote& response 1636254721Semaste) 1637254721Semaste{ 1638254721Semaste if (pid != LLDB_INVALID_PROCESS_ID) 1639254721Semaste { 1640254721Semaste char packet[64]; 1641254721Semaste const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid); 1642254721Semaste assert (packet_len < (int)sizeof(packet)); 1643269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 1644254721Semaste { 1645254721Semaste if (response.IsErrorResponse()) 1646254721Semaste return response.GetError(); 1647254721Semaste return 0; 1648254721Semaste } 1649254721Semaste } 1650254721Semaste return -1; 1651254721Semaste} 1652254721Semaste 1653254721Semasteconst lldb_private::ArchSpec & 1654254721SemasteGDBRemoteCommunicationClient::GetHostArchitecture () 1655254721Semaste{ 1656254721Semaste if (m_qHostInfo_is_valid == eLazyBoolCalculate) 1657254721Semaste GetHostInfo (); 1658254721Semaste return m_host_arch; 1659254721Semaste} 1660254721Semaste 1661263363Semasteuint32_t 1662263363SemasteGDBRemoteCommunicationClient::GetHostDefaultPacketTimeout () 1663263363Semaste{ 1664263363Semaste if (m_qHostInfo_is_valid == eLazyBoolCalculate) 1665263363Semaste GetHostInfo (); 1666263363Semaste return m_default_packet_timeout; 1667263363Semaste} 1668263363Semaste 1669254721Semasteaddr_t 1670254721SemasteGDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions) 1671254721Semaste{ 1672254721Semaste if (m_supports_alloc_dealloc_memory != eLazyBoolNo) 1673254721Semaste { 1674254721Semaste m_supports_alloc_dealloc_memory = eLazyBoolYes; 1675254721Semaste char packet[64]; 1676254721Semaste const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", 1677254721Semaste (uint64_t)size, 1678254721Semaste permissions & lldb::ePermissionsReadable ? "r" : "", 1679254721Semaste permissions & lldb::ePermissionsWritable ? "w" : "", 1680254721Semaste permissions & lldb::ePermissionsExecutable ? "x" : ""); 1681254721Semaste assert (packet_len < (int)sizeof(packet)); 1682254721Semaste StringExtractorGDBRemote response; 1683269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 1684254721Semaste { 1685254721Semaste if (!response.IsErrorResponse()) 1686254721Semaste return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 1687254721Semaste } 1688254721Semaste else 1689254721Semaste { 1690254721Semaste m_supports_alloc_dealloc_memory = eLazyBoolNo; 1691254721Semaste } 1692254721Semaste } 1693254721Semaste return LLDB_INVALID_ADDRESS; 1694254721Semaste} 1695254721Semaste 1696254721Semastebool 1697254721SemasteGDBRemoteCommunicationClient::DeallocateMemory (addr_t addr) 1698254721Semaste{ 1699254721Semaste if (m_supports_alloc_dealloc_memory != eLazyBoolNo) 1700254721Semaste { 1701254721Semaste m_supports_alloc_dealloc_memory = eLazyBoolYes; 1702254721Semaste char packet[64]; 1703254721Semaste const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr); 1704254721Semaste assert (packet_len < (int)sizeof(packet)); 1705254721Semaste StringExtractorGDBRemote response; 1706269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 1707254721Semaste { 1708254721Semaste if (response.IsOKResponse()) 1709254721Semaste return true; 1710254721Semaste } 1711254721Semaste else 1712254721Semaste { 1713254721Semaste m_supports_alloc_dealloc_memory = eLazyBoolNo; 1714254721Semaste } 1715254721Semaste } 1716254721Semaste return false; 1717254721Semaste} 1718254721Semaste 1719254721SemasteError 1720254721SemasteGDBRemoteCommunicationClient::Detach (bool keep_stopped) 1721254721Semaste{ 1722254721Semaste Error error; 1723254721Semaste 1724254721Semaste if (keep_stopped) 1725254721Semaste { 1726254721Semaste if (m_supports_detach_stay_stopped == eLazyBoolCalculate) 1727254721Semaste { 1728254721Semaste char packet[64]; 1729254721Semaste const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:"); 1730254721Semaste assert (packet_len < (int)sizeof(packet)); 1731254721Semaste StringExtractorGDBRemote response; 1732269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 1733254721Semaste { 1734254721Semaste m_supports_detach_stay_stopped = eLazyBoolYes; 1735254721Semaste } 1736254721Semaste else 1737254721Semaste { 1738254721Semaste m_supports_detach_stay_stopped = eLazyBoolNo; 1739254721Semaste } 1740254721Semaste } 1741254721Semaste 1742254721Semaste if (m_supports_detach_stay_stopped == eLazyBoolNo) 1743254721Semaste { 1744254721Semaste error.SetErrorString("Stays stopped not supported by this target."); 1745254721Semaste return error; 1746254721Semaste } 1747254721Semaste else 1748254721Semaste { 1749269024Semaste PacketResult packet_result = SendPacket ("D1", 2); 1750269024Semaste if (packet_result != PacketResult::Success) 1751254721Semaste error.SetErrorString ("Sending extended disconnect packet failed."); 1752254721Semaste } 1753254721Semaste } 1754254721Semaste else 1755254721Semaste { 1756269024Semaste PacketResult packet_result = SendPacket ("D", 1); 1757269024Semaste if (packet_result != PacketResult::Success) 1758254721Semaste error.SetErrorString ("Sending disconnect packet failed."); 1759254721Semaste } 1760254721Semaste return error; 1761254721Semaste} 1762254721Semaste 1763254721SemasteError 1764254721SemasteGDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, 1765254721Semaste lldb_private::MemoryRegionInfo ®ion_info) 1766254721Semaste{ 1767254721Semaste Error error; 1768254721Semaste region_info.Clear(); 1769254721Semaste 1770254721Semaste if (m_supports_memory_region_info != eLazyBoolNo) 1771254721Semaste { 1772254721Semaste m_supports_memory_region_info = eLazyBoolYes; 1773254721Semaste char packet[64]; 1774254721Semaste const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr); 1775254721Semaste assert (packet_len < (int)sizeof(packet)); 1776254721Semaste StringExtractorGDBRemote response; 1777269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 1778254721Semaste { 1779254721Semaste std::string name; 1780254721Semaste std::string value; 1781254721Semaste addr_t addr_value; 1782254721Semaste bool success = true; 1783254721Semaste bool saw_permissions = false; 1784254721Semaste while (success && response.GetNameColonValue(name, value)) 1785254721Semaste { 1786254721Semaste if (name.compare ("start") == 0) 1787254721Semaste { 1788254721Semaste addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success); 1789254721Semaste if (success) 1790254721Semaste region_info.GetRange().SetRangeBase(addr_value); 1791254721Semaste } 1792254721Semaste else if (name.compare ("size") == 0) 1793254721Semaste { 1794254721Semaste addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success); 1795254721Semaste if (success) 1796254721Semaste region_info.GetRange().SetByteSize (addr_value); 1797254721Semaste } 1798254721Semaste else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid()) 1799254721Semaste { 1800254721Semaste saw_permissions = true; 1801254721Semaste if (region_info.GetRange().Contains (addr)) 1802254721Semaste { 1803254721Semaste if (value.find('r') != std::string::npos) 1804254721Semaste region_info.SetReadable (MemoryRegionInfo::eYes); 1805254721Semaste else 1806254721Semaste region_info.SetReadable (MemoryRegionInfo::eNo); 1807254721Semaste 1808254721Semaste if (value.find('w') != std::string::npos) 1809254721Semaste region_info.SetWritable (MemoryRegionInfo::eYes); 1810254721Semaste else 1811254721Semaste region_info.SetWritable (MemoryRegionInfo::eNo); 1812254721Semaste 1813254721Semaste if (value.find('x') != std::string::npos) 1814254721Semaste region_info.SetExecutable (MemoryRegionInfo::eYes); 1815254721Semaste else 1816254721Semaste region_info.SetExecutable (MemoryRegionInfo::eNo); 1817254721Semaste } 1818254721Semaste else 1819254721Semaste { 1820254721Semaste // The reported region does not contain this address -- we're looking at an unmapped page 1821254721Semaste region_info.SetReadable (MemoryRegionInfo::eNo); 1822254721Semaste region_info.SetWritable (MemoryRegionInfo::eNo); 1823254721Semaste region_info.SetExecutable (MemoryRegionInfo::eNo); 1824254721Semaste } 1825254721Semaste } 1826254721Semaste else if (name.compare ("error") == 0) 1827254721Semaste { 1828254721Semaste StringExtractorGDBRemote name_extractor; 1829254721Semaste // Swap "value" over into "name_extractor" 1830254721Semaste name_extractor.GetStringRef().swap(value); 1831254721Semaste // Now convert the HEX bytes into a string value 1832254721Semaste name_extractor.GetHexByteString (value); 1833254721Semaste error.SetErrorString(value.c_str()); 1834254721Semaste } 1835254721Semaste } 1836254721Semaste 1837254721Semaste // We got a valid address range back but no permissions -- which means this is an unmapped page 1838254721Semaste if (region_info.GetRange().IsValid() && saw_permissions == false) 1839254721Semaste { 1840254721Semaste region_info.SetReadable (MemoryRegionInfo::eNo); 1841254721Semaste region_info.SetWritable (MemoryRegionInfo::eNo); 1842254721Semaste region_info.SetExecutable (MemoryRegionInfo::eNo); 1843254721Semaste } 1844254721Semaste } 1845254721Semaste else 1846254721Semaste { 1847254721Semaste m_supports_memory_region_info = eLazyBoolNo; 1848254721Semaste } 1849254721Semaste } 1850254721Semaste 1851254721Semaste if (m_supports_memory_region_info == eLazyBoolNo) 1852254721Semaste { 1853254721Semaste error.SetErrorString("qMemoryRegionInfo is not supported"); 1854254721Semaste } 1855254721Semaste if (error.Fail()) 1856254721Semaste region_info.Clear(); 1857254721Semaste return error; 1858254721Semaste 1859254721Semaste} 1860254721Semaste 1861254721SemasteError 1862254721SemasteGDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num) 1863254721Semaste{ 1864254721Semaste Error error; 1865254721Semaste 1866254721Semaste if (m_supports_watchpoint_support_info == eLazyBoolYes) 1867254721Semaste { 1868254721Semaste num = m_num_supported_hardware_watchpoints; 1869254721Semaste return error; 1870254721Semaste } 1871254721Semaste 1872254721Semaste // Set num to 0 first. 1873254721Semaste num = 0; 1874254721Semaste if (m_supports_watchpoint_support_info != eLazyBoolNo) 1875254721Semaste { 1876254721Semaste char packet[64]; 1877254721Semaste const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:"); 1878254721Semaste assert (packet_len < (int)sizeof(packet)); 1879254721Semaste StringExtractorGDBRemote response; 1880269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 1881254721Semaste { 1882254721Semaste m_supports_watchpoint_support_info = eLazyBoolYes; 1883254721Semaste std::string name; 1884254721Semaste std::string value; 1885254721Semaste while (response.GetNameColonValue(name, value)) 1886254721Semaste { 1887254721Semaste if (name.compare ("num") == 0) 1888254721Semaste { 1889254721Semaste num = Args::StringToUInt32(value.c_str(), 0, 0); 1890254721Semaste m_num_supported_hardware_watchpoints = num; 1891254721Semaste } 1892254721Semaste } 1893254721Semaste } 1894254721Semaste else 1895254721Semaste { 1896254721Semaste m_supports_watchpoint_support_info = eLazyBoolNo; 1897254721Semaste } 1898254721Semaste } 1899254721Semaste 1900254721Semaste if (m_supports_watchpoint_support_info == eLazyBoolNo) 1901254721Semaste { 1902254721Semaste error.SetErrorString("qWatchpointSupportInfo is not supported"); 1903254721Semaste } 1904254721Semaste return error; 1905254721Semaste 1906254721Semaste} 1907254721Semaste 1908254721Semastelldb_private::Error 1909254721SemasteGDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num, bool& after) 1910254721Semaste{ 1911254721Semaste Error error(GetWatchpointSupportInfo(num)); 1912254721Semaste if (error.Success()) 1913254721Semaste error = GetWatchpointsTriggerAfterInstruction(after); 1914254721Semaste return error; 1915254721Semaste} 1916254721Semaste 1917254721Semastelldb_private::Error 1918254721SemasteGDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after) 1919254721Semaste{ 1920254721Semaste Error error; 1921254721Semaste 1922254721Semaste // we assume watchpoints will happen after running the relevant opcode 1923254721Semaste // and we only want to override this behavior if we have explicitly 1924254721Semaste // received a qHostInfo telling us otherwise 1925254721Semaste if (m_qHostInfo_is_valid != eLazyBoolYes) 1926254721Semaste after = true; 1927254721Semaste else 1928254721Semaste after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); 1929254721Semaste return error; 1930254721Semaste} 1931254721Semaste 1932254721Semasteint 1933254721SemasteGDBRemoteCommunicationClient::SetSTDIN (char const *path) 1934254721Semaste{ 1935254721Semaste if (path && path[0]) 1936254721Semaste { 1937254721Semaste StreamString packet; 1938254721Semaste packet.PutCString("QSetSTDIN:"); 1939254721Semaste packet.PutBytesAsRawHex8(path, strlen(path)); 1940254721Semaste 1941254721Semaste StringExtractorGDBRemote response; 1942269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1943254721Semaste { 1944254721Semaste if (response.IsOKResponse()) 1945254721Semaste return 0; 1946254721Semaste uint8_t error = response.GetError(); 1947254721Semaste if (error) 1948254721Semaste return error; 1949254721Semaste } 1950254721Semaste } 1951254721Semaste return -1; 1952254721Semaste} 1953254721Semaste 1954254721Semasteint 1955254721SemasteGDBRemoteCommunicationClient::SetSTDOUT (char const *path) 1956254721Semaste{ 1957254721Semaste if (path && path[0]) 1958254721Semaste { 1959254721Semaste StreamString packet; 1960254721Semaste packet.PutCString("QSetSTDOUT:"); 1961254721Semaste packet.PutBytesAsRawHex8(path, strlen(path)); 1962254721Semaste 1963254721Semaste StringExtractorGDBRemote response; 1964269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1965254721Semaste { 1966254721Semaste if (response.IsOKResponse()) 1967254721Semaste return 0; 1968254721Semaste uint8_t error = response.GetError(); 1969254721Semaste if (error) 1970254721Semaste return error; 1971254721Semaste } 1972254721Semaste } 1973254721Semaste return -1; 1974254721Semaste} 1975254721Semaste 1976254721Semasteint 1977254721SemasteGDBRemoteCommunicationClient::SetSTDERR (char const *path) 1978254721Semaste{ 1979254721Semaste if (path && path[0]) 1980254721Semaste { 1981254721Semaste StreamString packet; 1982254721Semaste packet.PutCString("QSetSTDERR:"); 1983254721Semaste packet.PutBytesAsRawHex8(path, strlen(path)); 1984254721Semaste 1985254721Semaste StringExtractorGDBRemote response; 1986269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 1987254721Semaste { 1988254721Semaste if (response.IsOKResponse()) 1989254721Semaste return 0; 1990254721Semaste uint8_t error = response.GetError(); 1991254721Semaste if (error) 1992254721Semaste return error; 1993254721Semaste } 1994254721Semaste } 1995254721Semaste return -1; 1996254721Semaste} 1997254721Semaste 1998263367Semastebool 1999263367SemasteGDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd) 2000263367Semaste{ 2001263367Semaste StringExtractorGDBRemote response; 2002269024Semaste if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success) 2003263367Semaste { 2004263367Semaste if (response.IsUnsupportedResponse()) 2005263367Semaste return false; 2006263367Semaste if (response.IsErrorResponse()) 2007263367Semaste return false; 2008263367Semaste response.GetHexByteString (cwd); 2009263367Semaste return !cwd.empty(); 2010263367Semaste } 2011263367Semaste return false; 2012263367Semaste} 2013263367Semaste 2014254721Semasteint 2015254721SemasteGDBRemoteCommunicationClient::SetWorkingDir (char const *path) 2016254721Semaste{ 2017254721Semaste if (path && path[0]) 2018254721Semaste { 2019254721Semaste StreamString packet; 2020254721Semaste packet.PutCString("QSetWorkingDir:"); 2021254721Semaste packet.PutBytesAsRawHex8(path, strlen(path)); 2022254721Semaste 2023254721Semaste StringExtractorGDBRemote response; 2024269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 2025254721Semaste { 2026254721Semaste if (response.IsOKResponse()) 2027254721Semaste return 0; 2028254721Semaste uint8_t error = response.GetError(); 2029254721Semaste if (error) 2030254721Semaste return error; 2031254721Semaste } 2032254721Semaste } 2033254721Semaste return -1; 2034254721Semaste} 2035254721Semaste 2036254721Semasteint 2037254721SemasteGDBRemoteCommunicationClient::SetDisableASLR (bool enable) 2038254721Semaste{ 2039254721Semaste char packet[32]; 2040254721Semaste const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0); 2041254721Semaste assert (packet_len < (int)sizeof(packet)); 2042254721Semaste StringExtractorGDBRemote response; 2043269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 2044254721Semaste { 2045254721Semaste if (response.IsOKResponse()) 2046254721Semaste return 0; 2047254721Semaste uint8_t error = response.GetError(); 2048254721Semaste if (error) 2049254721Semaste return error; 2050254721Semaste } 2051254721Semaste return -1; 2052254721Semaste} 2053254721Semaste 2054254721Semastebool 2055254721SemasteGDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) 2056254721Semaste{ 2057254721Semaste if (response.IsNormalResponse()) 2058254721Semaste { 2059254721Semaste std::string name; 2060254721Semaste std::string value; 2061254721Semaste StringExtractor extractor; 2062269024Semaste 2063269024Semaste uint32_t cpu = LLDB_INVALID_CPUTYPE; 2064269024Semaste uint32_t sub = 0; 2065269024Semaste std::string vendor; 2066269024Semaste std::string os_type; 2067254721Semaste 2068254721Semaste while (response.GetNameColonValue(name, value)) 2069254721Semaste { 2070254721Semaste if (name.compare("pid") == 0) 2071254721Semaste { 2072254721Semaste process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); 2073254721Semaste } 2074254721Semaste else if (name.compare("ppid") == 0) 2075254721Semaste { 2076254721Semaste process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); 2077254721Semaste } 2078254721Semaste else if (name.compare("uid") == 0) 2079254721Semaste { 2080254721Semaste process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 2081254721Semaste } 2082254721Semaste else if (name.compare("euid") == 0) 2083254721Semaste { 2084254721Semaste process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 2085254721Semaste } 2086254721Semaste else if (name.compare("gid") == 0) 2087254721Semaste { 2088254721Semaste process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 2089254721Semaste } 2090254721Semaste else if (name.compare("egid") == 0) 2091254721Semaste { 2092254721Semaste process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); 2093254721Semaste } 2094254721Semaste else if (name.compare("triple") == 0) 2095254721Semaste { 2096254721Semaste // The triple comes as ASCII hex bytes since it contains '-' chars 2097254721Semaste extractor.GetStringRef().swap(value); 2098254721Semaste extractor.SetFilePos(0); 2099254721Semaste extractor.GetHexByteString (value); 2100254721Semaste process_info.GetArchitecture ().SetTriple (value.c_str()); 2101254721Semaste } 2102254721Semaste else if (name.compare("name") == 0) 2103254721Semaste { 2104254721Semaste StringExtractor extractor; 2105254721Semaste // The process name from ASCII hex bytes since we can't 2106254721Semaste // control the characters in a process name 2107254721Semaste extractor.GetStringRef().swap(value); 2108254721Semaste extractor.SetFilePos(0); 2109254721Semaste extractor.GetHexByteString (value); 2110254721Semaste process_info.GetExecutableFile().SetFile (value.c_str(), false); 2111254721Semaste } 2112269024Semaste else if (name.compare("cputype") == 0) 2113269024Semaste { 2114269024Semaste cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16); 2115269024Semaste } 2116269024Semaste else if (name.compare("cpusubtype") == 0) 2117269024Semaste { 2118269024Semaste sub = Args::StringToUInt32 (value.c_str(), 0, 16); 2119269024Semaste } 2120269024Semaste else if (name.compare("vendor") == 0) 2121269024Semaste { 2122269024Semaste vendor = value; 2123269024Semaste } 2124269024Semaste else if (name.compare("ostype") == 0) 2125269024Semaste { 2126269024Semaste os_type = value; 2127269024Semaste } 2128254721Semaste } 2129269024Semaste 2130269024Semaste if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) 2131269024Semaste { 2132269024Semaste if (vendor == "apple") 2133269024Semaste { 2134269024Semaste process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub); 2135269024Semaste process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor)); 2136269024Semaste process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type)); 2137269024Semaste } 2138269024Semaste } 2139254721Semaste 2140254721Semaste if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 2141254721Semaste return true; 2142254721Semaste } 2143254721Semaste return false; 2144254721Semaste} 2145254721Semaste 2146254721Semastebool 2147254721SemasteGDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 2148254721Semaste{ 2149254721Semaste process_info.Clear(); 2150254721Semaste 2151254721Semaste if (m_supports_qProcessInfoPID) 2152254721Semaste { 2153254721Semaste char packet[32]; 2154254721Semaste const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid); 2155254721Semaste assert (packet_len < (int)sizeof(packet)); 2156254721Semaste StringExtractorGDBRemote response; 2157269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 2158254721Semaste { 2159254721Semaste return DecodeProcessInfoResponse (response, process_info); 2160254721Semaste } 2161254721Semaste else 2162254721Semaste { 2163254721Semaste m_supports_qProcessInfoPID = false; 2164254721Semaste return false; 2165254721Semaste } 2166254721Semaste } 2167254721Semaste return false; 2168254721Semaste} 2169254721Semaste 2170254721Semastebool 2171254721SemasteGDBRemoteCommunicationClient::GetCurrentProcessInfo () 2172254721Semaste{ 2173254721Semaste if (m_qProcessInfo_is_valid == eLazyBoolYes) 2174254721Semaste return true; 2175254721Semaste if (m_qProcessInfo_is_valid == eLazyBoolNo) 2176254721Semaste return false; 2177254721Semaste 2178254721Semaste GetHostInfo (); 2179254721Semaste 2180254721Semaste StringExtractorGDBRemote response; 2181269024Semaste if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success) 2182254721Semaste { 2183254721Semaste if (response.IsNormalResponse()) 2184254721Semaste { 2185254721Semaste std::string name; 2186254721Semaste std::string value; 2187254721Semaste uint32_t cpu = LLDB_INVALID_CPUTYPE; 2188254721Semaste uint32_t sub = 0; 2189254721Semaste std::string arch_name; 2190254721Semaste std::string os_name; 2191254721Semaste std::string vendor_name; 2192254721Semaste std::string triple; 2193254721Semaste uint32_t pointer_byte_size = 0; 2194254721Semaste StringExtractor extractor; 2195254721Semaste ByteOrder byte_order = eByteOrderInvalid; 2196254721Semaste uint32_t num_keys_decoded = 0; 2197254721Semaste while (response.GetNameColonValue(name, value)) 2198254721Semaste { 2199254721Semaste if (name.compare("cputype") == 0) 2200254721Semaste { 2201254721Semaste cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16); 2202254721Semaste if (cpu != LLDB_INVALID_CPUTYPE) 2203254721Semaste ++num_keys_decoded; 2204254721Semaste } 2205254721Semaste else if (name.compare("cpusubtype") == 0) 2206254721Semaste { 2207254721Semaste sub = Args::StringToUInt32 (value.c_str(), 0, 16); 2208254721Semaste if (sub != 0) 2209254721Semaste ++num_keys_decoded; 2210254721Semaste } 2211254721Semaste else if (name.compare("ostype") == 0) 2212254721Semaste { 2213254721Semaste os_name.swap (value); 2214254721Semaste ++num_keys_decoded; 2215254721Semaste } 2216254721Semaste else if (name.compare("vendor") == 0) 2217254721Semaste { 2218254721Semaste vendor_name.swap(value); 2219254721Semaste ++num_keys_decoded; 2220254721Semaste } 2221254721Semaste else if (name.compare("endian") == 0) 2222254721Semaste { 2223254721Semaste ++num_keys_decoded; 2224254721Semaste if (value.compare("little") == 0) 2225254721Semaste byte_order = eByteOrderLittle; 2226254721Semaste else if (value.compare("big") == 0) 2227254721Semaste byte_order = eByteOrderBig; 2228254721Semaste else if (value.compare("pdp") == 0) 2229254721Semaste byte_order = eByteOrderPDP; 2230254721Semaste else 2231254721Semaste --num_keys_decoded; 2232254721Semaste } 2233254721Semaste else if (name.compare("ptrsize") == 0) 2234254721Semaste { 2235254721Semaste pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16); 2236254721Semaste if (pointer_byte_size != 0) 2237254721Semaste ++num_keys_decoded; 2238254721Semaste } 2239254721Semaste } 2240254721Semaste if (num_keys_decoded > 0) 2241254721Semaste m_qProcessInfo_is_valid = eLazyBoolYes; 2242254721Semaste if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty()) 2243254721Semaste { 2244254721Semaste m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub); 2245254721Semaste if (pointer_byte_size) 2246254721Semaste { 2247254721Semaste assert (pointer_byte_size == m_process_arch.GetAddressByteSize()); 2248254721Semaste } 2249254721Semaste m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); 2250254721Semaste m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name)); 2251254721Semaste return true; 2252254721Semaste } 2253254721Semaste } 2254254721Semaste } 2255254721Semaste else 2256254721Semaste { 2257254721Semaste m_qProcessInfo_is_valid = eLazyBoolNo; 2258254721Semaste } 2259254721Semaste 2260254721Semaste return false; 2261254721Semaste} 2262254721Semaste 2263254721Semaste 2264254721Semasteuint32_t 2265254721SemasteGDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info, 2266254721Semaste ProcessInstanceInfoList &process_infos) 2267254721Semaste{ 2268254721Semaste process_infos.Clear(); 2269254721Semaste 2270254721Semaste if (m_supports_qfProcessInfo) 2271254721Semaste { 2272254721Semaste StreamString packet; 2273254721Semaste packet.PutCString ("qfProcessInfo"); 2274254721Semaste if (!match_info.MatchAllProcesses()) 2275254721Semaste { 2276254721Semaste packet.PutChar (':'); 2277254721Semaste const char *name = match_info.GetProcessInfo().GetName(); 2278254721Semaste bool has_name_match = false; 2279254721Semaste if (name && name[0]) 2280254721Semaste { 2281254721Semaste has_name_match = true; 2282254721Semaste NameMatchType name_match_type = match_info.GetNameMatchType(); 2283254721Semaste switch (name_match_type) 2284254721Semaste { 2285254721Semaste case eNameMatchIgnore: 2286254721Semaste has_name_match = false; 2287254721Semaste break; 2288254721Semaste 2289254721Semaste case eNameMatchEquals: 2290254721Semaste packet.PutCString ("name_match:equals;"); 2291254721Semaste break; 2292254721Semaste 2293254721Semaste case eNameMatchContains: 2294254721Semaste packet.PutCString ("name_match:contains;"); 2295254721Semaste break; 2296254721Semaste 2297254721Semaste case eNameMatchStartsWith: 2298254721Semaste packet.PutCString ("name_match:starts_with;"); 2299254721Semaste break; 2300254721Semaste 2301254721Semaste case eNameMatchEndsWith: 2302254721Semaste packet.PutCString ("name_match:ends_with;"); 2303254721Semaste break; 2304254721Semaste 2305254721Semaste case eNameMatchRegularExpression: 2306254721Semaste packet.PutCString ("name_match:regex;"); 2307254721Semaste break; 2308254721Semaste } 2309254721Semaste if (has_name_match) 2310254721Semaste { 2311254721Semaste packet.PutCString ("name:"); 2312254721Semaste packet.PutBytesAsRawHex8(name, ::strlen(name)); 2313254721Semaste packet.PutChar (';'); 2314254721Semaste } 2315254721Semaste } 2316254721Semaste 2317254721Semaste if (match_info.GetProcessInfo().ProcessIDIsValid()) 2318254721Semaste packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID()); 2319254721Semaste if (match_info.GetProcessInfo().ParentProcessIDIsValid()) 2320254721Semaste packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID()); 2321254721Semaste if (match_info.GetProcessInfo().UserIDIsValid()) 2322254721Semaste packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID()); 2323254721Semaste if (match_info.GetProcessInfo().GroupIDIsValid()) 2324254721Semaste packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID()); 2325254721Semaste if (match_info.GetProcessInfo().EffectiveUserIDIsValid()) 2326254721Semaste packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID()); 2327254721Semaste if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) 2328254721Semaste packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID()); 2329254721Semaste if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) 2330254721Semaste packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0); 2331254721Semaste if (match_info.GetProcessInfo().GetArchitecture().IsValid()) 2332254721Semaste { 2333254721Semaste const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture(); 2334254721Semaste const llvm::Triple &triple = match_arch.GetTriple(); 2335254721Semaste packet.PutCString("triple:"); 2336254721Semaste packet.PutCStringAsRawHex8(triple.getTriple().c_str()); 2337254721Semaste packet.PutChar (';'); 2338254721Semaste } 2339254721Semaste } 2340254721Semaste StringExtractorGDBRemote response; 2341269024Semaste if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success) 2342254721Semaste { 2343254721Semaste do 2344254721Semaste { 2345254721Semaste ProcessInstanceInfo process_info; 2346254721Semaste if (!DecodeProcessInfoResponse (response, process_info)) 2347254721Semaste break; 2348254721Semaste process_infos.Append(process_info); 2349254721Semaste response.GetStringRef().clear(); 2350254721Semaste response.SetFilePos(0); 2351269024Semaste } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success); 2352254721Semaste } 2353254721Semaste else 2354254721Semaste { 2355254721Semaste m_supports_qfProcessInfo = false; 2356254721Semaste return 0; 2357254721Semaste } 2358254721Semaste } 2359254721Semaste return process_infos.GetSize(); 2360254721Semaste 2361254721Semaste} 2362254721Semaste 2363254721Semastebool 2364254721SemasteGDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name) 2365254721Semaste{ 2366254721Semaste if (m_supports_qUserName) 2367254721Semaste { 2368254721Semaste char packet[32]; 2369254721Semaste const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid); 2370254721Semaste assert (packet_len < (int)sizeof(packet)); 2371254721Semaste StringExtractorGDBRemote response; 2372269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 2373254721Semaste { 2374254721Semaste if (response.IsNormalResponse()) 2375254721Semaste { 2376254721Semaste // Make sure we parsed the right number of characters. The response is 2377254721Semaste // the hex encoded user name and should make up the entire packet. 2378254721Semaste // If there are any non-hex ASCII bytes, the length won't match below.. 2379254721Semaste if (response.GetHexByteString (name) * 2 == response.GetStringRef().size()) 2380254721Semaste return true; 2381254721Semaste } 2382254721Semaste } 2383254721Semaste else 2384254721Semaste { 2385254721Semaste m_supports_qUserName = false; 2386254721Semaste return false; 2387254721Semaste } 2388254721Semaste } 2389254721Semaste return false; 2390254721Semaste 2391254721Semaste} 2392254721Semaste 2393254721Semastebool 2394254721SemasteGDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name) 2395254721Semaste{ 2396254721Semaste if (m_supports_qGroupName) 2397254721Semaste { 2398254721Semaste char packet[32]; 2399254721Semaste const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid); 2400254721Semaste assert (packet_len < (int)sizeof(packet)); 2401254721Semaste StringExtractorGDBRemote response; 2402269024Semaste if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success) 2403254721Semaste { 2404254721Semaste if (response.IsNormalResponse()) 2405254721Semaste { 2406254721Semaste // Make sure we parsed the right number of characters. The response is 2407254721Semaste // the hex encoded group name and should make up the entire packet. 2408254721Semaste // If there are any non-hex ASCII bytes, the length won't match below.. 2409254721Semaste if (response.GetHexByteString (name) * 2 == response.GetStringRef().size()) 2410254721Semaste return true; 2411254721Semaste } 2412254721Semaste } 2413254721Semaste else 2414254721Semaste { 2415254721Semaste m_supports_qGroupName = false; 2416254721Semaste return false; 2417254721Semaste } 2418254721Semaste } 2419254721Semaste return false; 2420254721Semaste} 2421254721Semaste 2422254721Semastevoid 2423254721SemasteGDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets) 2424254721Semaste{ 2425254721Semaste uint32_t i; 2426254721Semaste TimeValue start_time, end_time; 2427254721Semaste uint64_t total_time_nsec; 2428254721Semaste if (SendSpeedTestPacket (0, 0)) 2429254721Semaste { 2430269024Semaste static uint32_t g_send_sizes[] = { 0, 64, 128, 512, 1024 }; 2431269024Semaste static uint32_t g_recv_sizes[] = { 0, 64, 128, 512, 1024 }; //, 4*1024, 8*1024, 16*1024, 32*1024, 48*1024, 64*1024, 96*1024, 128*1024 }; 2432269024Semaste const size_t k_num_send_sizes = sizeof(g_send_sizes)/sizeof(uint32_t); 2433269024Semaste const size_t k_num_recv_sizes = sizeof(g_recv_sizes)/sizeof(uint32_t); 2434269024Semaste const uint64_t k_recv_amount = 4*1024*1024; // Receive 4MB 2435269024Semaste for (uint32_t send_idx = 0; send_idx < k_num_send_sizes; ++send_idx) 2436254721Semaste { 2437269024Semaste const uint32_t send_size = g_send_sizes[send_idx]; 2438269024Semaste for (uint32_t recv_idx = 0; recv_idx < k_num_recv_sizes; ++recv_idx) 2439254721Semaste { 2440269024Semaste const uint32_t recv_size = g_recv_sizes[recv_idx]; 2441269024Semaste StreamString packet; 2442269024Semaste packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size); 2443269024Semaste uint32_t bytes_left = send_size; 2444269024Semaste while (bytes_left > 0) 2445269024Semaste { 2446269024Semaste if (bytes_left >= 26) 2447269024Semaste { 2448269024Semaste packet.PutCString("abcdefghijklmnopqrstuvwxyz"); 2449269024Semaste bytes_left -= 26; 2450269024Semaste } 2451269024Semaste else 2452269024Semaste { 2453269024Semaste packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz"); 2454269024Semaste bytes_left = 0; 2455269024Semaste } 2456269024Semaste } 2457269024Semaste 2458254721Semaste start_time = TimeValue::Now(); 2459269024Semaste if (recv_size == 0) 2460254721Semaste { 2461269024Semaste for (i=0; i<num_packets; ++i) 2462269024Semaste { 2463269024Semaste StringExtractorGDBRemote response; 2464269024Semaste SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false); 2465269024Semaste } 2466254721Semaste } 2467269024Semaste else 2468269024Semaste { 2469269024Semaste uint32_t bytes_read = 0; 2470269024Semaste while (bytes_read < k_recv_amount) 2471269024Semaste { 2472269024Semaste StringExtractorGDBRemote response; 2473269024Semaste SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false); 2474269024Semaste bytes_read += recv_size; 2475269024Semaste } 2476269024Semaste } 2477254721Semaste end_time = TimeValue::Now(); 2478254721Semaste total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970(); 2479254721Semaste if (recv_size == 0) 2480269024Semaste { 2481269024Semaste float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec; 2482269024Semaste printf ("%u qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %f packets/sec.\n", 2483269024Semaste num_packets, 2484269024Semaste send_size, 2485269024Semaste recv_size, 2486269024Semaste total_time_nsec / TimeValue::NanoSecPerSec, 2487269024Semaste total_time_nsec % TimeValue::NanoSecPerSec, 2488269024Semaste packets_per_second); 2489269024Semaste } 2490269024Semaste else 2491269024Semaste { 2492269024Semaste float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0); 2493269024Semaste printf ("%u qSpeedTest(send=%-7u, recv=%-7u) sent 4MB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec.\n", 2494269024Semaste num_packets, 2495269024Semaste send_size, 2496269024Semaste recv_size, 2497269024Semaste total_time_nsec / TimeValue::NanoSecPerSec, 2498269024Semaste total_time_nsec % TimeValue::NanoSecPerSec, 2499269024Semaste mb_second); 2500269024Semaste } 2501254721Semaste } 2502254721Semaste } 2503254721Semaste } 2504254721Semaste} 2505254721Semaste 2506254721Semastebool 2507254721SemasteGDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size) 2508254721Semaste{ 2509254721Semaste StreamString packet; 2510254721Semaste packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size); 2511254721Semaste uint32_t bytes_left = send_size; 2512254721Semaste while (bytes_left > 0) 2513254721Semaste { 2514254721Semaste if (bytes_left >= 26) 2515254721Semaste { 2516254721Semaste packet.PutCString("abcdefghijklmnopqrstuvwxyz"); 2517254721Semaste bytes_left -= 26; 2518254721Semaste } 2519254721Semaste else 2520254721Semaste { 2521254721Semaste packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz"); 2522254721Semaste bytes_left = 0; 2523254721Semaste } 2524254721Semaste } 2525254721Semaste 2526254721Semaste StringExtractorGDBRemote response; 2527269024Semaste return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success; 2528254721Semaste} 2529254721Semaste 2530254721Semasteuint16_t 2531269024SemasteGDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname) 2532254721Semaste{ 2533263363Semaste pid = LLDB_INVALID_PROCESS_ID; 2534254721Semaste StringExtractorGDBRemote response; 2535263363Semaste StreamString stream; 2536263367Semaste stream.PutCString("qLaunchGDBServer;"); 2537263363Semaste std::string hostname; 2538269024Semaste if (remote_accept_hostname && remote_accept_hostname[0]) 2539269024Semaste hostname = remote_accept_hostname; 2540263363Semaste else 2541263363Semaste { 2542269024Semaste if (Host::GetHostname (hostname)) 2543269024Semaste { 2544269024Semaste // Make the GDB server we launch only accept connections from this host 2545269024Semaste stream.Printf("host:%s;", hostname.c_str()); 2546269024Semaste } 2547269024Semaste else 2548269024Semaste { 2549269024Semaste // Make the GDB server we launch accept connections from any host since we can't figure out the hostname 2550269024Semaste stream.Printf("host:*;"); 2551269024Semaste } 2552263363Semaste } 2553263363Semaste const char *packet = stream.GetData(); 2554263363Semaste int packet_len = stream.GetSize(); 2555263363Semaste 2556269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2557263363Semaste { 2558254721Semaste std::string name; 2559254721Semaste std::string value; 2560254721Semaste uint16_t port = 0; 2561254721Semaste while (response.GetNameColonValue(name, value)) 2562254721Semaste { 2563263363Semaste if (name.compare("port") == 0) 2564254721Semaste port = Args::StringToUInt32(value.c_str(), 0, 0); 2565263363Semaste else if (name.compare("pid") == 0) 2566263363Semaste pid = Args::StringToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); 2567254721Semaste } 2568254721Semaste return port; 2569254721Semaste } 2570254721Semaste return 0; 2571254721Semaste} 2572254721Semaste 2573254721Semastebool 2574263363SemasteGDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid) 2575263363Semaste{ 2576263363Semaste StreamString stream; 2577263363Semaste stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid); 2578263363Semaste const char *packet = stream.GetData(); 2579263363Semaste int packet_len = stream.GetSize(); 2580263363Semaste 2581263363Semaste StringExtractorGDBRemote response; 2582269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2583263363Semaste { 2584263363Semaste if (response.IsOKResponse()) 2585263363Semaste return true; 2586263363Semaste } 2587263363Semaste return false; 2588263363Semaste} 2589263363Semaste 2590263363Semastebool 2591254721SemasteGDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid) 2592254721Semaste{ 2593254721Semaste if (m_curr_tid == tid) 2594254721Semaste return true; 2595254721Semaste 2596254721Semaste char packet[32]; 2597254721Semaste int packet_len; 2598254721Semaste if (tid == UINT64_MAX) 2599254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "Hg-1"); 2600254721Semaste else 2601254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid); 2602254721Semaste assert (packet_len + 1 < (int)sizeof(packet)); 2603254721Semaste StringExtractorGDBRemote response; 2604269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2605254721Semaste { 2606254721Semaste if (response.IsOKResponse()) 2607254721Semaste { 2608254721Semaste m_curr_tid = tid; 2609254721Semaste return true; 2610254721Semaste } 2611254721Semaste } 2612254721Semaste return false; 2613254721Semaste} 2614254721Semaste 2615254721Semastebool 2616254721SemasteGDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid) 2617254721Semaste{ 2618254721Semaste if (m_curr_tid_run == tid) 2619254721Semaste return true; 2620254721Semaste 2621254721Semaste char packet[32]; 2622254721Semaste int packet_len; 2623254721Semaste if (tid == UINT64_MAX) 2624254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "Hc-1"); 2625254721Semaste else 2626254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid); 2627254721Semaste 2628254721Semaste assert (packet_len + 1 < (int)sizeof(packet)); 2629254721Semaste StringExtractorGDBRemote response; 2630269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2631254721Semaste { 2632254721Semaste if (response.IsOKResponse()) 2633254721Semaste { 2634254721Semaste m_curr_tid_run = tid; 2635254721Semaste return true; 2636254721Semaste } 2637254721Semaste } 2638254721Semaste return false; 2639254721Semaste} 2640254721Semaste 2641254721Semastebool 2642254721SemasteGDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response) 2643254721Semaste{ 2644269024Semaste if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success) 2645254721Semaste return response.IsNormalResponse(); 2646254721Semaste return false; 2647254721Semaste} 2648254721Semaste 2649254721Semastebool 2650254721SemasteGDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response) 2651254721Semaste{ 2652254721Semaste if (m_supports_qThreadStopInfo) 2653254721Semaste { 2654254721Semaste char packet[256]; 2655254721Semaste int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid); 2656254721Semaste assert (packet_len < (int)sizeof(packet)); 2657269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2658254721Semaste { 2659263363Semaste if (response.IsUnsupportedResponse()) 2660263363Semaste m_supports_qThreadStopInfo = false; 2661263363Semaste else if (response.IsNormalResponse()) 2662254721Semaste return true; 2663254721Semaste else 2664254721Semaste return false; 2665254721Semaste } 2666254721Semaste else 2667254721Semaste { 2668254721Semaste m_supports_qThreadStopInfo = false; 2669254721Semaste } 2670254721Semaste } 2671254721Semaste return false; 2672254721Semaste} 2673254721Semaste 2674254721Semaste 2675254721Semasteuint8_t 2676254721SemasteGDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length) 2677254721Semaste{ 2678269024Semaste // Check if the stub is known not to support this breakpoint type 2679269024Semaste if (!SupportsGDBStoppointPacket(type)) 2680269024Semaste return UINT8_MAX; 2681269024Semaste // Construct the breakpoint packet 2682254721Semaste char packet[64]; 2683254721Semaste const int packet_len = ::snprintf (packet, 2684254721Semaste sizeof(packet), 2685254721Semaste "%c%i,%" PRIx64 ",%x", 2686254721Semaste insert ? 'Z' : 'z', 2687254721Semaste type, 2688254721Semaste addr, 2689254721Semaste length); 2690269024Semaste // Check we havent overwritten the end of the packet buffer 2691254721Semaste assert (packet_len + 1 < (int)sizeof(packet)); 2692254721Semaste StringExtractorGDBRemote response; 2693269024Semaste // Try to send the breakpoint packet, and check that it was correctly sent 2694269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success) 2695254721Semaste { 2696269024Semaste // Receive and OK packet when the breakpoint successfully placed 2697254721Semaste if (response.IsOKResponse()) 2698254721Semaste return 0; 2699269024Semaste 2700269024Semaste // Error while setting breakpoint, send back specific error 2701269024Semaste if (response.IsErrorResponse()) 2702254721Semaste return response.GetError(); 2703269024Semaste 2704269024Semaste // Empty packet informs us that breakpoint is not supported 2705269024Semaste if (response.IsUnsupportedResponse()) 2706254721Semaste { 2707269024Semaste // Disable this breakpoint type since it is unsupported 2708269024Semaste switch (type) 2709269024Semaste { 2710254721Semaste case eBreakpointSoftware: m_supports_z0 = false; break; 2711254721Semaste case eBreakpointHardware: m_supports_z1 = false; break; 2712254721Semaste case eWatchpointWrite: m_supports_z2 = false; break; 2713254721Semaste case eWatchpointRead: m_supports_z3 = false; break; 2714254721Semaste case eWatchpointReadWrite: m_supports_z4 = false; break; 2715269024Semaste } 2716254721Semaste } 2717254721Semaste } 2718269024Semaste // Signal generic faliure 2719254721Semaste return UINT8_MAX; 2720254721Semaste} 2721254721Semaste 2722254721Semastesize_t 2723254721SemasteGDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids, 2724254721Semaste bool &sequence_mutex_unavailable) 2725254721Semaste{ 2726254721Semaste Mutex::Locker locker; 2727254721Semaste thread_ids.clear(); 2728254721Semaste 2729254721Semaste if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex")) 2730254721Semaste { 2731254721Semaste sequence_mutex_unavailable = false; 2732254721Semaste StringExtractorGDBRemote response; 2733254721Semaste 2734269024Semaste PacketResult packet_result; 2735269024Semaste for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response); 2736269024Semaste packet_result == PacketResult::Success && response.IsNormalResponse(); 2737269024Semaste packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response)) 2738254721Semaste { 2739254721Semaste char ch = response.GetChar(); 2740254721Semaste if (ch == 'l') 2741254721Semaste break; 2742254721Semaste if (ch == 'm') 2743254721Semaste { 2744254721Semaste do 2745254721Semaste { 2746254721Semaste tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID); 2747254721Semaste 2748254721Semaste if (tid != LLDB_INVALID_THREAD_ID) 2749254721Semaste { 2750254721Semaste thread_ids.push_back (tid); 2751254721Semaste } 2752254721Semaste ch = response.GetChar(); // Skip the command separator 2753254721Semaste } while (ch == ','); // Make sure we got a comma separator 2754254721Semaste } 2755254721Semaste } 2756254721Semaste } 2757254721Semaste else 2758254721Semaste { 2759254721Semaste#if defined (LLDB_CONFIGURATION_DEBUG) 2760254721Semaste // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"); 2761254721Semaste#else 2762254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); 2763254721Semaste if (log) 2764254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'"); 2765254721Semaste#endif 2766254721Semaste sequence_mutex_unavailable = true; 2767254721Semaste } 2768254721Semaste return thread_ids.size(); 2769254721Semaste} 2770254721Semaste 2771254721Semastelldb::addr_t 2772254721SemasteGDBRemoteCommunicationClient::GetShlibInfoAddr() 2773254721Semaste{ 2774254721Semaste if (!IsRunning()) 2775254721Semaste { 2776254721Semaste StringExtractorGDBRemote response; 2777269024Semaste if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success) 2778254721Semaste { 2779254721Semaste if (response.IsNormalResponse()) 2780254721Semaste return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); 2781254721Semaste } 2782254721Semaste } 2783254721Semaste return LLDB_INVALID_ADDRESS; 2784254721Semaste} 2785254721Semaste 2786263363Semastelldb_private::Error 2787263363SemasteGDBRemoteCommunicationClient::RunShellCommand (const char *command, // Shouldn't be NULL 2788263363Semaste const char *working_dir, // Pass NULL to use the current working directory 2789263363Semaste int *status_ptr, // Pass NULL if you don't want the process exit status 2790263363Semaste int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit 2791263363Semaste std::string *command_output, // Pass NULL if you don't want the command output 2792263363Semaste uint32_t timeout_sec) // Timeout in seconds to wait for shell program to finish 2793263363Semaste{ 2794263363Semaste lldb_private::StreamString stream; 2795263367Semaste stream.PutCString("qPlatform_shell:"); 2796263363Semaste stream.PutBytesAsRawHex8(command, strlen(command)); 2797263363Semaste stream.PutChar(','); 2798263363Semaste stream.PutHex32(timeout_sec); 2799263363Semaste if (working_dir && *working_dir) 2800263363Semaste { 2801263363Semaste stream.PutChar(','); 2802263363Semaste stream.PutBytesAsRawHex8(working_dir, strlen(working_dir)); 2803263363Semaste } 2804263363Semaste const char *packet = stream.GetData(); 2805263363Semaste int packet_len = stream.GetSize(); 2806263363Semaste StringExtractorGDBRemote response; 2807269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2808263363Semaste { 2809263363Semaste if (response.GetChar() != 'F') 2810263363Semaste return Error("malformed reply"); 2811263363Semaste if (response.GetChar() != ',') 2812263363Semaste return Error("malformed reply"); 2813263363Semaste uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX); 2814263363Semaste if (exitcode == UINT32_MAX) 2815263363Semaste return Error("unable to run remote process"); 2816263363Semaste else if (status_ptr) 2817263363Semaste *status_ptr = exitcode; 2818263363Semaste if (response.GetChar() != ',') 2819263363Semaste return Error("malformed reply"); 2820263363Semaste uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX); 2821263363Semaste if (signo_ptr) 2822263363Semaste *signo_ptr = signo; 2823263363Semaste if (response.GetChar() != ',') 2824263363Semaste return Error("malformed reply"); 2825263363Semaste std::string output; 2826263363Semaste response.GetEscapedBinaryData(output); 2827263363Semaste if (command_output) 2828263363Semaste command_output->assign(output); 2829263363Semaste return Error(); 2830263363Semaste } 2831263363Semaste return Error("unable to send packet"); 2832263363Semaste} 2833263363Semaste 2834263367SemasteError 2835263367SemasteGDBRemoteCommunicationClient::MakeDirectory (const char *path, 2836263367Semaste uint32_t file_permissions) 2837263363Semaste{ 2838263363Semaste lldb_private::StreamString stream; 2839263367Semaste stream.PutCString("qPlatform_mkdir:"); 2840263367Semaste stream.PutHex32(file_permissions); 2841263363Semaste stream.PutChar(','); 2842263367Semaste stream.PutBytesAsRawHex8(path, strlen(path)); 2843263363Semaste const char *packet = stream.GetData(); 2844263363Semaste int packet_len = stream.GetSize(); 2845263363Semaste StringExtractorGDBRemote response; 2846269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2847263363Semaste { 2848263367Semaste return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX); 2849263363Semaste } 2850263367Semaste return Error(); 2851263363Semaste 2852263363Semaste} 2853263363Semaste 2854263367SemasteError 2855263367SemasteGDBRemoteCommunicationClient::SetFilePermissions (const char *path, 2856263367Semaste uint32_t file_permissions) 2857263367Semaste{ 2858263367Semaste lldb_private::StreamString stream; 2859263367Semaste stream.PutCString("qPlatform_chmod:"); 2860263367Semaste stream.PutHex32(file_permissions); 2861263367Semaste stream.PutChar(','); 2862263367Semaste stream.PutBytesAsRawHex8(path, strlen(path)); 2863263367Semaste const char *packet = stream.GetData(); 2864263367Semaste int packet_len = stream.GetSize(); 2865263367Semaste StringExtractorGDBRemote response; 2866269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2867263367Semaste { 2868263367Semaste return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX); 2869263367Semaste } 2870263367Semaste return Error(); 2871263367Semaste 2872263367Semaste} 2873263367Semaste 2874263363Semastestatic uint64_t 2875263363SemasteParseHostIOPacketResponse (StringExtractorGDBRemote &response, 2876263363Semaste uint64_t fail_result, 2877263363Semaste Error &error) 2878263363Semaste{ 2879263363Semaste response.SetFilePos(0); 2880263363Semaste if (response.GetChar() != 'F') 2881263363Semaste return fail_result; 2882263363Semaste int32_t result = response.GetS32 (-2); 2883263363Semaste if (result == -2) 2884263363Semaste return fail_result; 2885263363Semaste if (response.GetChar() == ',') 2886263363Semaste { 2887263363Semaste int result_errno = response.GetS32 (-2); 2888263363Semaste if (result_errno != -2) 2889263363Semaste error.SetError(result_errno, eErrorTypePOSIX); 2890263363Semaste else 2891263363Semaste error.SetError(-1, eErrorTypeGeneric); 2892263363Semaste } 2893263363Semaste else 2894263363Semaste error.Clear(); 2895263363Semaste return result; 2896263363Semaste} 2897263363Semastelldb::user_id_t 2898263363SemasteGDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec, 2899263363Semaste uint32_t flags, 2900263363Semaste mode_t mode, 2901263363Semaste Error &error) 2902263363Semaste{ 2903263363Semaste lldb_private::StreamString stream; 2904263363Semaste stream.PutCString("vFile:open:"); 2905263363Semaste std::string path (file_spec.GetPath()); 2906263363Semaste if (path.empty()) 2907263363Semaste return UINT64_MAX; 2908263363Semaste stream.PutCStringAsRawHex8(path.c_str()); 2909263363Semaste stream.PutChar(','); 2910263363Semaste const uint32_t posix_open_flags = File::ConvertOpenOptionsForPOSIXOpen(flags); 2911263363Semaste stream.PutHex32(posix_open_flags); 2912263363Semaste stream.PutChar(','); 2913263363Semaste stream.PutHex32(mode); 2914263363Semaste const char* packet = stream.GetData(); 2915263363Semaste int packet_len = stream.GetSize(); 2916263363Semaste StringExtractorGDBRemote response; 2917269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2918263363Semaste { 2919263363Semaste return ParseHostIOPacketResponse (response, UINT64_MAX, error); 2920263363Semaste } 2921263363Semaste return UINT64_MAX; 2922263363Semaste} 2923263363Semaste 2924263363Semastebool 2925263363SemasteGDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd, 2926263363Semaste Error &error) 2927263363Semaste{ 2928263363Semaste lldb_private::StreamString stream; 2929263363Semaste stream.Printf("vFile:close:%i", (int)fd); 2930263363Semaste const char* packet = stream.GetData(); 2931263363Semaste int packet_len = stream.GetSize(); 2932263363Semaste StringExtractorGDBRemote response; 2933269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2934263363Semaste { 2935263363Semaste return ParseHostIOPacketResponse (response, -1, error) == 0; 2936263363Semaste } 2937263363Semaste return false; 2938263363Semaste} 2939263363Semaste 2940263363Semaste// Extension of host I/O packets to get the file size. 2941263363Semastelldb::user_id_t 2942263363SemasteGDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec) 2943263363Semaste{ 2944263363Semaste lldb_private::StreamString stream; 2945263363Semaste stream.PutCString("vFile:size:"); 2946263363Semaste std::string path (file_spec.GetPath()); 2947263363Semaste stream.PutCStringAsRawHex8(path.c_str()); 2948263363Semaste const char* packet = stream.GetData(); 2949263363Semaste int packet_len = stream.GetSize(); 2950263363Semaste StringExtractorGDBRemote response; 2951269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2952263363Semaste { 2953263363Semaste if (response.GetChar() != 'F') 2954263363Semaste return UINT64_MAX; 2955263363Semaste uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX); 2956263363Semaste return retcode; 2957263363Semaste } 2958263363Semaste return UINT64_MAX; 2959263363Semaste} 2960263363Semaste 2961263367SemasteError 2962263367SemasteGDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &file_permissions) 2963263363Semaste{ 2964263367Semaste Error error; 2965263363Semaste lldb_private::StreamString stream; 2966263363Semaste stream.PutCString("vFile:mode:"); 2967263367Semaste stream.PutCStringAsRawHex8(path); 2968263363Semaste const char* packet = stream.GetData(); 2969263363Semaste int packet_len = stream.GetSize(); 2970263363Semaste StringExtractorGDBRemote response; 2971269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 2972263363Semaste { 2973263363Semaste if (response.GetChar() != 'F') 2974263363Semaste { 2975263363Semaste error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet); 2976263363Semaste } 2977263367Semaste else 2978263363Semaste { 2979263367Semaste const uint32_t mode = response.GetS32(-1); 2980263367Semaste if (mode == -1) 2981263363Semaste { 2982263367Semaste if (response.GetChar() == ',') 2983263367Semaste { 2984263367Semaste int response_errno = response.GetS32(-1); 2985263367Semaste if (response_errno > 0) 2986263367Semaste error.SetError(response_errno, lldb::eErrorTypePOSIX); 2987263367Semaste else 2988263367Semaste error.SetErrorToGenericError(); 2989263367Semaste } 2990263363Semaste else 2991263363Semaste error.SetErrorToGenericError(); 2992263363Semaste } 2993263367Semaste else 2994263367Semaste { 2995263367Semaste file_permissions = mode & (S_IRWXU|S_IRWXG|S_IRWXO); 2996263367Semaste } 2997263363Semaste } 2998263363Semaste } 2999263363Semaste else 3000263363Semaste { 3001263363Semaste error.SetErrorStringWithFormat ("failed to send '%s' packet", packet); 3002263363Semaste } 3003263367Semaste return error; 3004263363Semaste} 3005263363Semaste 3006263363Semasteuint64_t 3007263363SemasteGDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd, 3008263363Semaste uint64_t offset, 3009263363Semaste void *dst, 3010263363Semaste uint64_t dst_len, 3011263363Semaste Error &error) 3012263363Semaste{ 3013263363Semaste lldb_private::StreamString stream; 3014263363Semaste stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset); 3015263363Semaste const char* packet = stream.GetData(); 3016263363Semaste int packet_len = stream.GetSize(); 3017263363Semaste StringExtractorGDBRemote response; 3018269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 3019263363Semaste { 3020263363Semaste if (response.GetChar() != 'F') 3021263363Semaste return 0; 3022263363Semaste uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX); 3023263363Semaste if (retcode == UINT32_MAX) 3024263363Semaste return retcode; 3025263363Semaste const char next = (response.Peek() ? *response.Peek() : 0); 3026263363Semaste if (next == ',') 3027263363Semaste return 0; 3028263363Semaste if (next == ';') 3029263363Semaste { 3030263363Semaste response.GetChar(); // skip the semicolon 3031263363Semaste std::string buffer; 3032263363Semaste if (response.GetEscapedBinaryData(buffer)) 3033263363Semaste { 3034263363Semaste const uint64_t data_to_write = std::min<uint64_t>(dst_len, buffer.size()); 3035263363Semaste if (data_to_write > 0) 3036263363Semaste memcpy(dst, &buffer[0], data_to_write); 3037263363Semaste return data_to_write; 3038263363Semaste } 3039263363Semaste } 3040263363Semaste } 3041263363Semaste return 0; 3042263363Semaste} 3043263363Semaste 3044263363Semasteuint64_t 3045263363SemasteGDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd, 3046263363Semaste uint64_t offset, 3047263363Semaste const void* src, 3048263363Semaste uint64_t src_len, 3049263363Semaste Error &error) 3050263363Semaste{ 3051263363Semaste lldb_private::StreamGDBRemote stream; 3052263363Semaste stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset); 3053263363Semaste stream.PutEscapedBytes(src, src_len); 3054263363Semaste const char* packet = stream.GetData(); 3055263363Semaste int packet_len = stream.GetSize(); 3056263363Semaste StringExtractorGDBRemote response; 3057269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 3058263363Semaste { 3059263363Semaste if (response.GetChar() != 'F') 3060263363Semaste { 3061263363Semaste error.SetErrorStringWithFormat("write file failed"); 3062263363Semaste return 0; 3063263363Semaste } 3064263363Semaste uint64_t bytes_written = response.GetU64(UINT64_MAX); 3065263363Semaste if (bytes_written == UINT64_MAX) 3066263363Semaste { 3067263363Semaste error.SetErrorToGenericError(); 3068263363Semaste if (response.GetChar() == ',') 3069263363Semaste { 3070263363Semaste int response_errno = response.GetS32(-1); 3071263363Semaste if (response_errno > 0) 3072263363Semaste error.SetError(response_errno, lldb::eErrorTypePOSIX); 3073263363Semaste } 3074263363Semaste return 0; 3075263363Semaste } 3076263363Semaste return bytes_written; 3077263363Semaste } 3078263363Semaste else 3079263363Semaste { 3080263363Semaste error.SetErrorString ("failed to send vFile:pwrite packet"); 3081263363Semaste } 3082263363Semaste return 0; 3083263363Semaste} 3084263363Semaste 3085263367SemasteError 3086263367SemasteGDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst) 3087263367Semaste{ 3088263367Semaste Error error; 3089263367Semaste lldb_private::StreamGDBRemote stream; 3090263367Semaste stream.PutCString("vFile:symlink:"); 3091263367Semaste // the unix symlink() command reverses its parameters where the dst if first, 3092263367Semaste // so we follow suit here 3093263367Semaste stream.PutCStringAsRawHex8(dst); 3094263367Semaste stream.PutChar(','); 3095263367Semaste stream.PutCStringAsRawHex8(src); 3096263367Semaste const char* packet = stream.GetData(); 3097263367Semaste int packet_len = stream.GetSize(); 3098263367Semaste StringExtractorGDBRemote response; 3099269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 3100263367Semaste { 3101263367Semaste if (response.GetChar() == 'F') 3102263367Semaste { 3103263367Semaste uint32_t result = response.GetU32(UINT32_MAX); 3104263367Semaste if (result != 0) 3105263367Semaste { 3106263367Semaste error.SetErrorToGenericError(); 3107263367Semaste if (response.GetChar() == ',') 3108263367Semaste { 3109263367Semaste int response_errno = response.GetS32(-1); 3110263367Semaste if (response_errno > 0) 3111263367Semaste error.SetError(response_errno, lldb::eErrorTypePOSIX); 3112263367Semaste } 3113263367Semaste } 3114263367Semaste } 3115263367Semaste else 3116263367Semaste { 3117263367Semaste // Should have returned with 'F<result>[,<errno>]' 3118263367Semaste error.SetErrorStringWithFormat("symlink failed"); 3119263367Semaste } 3120263367Semaste } 3121263367Semaste else 3122263367Semaste { 3123263367Semaste error.SetErrorString ("failed to send vFile:symlink packet"); 3124263367Semaste } 3125263367Semaste return error; 3126263367Semaste} 3127263367Semaste 3128263367SemasteError 3129263367SemasteGDBRemoteCommunicationClient::Unlink (const char *path) 3130263367Semaste{ 3131263367Semaste Error error; 3132263367Semaste lldb_private::StreamGDBRemote stream; 3133263367Semaste stream.PutCString("vFile:unlink:"); 3134263367Semaste // the unix symlink() command reverses its parameters where the dst if first, 3135263367Semaste // so we follow suit here 3136263367Semaste stream.PutCStringAsRawHex8(path); 3137263367Semaste const char* packet = stream.GetData(); 3138263367Semaste int packet_len = stream.GetSize(); 3139263367Semaste StringExtractorGDBRemote response; 3140269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 3141263367Semaste { 3142263367Semaste if (response.GetChar() == 'F') 3143263367Semaste { 3144263367Semaste uint32_t result = response.GetU32(UINT32_MAX); 3145263367Semaste if (result != 0) 3146263367Semaste { 3147263367Semaste error.SetErrorToGenericError(); 3148263367Semaste if (response.GetChar() == ',') 3149263367Semaste { 3150263367Semaste int response_errno = response.GetS32(-1); 3151263367Semaste if (response_errno > 0) 3152263367Semaste error.SetError(response_errno, lldb::eErrorTypePOSIX); 3153263367Semaste } 3154263367Semaste } 3155263367Semaste } 3156263367Semaste else 3157263367Semaste { 3158263367Semaste // Should have returned with 'F<result>[,<errno>]' 3159263367Semaste error.SetErrorStringWithFormat("unlink failed"); 3160263367Semaste } 3161263367Semaste } 3162263367Semaste else 3163263367Semaste { 3164263367Semaste error.SetErrorString ("failed to send vFile:unlink packet"); 3165263367Semaste } 3166263367Semaste return error; 3167263367Semaste} 3168263367Semaste 3169263363Semaste// Extension of host I/O packets to get whether a file exists. 3170263363Semastebool 3171263363SemasteGDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec) 3172263363Semaste{ 3173263363Semaste lldb_private::StreamString stream; 3174263363Semaste stream.PutCString("vFile:exists:"); 3175263363Semaste std::string path (file_spec.GetPath()); 3176263363Semaste stream.PutCStringAsRawHex8(path.c_str()); 3177263363Semaste const char* packet = stream.GetData(); 3178263363Semaste int packet_len = stream.GetSize(); 3179263363Semaste StringExtractorGDBRemote response; 3180269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 3181263363Semaste { 3182263363Semaste if (response.GetChar() != 'F') 3183263363Semaste return false; 3184263363Semaste if (response.GetChar() != ',') 3185263363Semaste return false; 3186263363Semaste bool retcode = (response.GetChar() != '0'); 3187263363Semaste return retcode; 3188263363Semaste } 3189263363Semaste return false; 3190263363Semaste} 3191263363Semaste 3192263363Semastebool 3193263363SemasteGDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec, 3194263363Semaste uint64_t &high, 3195263363Semaste uint64_t &low) 3196263363Semaste{ 3197263363Semaste lldb_private::StreamString stream; 3198263363Semaste stream.PutCString("vFile:MD5:"); 3199263363Semaste std::string path (file_spec.GetPath()); 3200263363Semaste stream.PutCStringAsRawHex8(path.c_str()); 3201263363Semaste const char* packet = stream.GetData(); 3202263363Semaste int packet_len = stream.GetSize(); 3203263363Semaste StringExtractorGDBRemote response; 3204269024Semaste if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success) 3205263363Semaste { 3206263363Semaste if (response.GetChar() != 'F') 3207263363Semaste return false; 3208263363Semaste if (response.GetChar() != ',') 3209263363Semaste return false; 3210263363Semaste if (response.Peek() && *response.Peek() == 'x') 3211263363Semaste return false; 3212263363Semaste low = response.GetHexMaxU64(false, UINT64_MAX); 3213263363Semaste high = response.GetHexMaxU64(false, UINT64_MAX); 3214263363Semaste return true; 3215263363Semaste } 3216263363Semaste return false; 3217263363Semaste} 3218263367Semaste 3219263367Semastebool 3220263367SemasteGDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response) 3221263367Semaste{ 3222263367Semaste Mutex::Locker locker; 3223263367Semaste if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet.")) 3224263367Semaste { 3225263367Semaste const bool thread_suffix_supported = GetThreadSuffixSupported(); 3226263367Semaste 3227263367Semaste if (thread_suffix_supported || SetCurrentThread(tid)) 3228263367Semaste { 3229263367Semaste char packet[64]; 3230263367Semaste int packet_len = 0; 3231263367Semaste if (thread_suffix_supported) 3232263367Semaste packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid); 3233263367Semaste else 3234263367Semaste packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg); 3235263367Semaste assert (packet_len < ((int)sizeof(packet) - 1)); 3236269024Semaste return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success; 3237263367Semaste } 3238263367Semaste } 3239263367Semaste return false; 3240263367Semaste 3241263367Semaste} 3242263367Semaste 3243263367Semaste 3244263367Semastebool 3245263367SemasteGDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response) 3246263367Semaste{ 3247263367Semaste Mutex::Locker locker; 3248263367Semaste if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet.")) 3249263367Semaste { 3250263367Semaste const bool thread_suffix_supported = GetThreadSuffixSupported(); 3251263367Semaste 3252263367Semaste if (thread_suffix_supported || SetCurrentThread(tid)) 3253263367Semaste { 3254263367Semaste char packet[64]; 3255263367Semaste int packet_len = 0; 3256263367Semaste // Get all registers in one packet 3257263367Semaste if (thread_suffix_supported) 3258263367Semaste packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid); 3259263367Semaste else 3260263367Semaste packet_len = ::snprintf (packet, sizeof(packet), "g"); 3261263367Semaste assert (packet_len < ((int)sizeof(packet) - 1)); 3262269024Semaste return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success; 3263263367Semaste } 3264263367Semaste } 3265263367Semaste return false; 3266263367Semaste} 3267263367Semastebool 3268263367SemasteGDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id) 3269263367Semaste{ 3270263367Semaste save_id = 0; // Set to invalid save ID 3271263367Semaste if (m_supports_QSaveRegisterState == eLazyBoolNo) 3272263367Semaste return false; 3273263367Semaste 3274263367Semaste m_supports_QSaveRegisterState = eLazyBoolYes; 3275263367Semaste Mutex::Locker locker; 3276263367Semaste if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState.")) 3277263367Semaste { 3278263367Semaste const bool thread_suffix_supported = GetThreadSuffixSupported(); 3279263367Semaste if (thread_suffix_supported || SetCurrentThread(tid)) 3280263367Semaste { 3281263367Semaste char packet[256]; 3282263367Semaste if (thread_suffix_supported) 3283263367Semaste ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid); 3284263367Semaste else 3285263367Semaste ::strncpy (packet, "QSaveRegisterState", sizeof(packet)); 3286263367Semaste 3287263367Semaste StringExtractorGDBRemote response; 3288263367Semaste 3289269024Semaste if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success) 3290263367Semaste { 3291263367Semaste if (response.IsUnsupportedResponse()) 3292263367Semaste { 3293263367Semaste // This packet isn't supported, don't try calling it again 3294263367Semaste m_supports_QSaveRegisterState = eLazyBoolNo; 3295263367Semaste } 3296263367Semaste 3297263367Semaste const uint32_t response_save_id = response.GetU32(0); 3298263367Semaste if (response_save_id != 0) 3299263367Semaste { 3300263367Semaste save_id = response_save_id; 3301263367Semaste return true; 3302263367Semaste } 3303263367Semaste } 3304263367Semaste } 3305263367Semaste } 3306263367Semaste return false; 3307263367Semaste} 3308263367Semaste 3309263367Semastebool 3310263367SemasteGDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id) 3311263367Semaste{ 3312263367Semaste // We use the "m_supports_QSaveRegisterState" variable here becuase the 3313263367Semaste // QSaveRegisterState and QRestoreRegisterState packets must both be supported in 3314263367Semaste // order to be useful 3315263367Semaste if (m_supports_QSaveRegisterState == eLazyBoolNo) 3316263367Semaste return false; 3317263367Semaste 3318263367Semaste Mutex::Locker locker; 3319263367Semaste if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState.")) 3320263367Semaste { 3321263367Semaste const bool thread_suffix_supported = GetThreadSuffixSupported(); 3322263367Semaste if (thread_suffix_supported || SetCurrentThread(tid)) 3323263367Semaste { 3324263367Semaste char packet[256]; 3325263367Semaste if (thread_suffix_supported) 3326263367Semaste ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid); 3327263367Semaste else 3328263367Semaste ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id); 3329263367Semaste 3330263367Semaste StringExtractorGDBRemote response; 3331263367Semaste 3332269024Semaste if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success) 3333263367Semaste { 3334263367Semaste if (response.IsOKResponse()) 3335263367Semaste { 3336263367Semaste return true; 3337263367Semaste } 3338263367Semaste else if (response.IsUnsupportedResponse()) 3339263367Semaste { 3340263367Semaste // This packet isn't supported, don't try calling this packet or 3341263367Semaste // QSaveRegisterState again... 3342263367Semaste m_supports_QSaveRegisterState = eLazyBoolNo; 3343263367Semaste } 3344263367Semaste } 3345263367Semaste } 3346263367Semaste } 3347263367Semaste return false; 3348263367Semaste} 3349