4386 lines · cpp
1//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "GDBRemoteCommunicationClient.h"10 11#include <cmath>12#include <sys/stat.h>13 14#include <numeric>15#include <optional>16#include <sstream>17 18#include "lldb/Core/ModuleSpec.h"19#include "lldb/Host/HostInfo.h"20#include "lldb/Host/SafeMachO.h"21#include "lldb/Host/XML.h"22#include "lldb/Symbol/Symbol.h"23#include "lldb/Target/MemoryRegionInfo.h"24#include "lldb/Target/Target.h"25#include "lldb/Target/UnixSignals.h"26#include "lldb/Utility/Args.h"27#include "lldb/Utility/DataBufferHeap.h"28#include "lldb/Utility/LLDBAssert.h"29#include "lldb/Utility/LLDBLog.h"30#include "lldb/Utility/Log.h"31#include "lldb/Utility/State.h"32#include "lldb/Utility/StreamString.h"33 34#include "ProcessGDBRemote.h"35#include "ProcessGDBRemoteLog.h"36#include "lldb/Host/Config.h"37#include "lldb/Utility/StringExtractorGDBRemote.h"38 39#include "llvm/ADT/STLExtras.h"40#include "llvm/ADT/StringSwitch.h"41#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB42#include "llvm/Support/JSON.h"43 44#if HAVE_LIBCOMPRESSION45#include <compression.h>46#endif47 48using namespace lldb;49using namespace lldb_private::process_gdb_remote;50using namespace lldb_private;51using namespace std::chrono;52 53llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,54 const QOffsets &offsets) {55 return os << llvm::formatv(56 "QOffsets({0}, [{1:@[x]}])", offsets.segments,57 llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));58}59 60// GDBRemoteCommunicationClient constructor61GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()62 : GDBRemoteClientBase("gdb-remote.client"),63 64 m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),65 m_supports_qUserName(true), m_supports_qGroupName(true),66 m_supports_qThreadStopInfo(true), m_supports_z0(true),67 m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),68 m_supports_z4(true), m_supports_QEnvironment(true),69 m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),70 m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),71 m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),72 m_supports_vFileSize(true), m_supports_vFileMode(true),73 m_supports_vFileExists(true), m_supports_vRun(true),74 75 m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(),76 m_os_kernel(), m_hostname(), m_gdb_server_name(),77 m_default_packet_timeout(0), m_qSupported_response(),78 m_supported_async_json_packets_sp(), m_qXfer_memory_map() {}79 80// Destructor81GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {82 if (IsConnected())83 Disconnect();84}85 86bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {87 ResetDiscoverableSettings(false);88 89 // Start the read thread after we send the handshake ack since if we fail to90 // send the handshake ack, there is no reason to continue...91 std::chrono::steady_clock::time_point start_of_handshake =92 std::chrono::steady_clock::now();93 if (SendAck()) {94 // The return value from QueryNoAckModeSupported() is true if the packet95 // was sent and _any_ response (including UNIMPLEMENTED) was received), or96 // false if no response was received. This quickly tells us if we have a97 // live connection to a remote GDB server...98 if (QueryNoAckModeSupported()) {99 return true;100 } else {101 std::chrono::steady_clock::time_point end_of_handshake =102 std::chrono::steady_clock::now();103 auto handshake_timeout =104 std::chrono::duration<double>(end_of_handshake - start_of_handshake)105 .count();106 if (error_ptr) {107 if (!IsConnected())108 *error_ptr =109 Status::FromErrorString("Connection shut down by remote side "110 "while waiting for reply to initial "111 "handshake packet");112 else113 *error_ptr = Status::FromErrorStringWithFormat(114 "failed to get reply to handshake packet within timeout of "115 "%.1f seconds",116 handshake_timeout);117 }118 }119 } else {120 if (error_ptr)121 *error_ptr = Status::FromErrorString("failed to send the handshake ack");122 }123 return false;124}125 126bool GDBRemoteCommunicationClient::GetEchoSupported() {127 if (m_supports_qEcho == eLazyBoolCalculate) {128 GetRemoteQSupported();129 }130 return m_supports_qEcho == eLazyBoolYes;131}132 133bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {134 if (m_supports_QPassSignals == eLazyBoolCalculate) {135 GetRemoteQSupported();136 }137 return m_supports_QPassSignals == eLazyBoolYes;138}139 140bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {141 if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {142 GetRemoteQSupported();143 }144 return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;145}146 147bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {148 if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {149 GetRemoteQSupported();150 }151 return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;152}153 154bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {155 if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {156 GetRemoteQSupported();157 }158 return m_supports_qXfer_libraries_read == eLazyBoolYes;159}160 161bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {162 if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {163 GetRemoteQSupported();164 }165 return m_supports_qXfer_auxv_read == eLazyBoolYes;166}167 168bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {169 if (m_supports_qXfer_features_read == eLazyBoolCalculate) {170 GetRemoteQSupported();171 }172 return m_supports_qXfer_features_read == eLazyBoolYes;173}174 175bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {176 if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {177 GetRemoteQSupported();178 }179 return m_supports_qXfer_memory_map_read == eLazyBoolYes;180}181 182bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {183 if (m_supports_qXfer_siginfo_read == eLazyBoolCalculate) {184 GetRemoteQSupported();185 }186 return m_supports_qXfer_siginfo_read == eLazyBoolYes;187}188 189bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {190 if (m_supports_memory_tagging == eLazyBoolCalculate)191 GetRemoteQSupported();192 return m_supports_multiprocess == eLazyBoolYes;193}194 195uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {196 if (m_max_packet_size == 0) {197 GetRemoteQSupported();198 }199 return m_max_packet_size;200}201 202bool GDBRemoteCommunicationClient::GetReverseContinueSupported() {203 if (m_supports_reverse_continue == eLazyBoolCalculate)204 GetRemoteQSupported();205 return m_supports_reverse_continue == eLazyBoolYes;206}207 208bool GDBRemoteCommunicationClient::GetReverseStepSupported() {209 if (m_supports_reverse_step == eLazyBoolCalculate)210 GetRemoteQSupported();211 return m_supports_reverse_step == eLazyBoolYes;212}213 214bool GDBRemoteCommunicationClient::GetMultiMemReadSupported() {215 if (m_supports_multi_mem_read == eLazyBoolCalculate)216 GetRemoteQSupported();217 return m_supports_multi_mem_read == eLazyBoolYes;218}219 220bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {221 if (m_supports_not_sending_acks == eLazyBoolCalculate) {222 m_send_acks = true;223 m_supports_not_sending_acks = eLazyBoolNo;224 225 // This is the first real packet that we'll send in a debug session and it226 // may take a little longer than normal to receive a reply. Wait at least227 // 6 seconds for a reply to this packet.228 229 ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));230 231 StringExtractorGDBRemote response;232 if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==233 PacketResult::Success) {234 if (response.IsOKResponse()) {235 m_send_acks = false;236 m_supports_not_sending_acks = eLazyBoolYes;237 }238 return true;239 }240 }241 return false;242}243 244void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {245 if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {246 m_supports_threads_in_stop_reply = eLazyBoolNo;247 248 StringExtractorGDBRemote response;249 if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==250 PacketResult::Success) {251 if (response.IsOKResponse())252 m_supports_threads_in_stop_reply = eLazyBoolYes;253 }254 }255}256 257bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {258 if (m_attach_or_wait_reply == eLazyBoolCalculate) {259 m_attach_or_wait_reply = eLazyBoolNo;260 261 StringExtractorGDBRemote response;262 if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==263 PacketResult::Success) {264 if (response.IsOKResponse())265 m_attach_or_wait_reply = eLazyBoolYes;266 }267 }268 return m_attach_or_wait_reply == eLazyBoolYes;269}270 271bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {272 if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {273 m_prepare_for_reg_writing_reply = eLazyBoolNo;274 275 StringExtractorGDBRemote response;276 if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==277 PacketResult::Success) {278 if (response.IsOKResponse())279 m_prepare_for_reg_writing_reply = eLazyBoolYes;280 }281 }282 return m_prepare_for_reg_writing_reply == eLazyBoolYes;283}284 285void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {286 if (!did_exec) {287 // Hard reset everything, this is when we first connect to a GDB server288 m_supports_not_sending_acks = eLazyBoolCalculate;289 m_supports_thread_suffix = eLazyBoolCalculate;290 m_supports_threads_in_stop_reply = eLazyBoolCalculate;291 m_supports_vCont_c = eLazyBoolCalculate;292 m_supports_vCont_C = eLazyBoolCalculate;293 m_supports_vCont_s = eLazyBoolCalculate;294 m_supports_vCont_S = eLazyBoolCalculate;295 m_supports_p = eLazyBoolCalculate;296 m_supports_QSaveRegisterState = eLazyBoolCalculate;297 m_qHostInfo_is_valid = eLazyBoolCalculate;298 m_curr_pid_is_valid = eLazyBoolCalculate;299 m_qGDBServerVersion_is_valid = eLazyBoolCalculate;300 m_supports_alloc_dealloc_memory = eLazyBoolCalculate;301 m_supports_memory_region_info = eLazyBoolCalculate;302 m_prepare_for_reg_writing_reply = eLazyBoolCalculate;303 m_attach_or_wait_reply = eLazyBoolCalculate;304 m_avoid_g_packets = eLazyBoolCalculate;305 m_supports_multiprocess = eLazyBoolCalculate;306 m_supports_qSaveCore = eLazyBoolCalculate;307 m_supports_qXfer_auxv_read = eLazyBoolCalculate;308 m_supports_qXfer_libraries_read = eLazyBoolCalculate;309 m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;310 m_supports_qXfer_features_read = eLazyBoolCalculate;311 m_supports_qXfer_memory_map_read = eLazyBoolCalculate;312 m_supports_qXfer_siginfo_read = eLazyBoolCalculate;313 m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;314 m_uses_native_signals = eLazyBoolCalculate;315 m_x_packet_state.reset();316 m_supports_reverse_continue = eLazyBoolCalculate;317 m_supports_reverse_step = eLazyBoolCalculate;318 m_supports_qProcessInfoPID = true;319 m_supports_qfProcessInfo = true;320 m_supports_qUserName = true;321 m_supports_qGroupName = true;322 m_supports_qThreadStopInfo = true;323 m_supports_z0 = true;324 m_supports_z1 = true;325 m_supports_z2 = true;326 m_supports_z3 = true;327 m_supports_z4 = true;328 m_supports_QEnvironment = true;329 m_supports_QEnvironmentHexEncoded = true;330 m_supports_qSymbol = true;331 m_qSymbol_requests_done = false;332 m_supports_qModuleInfo = true;333 m_host_arch.Clear();334 m_host_distribution_id.clear();335 m_os_version = llvm::VersionTuple();336 m_os_build.clear();337 m_os_kernel.clear();338 m_hostname.clear();339 m_gdb_server_name.clear();340 m_gdb_server_version = UINT32_MAX;341 m_default_packet_timeout = seconds(0);342 m_target_vm_page_size = 0;343 m_max_packet_size = 0;344 m_qSupported_response.clear();345 m_supported_async_json_packets_is_valid = false;346 m_supported_async_json_packets_sp.reset();347 m_supports_jModulesInfo = true;348 m_supports_multi_mem_read = eLazyBoolCalculate;349 }350 351 // These flags should be reset when we first connect to a GDB server and when352 // our inferior process execs353 m_qProcessInfo_is_valid = eLazyBoolCalculate;354 m_process_arch.Clear();355}356 357void GDBRemoteCommunicationClient::GetRemoteQSupported() {358 // Clear out any capabilities we expect to see in the qSupported response359 m_supports_qXfer_auxv_read = eLazyBoolNo;360 m_supports_qXfer_libraries_read = eLazyBoolNo;361 m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;362 m_supports_augmented_libraries_svr4_read = eLazyBoolNo;363 m_supports_qXfer_features_read = eLazyBoolNo;364 m_supports_qXfer_memory_map_read = eLazyBoolNo;365 m_supports_qXfer_siginfo_read = eLazyBoolNo;366 m_supports_multiprocess = eLazyBoolNo;367 m_supports_qEcho = eLazyBoolNo;368 m_supports_QPassSignals = eLazyBoolNo;369 m_supports_memory_tagging = eLazyBoolNo;370 m_supports_qSaveCore = eLazyBoolNo;371 m_uses_native_signals = eLazyBoolNo;372 m_x_packet_state.reset();373 m_supports_reverse_continue = eLazyBoolNo;374 m_supports_reverse_step = eLazyBoolNo;375 m_supports_multi_mem_read = eLazyBoolNo;376 377 m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if378 // not, we assume no limit379 380 // build the qSupported packet381 std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",382 "multiprocess+",383 "fork-events+",384 "vfork-events+",385 "swbreak+",386 "hwbreak+"};387 StreamString packet;388 packet.PutCString("qSupported");389 for (uint32_t i = 0; i < features.size(); ++i) {390 packet.PutCString(i == 0 ? ":" : ";");391 packet.PutCString(features[i]);392 }393 394 StringExtractorGDBRemote response;395 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==396 PacketResult::Success) {397 // Hang on to the qSupported packet, so that platforms can do custom398 // configuration of the transport before attaching/launching the process.399 m_qSupported_response = response.GetStringRef().str();400 401 for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {402 if (x == "qXfer:auxv:read+")403 m_supports_qXfer_auxv_read = eLazyBoolYes;404 else if (x == "qXfer:libraries-svr4:read+")405 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;406 else if (x == "augmented-libraries-svr4-read") {407 m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied408 m_supports_augmented_libraries_svr4_read = eLazyBoolYes;409 } else if (x == "qXfer:libraries:read+")410 m_supports_qXfer_libraries_read = eLazyBoolYes;411 else if (x == "qXfer:features:read+")412 m_supports_qXfer_features_read = eLazyBoolYes;413 else if (x == "qXfer:memory-map:read+")414 m_supports_qXfer_memory_map_read = eLazyBoolYes;415 else if (x == "qXfer:siginfo:read+")416 m_supports_qXfer_siginfo_read = eLazyBoolYes;417 else if (x == "qEcho+")418 m_supports_qEcho = eLazyBoolYes;419 else if (x == "QPassSignals+")420 m_supports_QPassSignals = eLazyBoolYes;421 else if (x == "multiprocess+")422 m_supports_multiprocess = eLazyBoolYes;423 else if (x == "memory-tagging+")424 m_supports_memory_tagging = eLazyBoolYes;425 else if (x == "qSaveCore+")426 m_supports_qSaveCore = eLazyBoolYes;427 else if (x == "native-signals+")428 m_uses_native_signals = eLazyBoolYes;429 else if (x == "binary-upload+")430 m_x_packet_state = xPacketState::Prefixed;431 else if (x == "ReverseContinue+")432 m_supports_reverse_continue = eLazyBoolYes;433 else if (x == "ReverseStep+")434 m_supports_reverse_step = eLazyBoolYes;435 else if (x == "MultiMemRead+")436 m_supports_multi_mem_read = eLazyBoolYes;437 // Look for a list of compressions in the features list e.g.438 // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-439 // deflate,lzma440 else if (x.consume_front("SupportedCompressions=")) {441 llvm::SmallVector<llvm::StringRef, 4> compressions;442 x.split(compressions, ',');443 if (!compressions.empty())444 MaybeEnableCompression(compressions);445 } else if (x.consume_front("SupportedWatchpointTypes=")) {446 llvm::SmallVector<llvm::StringRef, 4> watchpoint_types;447 x.split(watchpoint_types, ',');448 m_watchpoint_types = eWatchpointHardwareFeatureUnknown;449 for (auto wp_type : watchpoint_types) {450 if (wp_type == "x86_64")451 m_watchpoint_types |= eWatchpointHardwareX86;452 if (wp_type == "aarch64-mask")453 m_watchpoint_types |= eWatchpointHardwareArmMASK;454 if (wp_type == "aarch64-bas")455 m_watchpoint_types |= eWatchpointHardwareArmBAS;456 }457 } else if (x.consume_front("PacketSize=")) {458 StringExtractorGDBRemote packet_response(x);459 m_max_packet_size =460 packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);461 if (m_max_packet_size == 0) {462 m_max_packet_size = UINT64_MAX; // Must have been a garbled response463 Log *log(GetLog(GDBRLog::Process));464 LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");465 }466 }467 }468 }469}470 471bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {472 if (m_supports_thread_suffix == eLazyBoolCalculate) {473 StringExtractorGDBRemote response;474 m_supports_thread_suffix = eLazyBoolNo;475 if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==476 PacketResult::Success) {477 if (response.IsOKResponse())478 m_supports_thread_suffix = eLazyBoolYes;479 }480 }481 return m_supports_thread_suffix;482}483bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {484 if (m_supports_vCont_c == eLazyBoolCalculate) {485 StringExtractorGDBRemote response;486 m_supports_vCont_any = eLazyBoolNo;487 m_supports_vCont_all = eLazyBoolNo;488 m_supports_vCont_c = eLazyBoolNo;489 m_supports_vCont_C = eLazyBoolNo;490 m_supports_vCont_s = eLazyBoolNo;491 m_supports_vCont_S = eLazyBoolNo;492 if (SendPacketAndWaitForResponse("vCont?", response) ==493 PacketResult::Success) {494 const char *response_cstr = response.GetStringRef().data();495 if (::strstr(response_cstr, ";c"))496 m_supports_vCont_c = eLazyBoolYes;497 498 if (::strstr(response_cstr, ";C"))499 m_supports_vCont_C = eLazyBoolYes;500 501 if (::strstr(response_cstr, ";s"))502 m_supports_vCont_s = eLazyBoolYes;503 504 if (::strstr(response_cstr, ";S"))505 m_supports_vCont_S = eLazyBoolYes;506 507 if (m_supports_vCont_c == eLazyBoolYes &&508 m_supports_vCont_C == eLazyBoolYes &&509 m_supports_vCont_s == eLazyBoolYes &&510 m_supports_vCont_S == eLazyBoolYes) {511 m_supports_vCont_all = eLazyBoolYes;512 }513 514 if (m_supports_vCont_c == eLazyBoolYes ||515 m_supports_vCont_C == eLazyBoolYes ||516 m_supports_vCont_s == eLazyBoolYes ||517 m_supports_vCont_S == eLazyBoolYes) {518 m_supports_vCont_any = eLazyBoolYes;519 }520 }521 }522 523 switch (flavor) {524 case 'a':525 return m_supports_vCont_any;526 case 'A':527 return m_supports_vCont_all;528 case 'c':529 return m_supports_vCont_c;530 case 'C':531 return m_supports_vCont_C;532 case 's':533 return m_supports_vCont_s;534 case 'S':535 return m_supports_vCont_S;536 default:537 break;538 }539 return false;540}541 542GDBRemoteCommunication::PacketResult543GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(544 lldb::tid_t tid, StreamString &&payload,545 StringExtractorGDBRemote &response) {546 Lock lock(*this);547 if (!lock) {548 if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets))549 LLDB_LOGF(log,550 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "551 "for %s packet.",552 __FUNCTION__, payload.GetData());553 return PacketResult::ErrorNoSequenceLock;554 }555 556 if (GetThreadSuffixSupported())557 payload.Printf(";thread:%4.4" PRIx64 ";", tid);558 else {559 if (!SetCurrentThread(tid))560 return PacketResult::ErrorSendFailed;561 }562 563 return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);564}565 566// Check if the target supports 'p' packet. It sends out a 'p' packet and567// checks the response. A normal packet will tell us that support is available.568//569// Takes a valid thread ID because p needs to apply to a thread.570bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {571 if (m_supports_p == eLazyBoolCalculate)572 m_supports_p = GetThreadPacketSupported(tid, "p0");573 return m_supports_p;574}575 576LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(577 lldb::tid_t tid, llvm::StringRef packetStr) {578 StreamString payload;579 payload.PutCString(packetStr);580 StringExtractorGDBRemote response;581 if (SendThreadSpecificPacketAndWaitForResponse(582 tid, std::move(payload), response) == PacketResult::Success &&583 response.IsNormalResponse()) {584 return eLazyBoolYes;585 }586 return eLazyBoolNo;587}588 589bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const {590 return m_supports_qSaveCore == eLazyBoolYes;591}592 593StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {594 // Get information on all threads at one using the "jThreadsInfo" packet595 StructuredData::ObjectSP object_sp;596 597 if (m_supports_jThreadsInfo) {598 StringExtractorGDBRemote response;599 response.SetResponseValidatorToJSON();600 if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==601 PacketResult::Success) {602 if (response.IsUnsupportedResponse()) {603 m_supports_jThreadsInfo = false;604 } else if (!response.Empty()) {605 object_sp = StructuredData::ParseJSON(response.GetStringRef());606 }607 }608 }609 return object_sp;610}611 612bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {613 if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {614 StringExtractorGDBRemote response;615 m_supports_jThreadExtendedInfo = eLazyBoolNo;616 if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==617 PacketResult::Success) {618 if (response.IsOKResponse()) {619 m_supports_jThreadExtendedInfo = eLazyBoolYes;620 }621 }622 }623 return m_supports_jThreadExtendedInfo;624}625 626void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {627 if (m_supports_error_string_reply == eLazyBoolCalculate) {628 StringExtractorGDBRemote response;629 // We try to enable error strings in remote packets but if we fail, we just630 // work in the older way.631 m_supports_error_string_reply = eLazyBoolNo;632 if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==633 PacketResult::Success) {634 if (response.IsOKResponse()) {635 m_supports_error_string_reply = eLazyBoolYes;636 }637 }638 }639}640 641bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {642 if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {643 StringExtractorGDBRemote response;644 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;645 if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",646 response) == PacketResult::Success) {647 if (response.IsOKResponse()) {648 m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;649 }650 }651 }652 return m_supports_jLoadedDynamicLibrariesInfos;653}654 655bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {656 if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {657 StringExtractorGDBRemote response;658 m_supports_jGetSharedCacheInfo = eLazyBoolNo;659 if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==660 PacketResult::Success) {661 if (response.IsOKResponse()) {662 m_supports_jGetSharedCacheInfo = eLazyBoolYes;663 }664 }665 }666 return m_supports_jGetSharedCacheInfo;667}668 669bool GDBRemoteCommunicationClient::GetDynamicLoaderProcessStateSupported() {670 if (m_supports_jGetDyldProcessState == eLazyBoolCalculate) {671 StringExtractorGDBRemote response;672 m_supports_jGetDyldProcessState = eLazyBoolNo;673 if (SendPacketAndWaitForResponse("jGetDyldProcessState", response) ==674 PacketResult::Success) {675 if (!response.IsUnsupportedResponse())676 m_supports_jGetDyldProcessState = eLazyBoolYes;677 }678 }679 return m_supports_jGetDyldProcessState;680}681 682bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {683 if (m_supports_memory_tagging == eLazyBoolCalculate) {684 GetRemoteQSupported();685 }686 return m_supports_memory_tagging == eLazyBoolYes;687}688 689DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,690 size_t len,691 int32_t type) {692 StreamString packet;693 packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);694 StringExtractorGDBRemote response;695 696 Log *log = GetLog(GDBRLog::Memory);697 698 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=699 PacketResult::Success ||700 !response.IsNormalResponse()) {701 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",702 __FUNCTION__);703 return nullptr;704 }705 706 // We are expecting707 // m<hex encoded bytes>708 709 if (response.GetChar() != 'm') {710 LLDB_LOGF(log,711 "GDBRemoteCommunicationClient::%s: qMemTags response did not "712 "begin with \"m\"",713 __FUNCTION__);714 return nullptr;715 }716 717 size_t expected_bytes = response.GetBytesLeft() / 2;718 WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));719 size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());720 // Check both because in some situations chars are consumed even721 // if the decoding fails.722 if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {723 LLDB_LOGF(724 log,725 "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",726 __FUNCTION__);727 return nullptr;728 }729 730 return buffer_sp;731}732 733Status GDBRemoteCommunicationClient::WriteMemoryTags(734 lldb::addr_t addr, size_t len, int32_t type,735 const std::vector<uint8_t> &tags) {736 // Format QMemTags:address,length:type:tags737 StreamString packet;738 packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);739 packet.PutBytesAsRawHex8(tags.data(), tags.size());740 741 Status status;742 StringExtractorGDBRemote response;743 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=744 PacketResult::Success ||745 !response.IsOKResponse()) {746 status = Status::FromErrorString("QMemTags packet failed");747 }748 return status;749}750 751GDBRemoteCommunicationClient::xPacketState752GDBRemoteCommunicationClient::GetxPacketState() {753 if (!m_x_packet_state)754 GetRemoteQSupported();755 if (!m_x_packet_state) {756 StringExtractorGDBRemote response;757 m_x_packet_state = xPacketState::Unimplemented;758 if (SendPacketAndWaitForResponse("x0,0", response) ==759 PacketResult::Success) {760 if (response.IsOKResponse())761 m_x_packet_state = xPacketState::Bare;762 }763 }764 return *m_x_packet_state;765}766 767lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {768 if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)769 return m_curr_pid;770 771 // First try to retrieve the pid via the qProcessInfo request.772 GetCurrentProcessInfo(allow_lazy);773 if (m_curr_pid_is_valid == eLazyBoolYes) {774 // We really got it.775 return m_curr_pid;776 } else {777 // If we don't get a response for qProcessInfo, check if $qC gives us a778 // result. $qC only returns a real process id on older debugserver and779 // lldb-platform stubs. The gdb remote protocol documents $qC as returning780 // the thread id, which newer debugserver and lldb-gdbserver stubs return781 // correctly.782 StringExtractorGDBRemote response;783 if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) {784 if (response.GetChar() == 'Q') {785 if (response.GetChar() == 'C') {786 m_curr_pid_run = m_curr_pid =787 response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);788 if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {789 m_curr_pid_is_valid = eLazyBoolYes;790 return m_curr_pid;791 }792 }793 }794 }795 796 // If we don't get a response for $qC, check if $qfThreadID gives us a797 // result.798 if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {799 bool sequence_mutex_unavailable;800 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);801 if (!ids.empty() && !sequence_mutex_unavailable) {802 // If server returned an explicit PID, use that.803 m_curr_pid_run = m_curr_pid = ids.front().first;804 // Otherwise, use the TID of the first thread (Linux hack).805 if (m_curr_pid == LLDB_INVALID_PROCESS_ID)806 m_curr_pid_run = m_curr_pid = ids.front().second;807 m_curr_pid_is_valid = eLazyBoolYes;808 return m_curr_pid;809 }810 }811 }812 813 return LLDB_INVALID_PROCESS_ID;814}815 816llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) {817 if (!args.GetArgumentAtIndex(0))818 return llvm::createStringError(llvm::inconvertibleErrorCode(),819 "Nothing to launch");820 // try vRun first821 if (m_supports_vRun) {822 StreamString packet;823 packet.PutCString("vRun");824 for (const Args::ArgEntry &arg : args) {825 packet.PutChar(';');826 packet.PutStringAsRawHex8(arg.ref());827 }828 829 StringExtractorGDBRemote response;830 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=831 PacketResult::Success)832 return llvm::createStringError(llvm::inconvertibleErrorCode(),833 "Sending vRun packet failed");834 835 if (response.IsErrorResponse())836 return response.GetStatus().ToError();837 838 // vRun replies with a stop reason packet839 // FIXME: right now we just discard the packet and LLDB queries840 // for stop reason again841 if (!response.IsUnsupportedResponse())842 return llvm::Error::success();843 844 m_supports_vRun = false;845 }846 847 // fallback to A848 StreamString packet;849 packet.PutChar('A');850 llvm::ListSeparator LS(",");851 for (const auto &arg : llvm::enumerate(args)) {852 packet << LS;853 packet.Format("{0},{1},", arg.value().ref().size() * 2, arg.index());854 packet.PutStringAsRawHex8(arg.value().ref());855 }856 857 StringExtractorGDBRemote response;858 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=859 PacketResult::Success) {860 return llvm::createStringError(llvm::inconvertibleErrorCode(),861 "Sending A packet failed");862 }863 if (!response.IsOKResponse())864 return response.GetStatus().ToError();865 866 if (SendPacketAndWaitForResponse("qLaunchSuccess", response) !=867 PacketResult::Success) {868 return llvm::createStringError(llvm::inconvertibleErrorCode(),869 "Sending qLaunchSuccess packet failed");870 }871 if (response.IsOKResponse())872 return llvm::Error::success();873 if (response.GetChar() == 'E') {874 return llvm::createStringError(llvm::inconvertibleErrorCode(),875 response.GetStringRef().substr(1));876 }877 return llvm::createStringError(llvm::inconvertibleErrorCode(),878 "unknown error occurred launching process");879}880 881int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {882 llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec;883 for (const auto &kv : env)884 vec.emplace_back(kv.first(), kv.second);885 llvm::sort(vec, llvm::less_first());886 for (const auto &[k, v] : vec) {887 int r = SendEnvironmentPacket((k + "=" + v).str().c_str());888 if (r != 0)889 return r;890 }891 return 0;892}893 894int GDBRemoteCommunicationClient::SendEnvironmentPacket(895 char const *name_equal_value) {896 if (name_equal_value && name_equal_value[0]) {897 bool send_hex_encoding = false;898 for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;899 ++p) {900 if (llvm::isPrint(*p)) {901 switch (*p) {902 case '$':903 case '#':904 case '*':905 case '}':906 send_hex_encoding = true;907 break;908 default:909 break;910 }911 } else {912 // We have non printable characters, lets hex encode this...913 send_hex_encoding = true;914 }915 }916 917 StringExtractorGDBRemote response;918 // Prefer sending unencoded, if possible and the server supports it.919 if (!send_hex_encoding && m_supports_QEnvironment) {920 StreamString packet;921 packet.Printf("QEnvironment:%s", name_equal_value);922 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=923 PacketResult::Success)924 return -1;925 926 if (response.IsOKResponse())927 return 0;928 if (response.IsUnsupportedResponse())929 m_supports_QEnvironment = false;930 else {931 uint8_t error = response.GetError();932 if (error)933 return error;934 return -1;935 }936 }937 938 if (m_supports_QEnvironmentHexEncoded) {939 StreamString packet;940 packet.PutCString("QEnvironmentHexEncoded:");941 packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));942 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=943 PacketResult::Success)944 return -1;945 946 if (response.IsOKResponse())947 return 0;948 if (response.IsUnsupportedResponse())949 m_supports_QEnvironmentHexEncoded = false;950 else {951 uint8_t error = response.GetError();952 if (error)953 return error;954 return -1;955 }956 }957 }958 return -1;959}960 961int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {962 if (arch && arch[0]) {963 StreamString packet;964 packet.Printf("QLaunchArch:%s", arch);965 StringExtractorGDBRemote response;966 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==967 PacketResult::Success) {968 if (response.IsOKResponse())969 return 0;970 uint8_t error = response.GetError();971 if (error)972 return error;973 }974 }975 return -1;976}977 978int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(979 char const *data, bool *was_supported) {980 if (data && *data != '\0') {981 StreamString packet;982 packet.Printf("QSetProcessEvent:%s", data);983 StringExtractorGDBRemote response;984 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==985 PacketResult::Success) {986 if (response.IsOKResponse()) {987 if (was_supported)988 *was_supported = true;989 return 0;990 } else if (response.IsUnsupportedResponse()) {991 if (was_supported)992 *was_supported = false;993 return -1;994 } else {995 uint8_t error = response.GetError();996 if (was_supported)997 *was_supported = true;998 if (error)999 return error;1000 }1001 }1002 }1003 return -1;1004}1005 1006llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {1007 GetHostInfo();1008 return m_os_version;1009}1010 1011llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {1012 GetHostInfo();1013 return m_maccatalyst_version;1014}1015 1016std::optional<std::string> GDBRemoteCommunicationClient::GetOSBuildString() {1017 if (GetHostInfo()) {1018 if (!m_os_build.empty())1019 return m_os_build;1020 }1021 return std::nullopt;1022}1023 1024std::optional<std::string>1025GDBRemoteCommunicationClient::GetOSKernelDescription() {1026 if (GetHostInfo()) {1027 if (!m_os_kernel.empty())1028 return m_os_kernel;1029 }1030 return std::nullopt;1031}1032 1033bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {1034 if (GetHostInfo()) {1035 if (!m_hostname.empty()) {1036 s = m_hostname;1037 return true;1038 }1039 }1040 s.clear();1041 return false;1042}1043 1044ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {1045 if (GetHostInfo())1046 return m_host_arch;1047 return ArchSpec();1048}1049 1050const lldb_private::ArchSpec &1051GDBRemoteCommunicationClient::GetProcessArchitecture() {1052 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)1053 GetCurrentProcessInfo();1054 return m_process_arch;1055}1056 1057bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(1058 UUID &uuid, addr_t &value, bool &value_is_offset) {1059 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)1060 GetCurrentProcessInfo();1061 1062 // Return true if we have a UUID or an address/offset of the1063 // main standalone / firmware binary being used.1064 if (!m_process_standalone_uuid.IsValid() &&1065 m_process_standalone_value == LLDB_INVALID_ADDRESS)1066 return false;1067 1068 uuid = m_process_standalone_uuid;1069 value = m_process_standalone_value;1070 value_is_offset = m_process_standalone_value_is_offset;1071 return true;1072}1073 1074std::vector<addr_t>1075GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {1076 if (m_qProcessInfo_is_valid == eLazyBoolCalculate)1077 GetCurrentProcessInfo();1078 return m_binary_addresses;1079}1080 1081bool GDBRemoteCommunicationClient::GetGDBServerVersion() {1082 if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {1083 m_gdb_server_name.clear();1084 m_gdb_server_version = 0;1085 m_qGDBServerVersion_is_valid = eLazyBoolNo;1086 1087 StringExtractorGDBRemote response;1088 if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==1089 PacketResult::Success) {1090 if (response.IsNormalResponse()) {1091 llvm::StringRef name, value;1092 bool success = false;1093 while (response.GetNameColonValue(name, value)) {1094 if (name == "name") {1095 success = true;1096 m_gdb_server_name = std::string(value);1097 } else if (name == "version") {1098 llvm::StringRef major, minor;1099 std::tie(major, minor) = value.split('.');1100 if (!major.getAsInteger(0, m_gdb_server_version))1101 success = true;1102 }1103 }1104 if (success)1105 m_qGDBServerVersion_is_valid = eLazyBoolYes;1106 }1107 }1108 }1109 return m_qGDBServerVersion_is_valid == eLazyBoolYes;1110}1111 1112void GDBRemoteCommunicationClient::MaybeEnableCompression(1113 llvm::ArrayRef<llvm::StringRef> supported_compressions) {1114 CompressionType avail_type = CompressionType::None;1115 llvm::StringRef avail_name;1116 1117#if HAVE_LIBCOMPRESSION1118 if (avail_type == CompressionType::None) {1119 for (auto compression : supported_compressions) {1120 if (compression == "lzfse") {1121 avail_type = CompressionType::LZFSE;1122 avail_name = compression;1123 break;1124 }1125 }1126 }1127 if (avail_type == CompressionType::None) {1128 for (auto compression : supported_compressions) {1129 if (compression == "zlib-deflate") {1130 avail_type = CompressionType::ZlibDeflate;1131 avail_name = compression;1132 break;1133 }1134 }1135 }1136#endif1137 1138#if LLVM_ENABLE_ZLIB1139 if (avail_type == CompressionType::None) {1140 for (auto compression : supported_compressions) {1141 if (compression == "zlib-deflate") {1142 avail_type = CompressionType::ZlibDeflate;1143 avail_name = compression;1144 break;1145 }1146 }1147 }1148#endif1149 1150#if HAVE_LIBCOMPRESSION1151 if (avail_type == CompressionType::None) {1152 for (auto compression : supported_compressions) {1153 if (compression == "lz4") {1154 avail_type = CompressionType::LZ4;1155 avail_name = compression;1156 break;1157 }1158 }1159 }1160 if (avail_type == CompressionType::None) {1161 for (auto compression : supported_compressions) {1162 if (compression == "lzma") {1163 avail_type = CompressionType::LZMA;1164 avail_name = compression;1165 break;1166 }1167 }1168 }1169#endif1170 1171 if (avail_type != CompressionType::None) {1172 StringExtractorGDBRemote response;1173 std::string packet = "QEnableCompression:type:" + avail_name.str() + ";";1174 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)1175 return;1176 1177 if (response.IsOKResponse()) {1178 m_compression_type = avail_type;1179 }1180 }1181}1182 1183const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {1184 if (GetGDBServerVersion()) {1185 if (!m_gdb_server_name.empty())1186 return m_gdb_server_name.c_str();1187 }1188 return nullptr;1189}1190 1191uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {1192 if (GetGDBServerVersion())1193 return m_gdb_server_version;1194 return 0;1195}1196 1197bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {1198 StringExtractorGDBRemote response;1199 if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success)1200 return false;1201 1202 if (!response.IsNormalResponse())1203 return false;1204 1205 if (response.GetChar() == 'Q' && response.GetChar() == 'C') {1206 auto pid_tid = response.GetPidTid(0);1207 if (!pid_tid)1208 return false;1209 1210 lldb::pid_t pid = pid_tid->first;1211 // invalid1212 if (pid == StringExtractorGDBRemote::AllProcesses)1213 return false;1214 1215 // if we get pid as well, update m_curr_pid1216 if (pid != 0) {1217 m_curr_pid_run = m_curr_pid = pid;1218 m_curr_pid_is_valid = eLazyBoolYes;1219 }1220 tid = pid_tid->second;1221 }1222 1223 return true;1224}1225 1226static void ParseOSType(llvm::StringRef value, std::string &os_name,1227 std::string &environment) {1228 if (value == "iossimulator" || value == "tvossimulator" ||1229 value == "watchossimulator" || value == "xrossimulator" ||1230 value == "visionossimulator") {1231 environment = "simulator";1232 os_name = value.drop_back(environment.size()).str();1233 } else if (value == "maccatalyst") {1234 os_name = "ios";1235 environment = "macabi";1236 } else {1237 os_name = value.str();1238 }1239}1240 1241bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {1242 Log *log = GetLog(GDBRLog::Process);1243 1244 if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {1245 // host info computation can require DNS traffic and shelling out to external processes.1246 // Increase the timeout to account for that.1247 ScopedTimeout timeout(*this, seconds(10));1248 m_qHostInfo_is_valid = eLazyBoolNo;1249 StringExtractorGDBRemote response;1250 if (SendPacketAndWaitForResponse("qHostInfo", response) ==1251 PacketResult::Success) {1252 if (response.IsNormalResponse()) {1253 llvm::StringRef name;1254 llvm::StringRef value;1255 uint32_t cpu = LLDB_INVALID_CPUTYPE;1256 uint32_t sub = 0;1257 std::string arch_name;1258 std::string os_name;1259 std::string environment;1260 std::string vendor_name;1261 std::string triple;1262 uint32_t pointer_byte_size = 0;1263 ByteOrder byte_order = eByteOrderInvalid;1264 uint32_t num_keys_decoded = 0;1265 while (response.GetNameColonValue(name, value)) {1266 if (name == "cputype") {1267 // exception type in big endian hex1268 if (!value.getAsInteger(0, cpu))1269 ++num_keys_decoded;1270 } else if (name == "cpusubtype") {1271 // exception count in big endian hex1272 if (!value.getAsInteger(0, sub))1273 ++num_keys_decoded;1274 } else if (name == "arch") {1275 arch_name = std::string(value);1276 ++num_keys_decoded;1277 } else if (name == "triple") {1278 StringExtractor extractor(value);1279 extractor.GetHexByteString(triple);1280 ++num_keys_decoded;1281 } else if (name == "distribution_id") {1282 StringExtractor extractor(value);1283 extractor.GetHexByteString(m_host_distribution_id);1284 ++num_keys_decoded;1285 } else if (name == "os_build") {1286 StringExtractor extractor(value);1287 extractor.GetHexByteString(m_os_build);1288 ++num_keys_decoded;1289 } else if (name == "hostname") {1290 StringExtractor extractor(value);1291 extractor.GetHexByteString(m_hostname);1292 ++num_keys_decoded;1293 } else if (name == "os_kernel") {1294 StringExtractor extractor(value);1295 extractor.GetHexByteString(m_os_kernel);1296 ++num_keys_decoded;1297 } else if (name == "ostype") {1298 ParseOSType(value, os_name, environment);1299 ++num_keys_decoded;1300 } else if (name == "vendor") {1301 vendor_name = std::string(value);1302 ++num_keys_decoded;1303 } else if (name == "endian") {1304 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)1305 .Case("little", eByteOrderLittle)1306 .Case("big", eByteOrderBig)1307 .Case("pdp", eByteOrderPDP)1308 .Default(eByteOrderInvalid);1309 if (byte_order != eByteOrderInvalid)1310 ++num_keys_decoded;1311 } else if (name == "ptrsize") {1312 if (!value.getAsInteger(0, pointer_byte_size))1313 ++num_keys_decoded;1314 } else if (name == "addressing_bits") {1315 if (!value.getAsInteger(0, m_low_mem_addressing_bits)) {1316 ++num_keys_decoded;1317 }1318 } else if (name == "high_mem_addressing_bits") {1319 if (!value.getAsInteger(0, m_high_mem_addressing_bits))1320 ++num_keys_decoded;1321 } else if (name == "low_mem_addressing_bits") {1322 if (!value.getAsInteger(0, m_low_mem_addressing_bits))1323 ++num_keys_decoded;1324 } else if (name == "os_version" ||1325 name == "version") // Older debugserver binaries used1326 // the "version" key instead of1327 // "os_version"...1328 {1329 if (!m_os_version.tryParse(value))1330 ++num_keys_decoded;1331 } else if (name == "maccatalyst_version") {1332 if (!m_maccatalyst_version.tryParse(value))1333 ++num_keys_decoded;1334 } else if (name == "watchpoint_exceptions_received") {1335 m_watchpoints_trigger_after_instruction =1336 llvm::StringSwitch<LazyBool>(value)1337 .Case("before", eLazyBoolNo)1338 .Case("after", eLazyBoolYes)1339 .Default(eLazyBoolCalculate);1340 if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)1341 ++num_keys_decoded;1342 } else if (name == "default_packet_timeout") {1343 uint32_t timeout_seconds;1344 if (!value.getAsInteger(0, timeout_seconds)) {1345 m_default_packet_timeout = seconds(timeout_seconds);1346 SetPacketTimeout(m_default_packet_timeout);1347 ++num_keys_decoded;1348 }1349 } else if (name == "vm-page-size") {1350 int page_size;1351 if (!value.getAsInteger(0, page_size)) {1352 m_target_vm_page_size = page_size;1353 ++num_keys_decoded;1354 }1355 }1356 }1357 1358 if (num_keys_decoded > 0)1359 m_qHostInfo_is_valid = eLazyBoolYes;1360 1361 if (triple.empty()) {1362 if (arch_name.empty()) {1363 if (cpu != LLDB_INVALID_CPUTYPE) {1364 m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);1365 if (pointer_byte_size) {1366 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());1367 }1368 if (byte_order != eByteOrderInvalid) {1369 assert(byte_order == m_host_arch.GetByteOrder());1370 }1371 1372 if (!vendor_name.empty())1373 m_host_arch.GetTriple().setVendorName(1374 llvm::StringRef(vendor_name));1375 if (!os_name.empty())1376 m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));1377 if (!environment.empty())1378 m_host_arch.GetTriple().setEnvironmentName(environment);1379 }1380 } else {1381 std::string triple;1382 triple += arch_name;1383 if (!vendor_name.empty() || !os_name.empty()) {1384 triple += '-';1385 if (vendor_name.empty())1386 triple += "unknown";1387 else1388 triple += vendor_name;1389 triple += '-';1390 if (os_name.empty())1391 triple += "unknown";1392 else1393 triple += os_name;1394 }1395 m_host_arch.SetTriple(triple.c_str());1396 1397 llvm::Triple &host_triple = m_host_arch.GetTriple();1398 if (host_triple.getVendor() == llvm::Triple::Apple &&1399 host_triple.getOS() == llvm::Triple::Darwin) {1400 switch (m_host_arch.GetMachine()) {1401 case llvm::Triple::aarch64:1402 case llvm::Triple::aarch64_32:1403 case llvm::Triple::arm:1404 case llvm::Triple::thumb:1405 host_triple.setOS(llvm::Triple::IOS);1406 break;1407 default:1408 host_triple.setOS(llvm::Triple::MacOSX);1409 break;1410 }1411 }1412 if (pointer_byte_size) {1413 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());1414 }1415 if (byte_order != eByteOrderInvalid) {1416 assert(byte_order == m_host_arch.GetByteOrder());1417 }1418 }1419 } else {1420 m_host_arch.SetTriple(triple.c_str());1421 if (pointer_byte_size) {1422 assert(pointer_byte_size == m_host_arch.GetAddressByteSize());1423 }1424 if (byte_order != eByteOrderInvalid) {1425 assert(byte_order == m_host_arch.GetByteOrder());1426 }1427 1428 LLDB_LOGF(log,1429 "GDBRemoteCommunicationClient::%s parsed host "1430 "architecture as %s, triple as %s from triple text %s",1431 __FUNCTION__,1432 m_host_arch.GetArchitectureName()1433 ? m_host_arch.GetArchitectureName()1434 : "<null-arch-name>",1435 m_host_arch.GetTriple().getTriple().c_str(),1436 triple.c_str());1437 }1438 }1439 }1440 }1441 return m_qHostInfo_is_valid == eLazyBoolYes;1442}1443 1444int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,1445 size_t data_len) {1446 StreamString packet;1447 packet.PutCString("I");1448 packet.PutBytesAsRawHex8(data, data_len);1449 StringExtractorGDBRemote response;1450 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1451 PacketResult::Success) {1452 return 0;1453 }1454 return response.GetError();1455}1456 1457const lldb_private::ArchSpec &1458GDBRemoteCommunicationClient::GetHostArchitecture() {1459 if (m_qHostInfo_is_valid == eLazyBoolCalculate)1460 GetHostInfo();1461 return m_host_arch;1462}1463 1464AddressableBits GDBRemoteCommunicationClient::GetAddressableBits() {1465 AddressableBits addressable_bits;1466 if (m_qHostInfo_is_valid == eLazyBoolCalculate)1467 GetHostInfo();1468 1469 if (m_low_mem_addressing_bits == m_high_mem_addressing_bits)1470 addressable_bits.SetAddressableBits(m_low_mem_addressing_bits);1471 else1472 addressable_bits.SetAddressableBits(m_low_mem_addressing_bits,1473 m_high_mem_addressing_bits);1474 return addressable_bits;1475}1476 1477seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {1478 if (m_qHostInfo_is_valid == eLazyBoolCalculate)1479 GetHostInfo();1480 return m_default_packet_timeout;1481}1482 1483addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,1484 uint32_t permissions) {1485 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {1486 m_supports_alloc_dealloc_memory = eLazyBoolYes;1487 char packet[64];1488 const int packet_len = ::snprintf(1489 packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,1490 permissions & lldb::ePermissionsReadable ? "r" : "",1491 permissions & lldb::ePermissionsWritable ? "w" : "",1492 permissions & lldb::ePermissionsExecutable ? "x" : "");1493 assert(packet_len < (int)sizeof(packet));1494 UNUSED_IF_ASSERT_DISABLED(packet_len);1495 StringExtractorGDBRemote response;1496 if (SendPacketAndWaitForResponse(packet, response) ==1497 PacketResult::Success) {1498 if (response.IsUnsupportedResponse())1499 m_supports_alloc_dealloc_memory = eLazyBoolNo;1500 else if (!response.IsErrorResponse())1501 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);1502 } else {1503 m_supports_alloc_dealloc_memory = eLazyBoolNo;1504 }1505 }1506 return LLDB_INVALID_ADDRESS;1507}1508 1509bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {1510 if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {1511 m_supports_alloc_dealloc_memory = eLazyBoolYes;1512 char packet[64];1513 const int packet_len =1514 ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);1515 assert(packet_len < (int)sizeof(packet));1516 UNUSED_IF_ASSERT_DISABLED(packet_len);1517 StringExtractorGDBRemote response;1518 if (SendPacketAndWaitForResponse(packet, response) ==1519 PacketResult::Success) {1520 if (response.IsUnsupportedResponse())1521 m_supports_alloc_dealloc_memory = eLazyBoolNo;1522 else if (response.IsOKResponse())1523 return true;1524 } else {1525 m_supports_alloc_dealloc_memory = eLazyBoolNo;1526 }1527 }1528 return false;1529}1530 1531Status GDBRemoteCommunicationClient::Detach(bool keep_stopped,1532 lldb::pid_t pid) {1533 Status error;1534 lldb_private::StreamString packet;1535 1536 packet.PutChar('D');1537 if (keep_stopped) {1538 if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {1539 char packet[64];1540 const int packet_len =1541 ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");1542 assert(packet_len < (int)sizeof(packet));1543 UNUSED_IF_ASSERT_DISABLED(packet_len);1544 StringExtractorGDBRemote response;1545 if (SendPacketAndWaitForResponse(packet, response) ==1546 PacketResult::Success &&1547 response.IsOKResponse()) {1548 m_supports_detach_stay_stopped = eLazyBoolYes;1549 } else {1550 m_supports_detach_stay_stopped = eLazyBoolNo;1551 }1552 }1553 1554 if (m_supports_detach_stay_stopped == eLazyBoolNo) {1555 error = Status::FromErrorString(1556 "Stays stopped not supported by this target.");1557 return error;1558 } else {1559 packet.PutChar('1');1560 }1561 }1562 1563 if (GetMultiprocessSupported()) {1564 // Some servers (e.g. qemu) require specifying the PID even if only a single1565 // process is running.1566 if (pid == LLDB_INVALID_PROCESS_ID)1567 pid = GetCurrentProcessID();1568 packet.PutChar(';');1569 packet.PutHex64(pid);1570 } else if (pid != LLDB_INVALID_PROCESS_ID) {1571 error = Status::FromErrorString(1572 "Multiprocess extension not supported by the server.");1573 return error;1574 }1575 1576 StringExtractorGDBRemote response;1577 PacketResult packet_result =1578 SendPacketAndWaitForResponse(packet.GetString(), response);1579 if (packet_result != PacketResult::Success)1580 error = Status::FromErrorString("Sending disconnect packet failed.");1581 return error;1582}1583 1584Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(1585 lldb::addr_t addr, lldb_private::MemoryRegionInfo ®ion_info) {1586 Status error;1587 region_info.Clear();1588 1589 if (m_supports_memory_region_info != eLazyBoolNo) {1590 m_supports_memory_region_info = eLazyBoolYes;1591 char packet[64];1592 const int packet_len = ::snprintf(1593 packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);1594 assert(packet_len < (int)sizeof(packet));1595 UNUSED_IF_ASSERT_DISABLED(packet_len);1596 StringExtractorGDBRemote response;1597 if (SendPacketAndWaitForResponse(packet, response) ==1598 PacketResult::Success &&1599 response.GetResponseType() == StringExtractorGDBRemote::eResponse) {1600 llvm::StringRef name;1601 llvm::StringRef value;1602 addr_t addr_value = LLDB_INVALID_ADDRESS;1603 bool success = true;1604 bool saw_permissions = false;1605 while (success && response.GetNameColonValue(name, value)) {1606 if (name == "start") {1607 if (!value.getAsInteger(16, addr_value))1608 region_info.GetRange().SetRangeBase(addr_value);1609 } else if (name == "size") {1610 if (!value.getAsInteger(16, addr_value)) {1611 region_info.GetRange().SetByteSize(addr_value);1612 if (region_info.GetRange().GetRangeEnd() <1613 region_info.GetRange().GetRangeBase()) {1614 // Range size overflowed, truncate it.1615 region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);1616 }1617 }1618 } else if (name == "permissions" && region_info.GetRange().IsValid()) {1619 saw_permissions = true;1620 if (region_info.GetRange().Contains(addr)) {1621 if (value.contains('r'))1622 region_info.SetReadable(MemoryRegionInfo::eYes);1623 else1624 region_info.SetReadable(MemoryRegionInfo::eNo);1625 1626 if (value.contains('w'))1627 region_info.SetWritable(MemoryRegionInfo::eYes);1628 else1629 region_info.SetWritable(MemoryRegionInfo::eNo);1630 1631 if (value.contains('x'))1632 region_info.SetExecutable(MemoryRegionInfo::eYes);1633 else1634 region_info.SetExecutable(MemoryRegionInfo::eNo);1635 1636 region_info.SetMapped(MemoryRegionInfo::eYes);1637 } else {1638 // The reported region does not contain this address -- we're1639 // looking at an unmapped page1640 region_info.SetReadable(MemoryRegionInfo::eNo);1641 region_info.SetWritable(MemoryRegionInfo::eNo);1642 region_info.SetExecutable(MemoryRegionInfo::eNo);1643 region_info.SetMapped(MemoryRegionInfo::eNo);1644 }1645 } else if (name == "name") {1646 StringExtractorGDBRemote name_extractor(value);1647 std::string name;1648 name_extractor.GetHexByteString(name);1649 region_info.SetName(name.c_str());1650 } else if (name == "flags") {1651 region_info.SetMemoryTagged(MemoryRegionInfo::eNo);1652 region_info.SetIsShadowStack(MemoryRegionInfo::eNo);1653 1654 llvm::StringRef flags = value;1655 llvm::StringRef flag;1656 while (flags.size()) {1657 flags = flags.ltrim();1658 std::tie(flag, flags) = flags.split(' ');1659 // To account for trailing whitespace1660 if (flag.size()) {1661 if (flag == "mt")1662 region_info.SetMemoryTagged(MemoryRegionInfo::eYes);1663 else if (flag == "ss")1664 region_info.SetIsShadowStack(MemoryRegionInfo::eYes);1665 }1666 }1667 } else if (name == "type") {1668 for (llvm::StringRef entry : llvm::split(value, ',')) {1669 if (entry == "stack")1670 region_info.SetIsStackMemory(MemoryRegionInfo::eYes);1671 else if (entry == "heap")1672 region_info.SetIsStackMemory(MemoryRegionInfo::eNo);1673 }1674 } else if (name == "error") {1675 StringExtractorGDBRemote error_extractor(value);1676 std::string error_string;1677 // Now convert the HEX bytes into a string value1678 error_extractor.GetHexByteString(error_string);1679 error = Status::FromErrorString(error_string.c_str());1680 } else if (name == "dirty-pages") {1681 std::vector<addr_t> dirty_page_list;1682 for (llvm::StringRef x : llvm::split(value, ',')) {1683 addr_t page;1684 x.consume_front("0x");1685 if (llvm::to_integer(x, page, 16))1686 dirty_page_list.push_back(page);1687 }1688 region_info.SetDirtyPageList(dirty_page_list);1689 }1690 }1691 1692 if (m_target_vm_page_size != 0)1693 region_info.SetPageSize(m_target_vm_page_size);1694 1695 if (region_info.GetRange().IsValid()) {1696 // We got a valid address range back but no permissions -- which means1697 // this is an unmapped page1698 if (!saw_permissions) {1699 region_info.SetReadable(MemoryRegionInfo::eNo);1700 region_info.SetWritable(MemoryRegionInfo::eNo);1701 region_info.SetExecutable(MemoryRegionInfo::eNo);1702 region_info.SetMapped(MemoryRegionInfo::eNo);1703 }1704 } else {1705 // We got an invalid address range back1706 error = Status::FromErrorString("Server returned invalid range");1707 }1708 } else {1709 m_supports_memory_region_info = eLazyBoolNo;1710 }1711 }1712 1713 if (m_supports_memory_region_info == eLazyBoolNo) {1714 error = Status::FromErrorString("qMemoryRegionInfo is not supported");1715 }1716 1717 // Try qXfer:memory-map:read to get region information not included in1718 // qMemoryRegionInfo1719 MemoryRegionInfo qXfer_region_info;1720 Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);1721 1722 if (error.Fail()) {1723 // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use1724 // the qXfer result as a fallback1725 if (qXfer_error.Success()) {1726 region_info = qXfer_region_info;1727 error.Clear();1728 } else {1729 region_info.Clear();1730 }1731 } else if (qXfer_error.Success()) {1732 // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if1733 // both regions are the same range, update the result to include the flash-1734 // memory information that is specific to the qXfer result.1735 if (region_info.GetRange() == qXfer_region_info.GetRange()) {1736 region_info.SetFlash(qXfer_region_info.GetFlash());1737 region_info.SetBlocksize(qXfer_region_info.GetBlocksize());1738 }1739 }1740 return error;1741}1742 1743Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(1744 lldb::addr_t addr, MemoryRegionInfo ®ion) {1745 Status error = LoadQXferMemoryMap();1746 if (!error.Success())1747 return error;1748 for (const auto &map_region : m_qXfer_memory_map) {1749 if (map_region.GetRange().Contains(addr)) {1750 region = map_region;1751 return error;1752 }1753 }1754 error = Status::FromErrorString("Region not found");1755 return error;1756}1757 1758Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {1759 1760 Status error;1761 1762 if (m_qXfer_memory_map_loaded)1763 // Already loaded, return success1764 return error;1765 1766 if (!XMLDocument::XMLEnabled()) {1767 error = Status::FromErrorString("XML is not supported");1768 return error;1769 }1770 1771 if (!GetQXferMemoryMapReadSupported()) {1772 error = Status::FromErrorString("Memory map is not supported");1773 return error;1774 }1775 1776 llvm::Expected<std::string> xml = ReadExtFeature("memory-map", "");1777 if (!xml)1778 return Status::FromError(xml.takeError());1779 1780 XMLDocument xml_document;1781 1782 if (!xml_document.ParseMemory(xml->c_str(), xml->size())) {1783 error = Status::FromErrorString("Failed to parse memory map xml");1784 return error;1785 }1786 1787 XMLNode map_node = xml_document.GetRootElement("memory-map");1788 if (!map_node) {1789 error = Status::FromErrorString("Invalid root node in memory map xml");1790 return error;1791 }1792 1793 m_qXfer_memory_map.clear();1794 1795 map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {1796 if (!memory_node.IsElement())1797 return true;1798 if (memory_node.GetName() != "memory")1799 return true;1800 auto type = memory_node.GetAttributeValue("type", "");1801 uint64_t start;1802 uint64_t length;1803 if (!memory_node.GetAttributeValueAsUnsigned("start", start))1804 return true;1805 if (!memory_node.GetAttributeValueAsUnsigned("length", length))1806 return true;1807 MemoryRegionInfo region;1808 region.GetRange().SetRangeBase(start);1809 region.GetRange().SetByteSize(length);1810 if (type == "rom") {1811 region.SetReadable(MemoryRegionInfo::eYes);1812 this->m_qXfer_memory_map.push_back(region);1813 } else if (type == "ram") {1814 region.SetReadable(MemoryRegionInfo::eYes);1815 region.SetWritable(MemoryRegionInfo::eYes);1816 this->m_qXfer_memory_map.push_back(region);1817 } else if (type == "flash") {1818 region.SetFlash(MemoryRegionInfo::eYes);1819 memory_node.ForEachChildElement(1820 [®ion](const XMLNode &prop_node) -> bool {1821 if (!prop_node.IsElement())1822 return true;1823 if (prop_node.GetName() != "property")1824 return true;1825 auto propname = prop_node.GetAttributeValue("name", "");1826 if (propname == "blocksize") {1827 uint64_t blocksize;1828 if (prop_node.GetElementTextAsUnsigned(blocksize))1829 region.SetBlocksize(blocksize);1830 }1831 return true;1832 });1833 this->m_qXfer_memory_map.push_back(region);1834 }1835 return true;1836 });1837 1838 m_qXfer_memory_map_loaded = true;1839 1840 return error;1841}1842 1843std::optional<uint32_t> GDBRemoteCommunicationClient::GetWatchpointSlotCount() {1844 if (m_supports_watchpoint_support_info == eLazyBoolYes) {1845 return m_num_supported_hardware_watchpoints;1846 }1847 1848 std::optional<uint32_t> num;1849 if (m_supports_watchpoint_support_info != eLazyBoolNo) {1850 StringExtractorGDBRemote response;1851 if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==1852 PacketResult::Success) {1853 m_supports_watchpoint_support_info = eLazyBoolYes;1854 llvm::StringRef name;1855 llvm::StringRef value;1856 while (response.GetNameColonValue(name, value)) {1857 if (name == "num") {1858 value.getAsInteger(0, m_num_supported_hardware_watchpoints);1859 num = m_num_supported_hardware_watchpoints;1860 }1861 }1862 if (!num) {1863 m_supports_watchpoint_support_info = eLazyBoolNo;1864 }1865 } else {1866 m_supports_watchpoint_support_info = eLazyBoolNo;1867 }1868 }1869 1870 return num;1871}1872 1873WatchpointHardwareFeature1874GDBRemoteCommunicationClient::GetSupportedWatchpointTypes() {1875 return m_watchpoint_types;1876}1877 1878std::optional<bool> GDBRemoteCommunicationClient::GetWatchpointReportedAfter() {1879 if (m_qHostInfo_is_valid == eLazyBoolCalculate)1880 GetHostInfo();1881 1882 // Process determines this by target CPU, but allow for the1883 // remote stub to override it via the qHostInfo1884 // watchpoint_exceptions_received key, if it is present.1885 if (m_qHostInfo_is_valid == eLazyBoolYes) {1886 if (m_watchpoints_trigger_after_instruction == eLazyBoolNo)1887 return false;1888 if (m_watchpoints_trigger_after_instruction == eLazyBoolYes)1889 return true;1890 }1891 1892 return std::nullopt;1893}1894 1895int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {1896 if (file_spec) {1897 std::string path{file_spec.GetPath(false)};1898 StreamString packet;1899 packet.PutCString("QSetSTDIN:");1900 packet.PutStringAsRawHex8(path);1901 1902 StringExtractorGDBRemote response;1903 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1904 PacketResult::Success) {1905 if (response.IsOKResponse())1906 return 0;1907 uint8_t error = response.GetError();1908 if (error)1909 return error;1910 }1911 }1912 return -1;1913}1914 1915int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {1916 if (file_spec) {1917 std::string path{file_spec.GetPath(false)};1918 StreamString packet;1919 packet.PutCString("QSetSTDOUT:");1920 packet.PutStringAsRawHex8(path);1921 1922 StringExtractorGDBRemote response;1923 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1924 PacketResult::Success) {1925 if (response.IsOKResponse())1926 return 0;1927 uint8_t error = response.GetError();1928 if (error)1929 return error;1930 }1931 }1932 return -1;1933}1934 1935int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {1936 if (file_spec) {1937 std::string path{file_spec.GetPath(false)};1938 StreamString packet;1939 packet.PutCString("QSetSTDERR:");1940 packet.PutStringAsRawHex8(path);1941 1942 StringExtractorGDBRemote response;1943 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1944 PacketResult::Success) {1945 if (response.IsOKResponse())1946 return 0;1947 uint8_t error = response.GetError();1948 if (error)1949 return error;1950 }1951 }1952 return -1;1953}1954 1955bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {1956 StringExtractorGDBRemote response;1957 if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==1958 PacketResult::Success) {1959 if (response.IsUnsupportedResponse())1960 return false;1961 if (response.IsErrorResponse())1962 return false;1963 std::string cwd;1964 response.GetHexByteString(cwd);1965 working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());1966 return !cwd.empty();1967 }1968 return false;1969}1970 1971int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {1972 if (working_dir) {1973 std::string path{working_dir.GetPath(false)};1974 StreamString packet;1975 packet.PutCString("QSetWorkingDir:");1976 packet.PutStringAsRawHex8(path);1977 1978 StringExtractorGDBRemote response;1979 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==1980 PacketResult::Success) {1981 if (response.IsOKResponse())1982 return 0;1983 uint8_t error = response.GetError();1984 if (error)1985 return error;1986 }1987 }1988 return -1;1989}1990 1991int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {1992 char packet[32];1993 const int packet_len =1994 ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);1995 assert(packet_len < (int)sizeof(packet));1996 UNUSED_IF_ASSERT_DISABLED(packet_len);1997 StringExtractorGDBRemote response;1998 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {1999 if (response.IsOKResponse())2000 return 0;2001 uint8_t error = response.GetError();2002 if (error)2003 return error;2004 }2005 return -1;2006}2007 2008int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {2009 char packet[32];2010 const int packet_len = ::snprintf(packet, sizeof(packet),2011 "QSetDetachOnError:%i", enable ? 1 : 0);2012 assert(packet_len < (int)sizeof(packet));2013 UNUSED_IF_ASSERT_DISABLED(packet_len);2014 StringExtractorGDBRemote response;2015 if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {2016 if (response.IsOKResponse())2017 return 0;2018 uint8_t error = response.GetError();2019 if (error)2020 return error;2021 }2022 return -1;2023}2024 2025bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(2026 StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {2027 if (response.IsNormalResponse()) {2028 llvm::StringRef name;2029 llvm::StringRef value;2030 StringExtractor extractor;2031 2032 uint32_t cpu = LLDB_INVALID_CPUTYPE;2033 uint32_t sub = 0;2034 std::string vendor;2035 std::string os_type;2036 2037 while (response.GetNameColonValue(name, value)) {2038 if (name == "pid") {2039 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;2040 value.getAsInteger(0, pid);2041 process_info.SetProcessID(pid);2042 } else if (name == "ppid") {2043 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;2044 value.getAsInteger(0, pid);2045 process_info.SetParentProcessID(pid);2046 } else if (name == "uid") {2047 uint32_t uid = UINT32_MAX;2048 value.getAsInteger(0, uid);2049 process_info.SetUserID(uid);2050 } else if (name == "euid") {2051 uint32_t uid = UINT32_MAX;2052 value.getAsInteger(0, uid);2053 process_info.SetEffectiveUserID(uid);2054 } else if (name == "gid") {2055 uint32_t gid = UINT32_MAX;2056 value.getAsInteger(0, gid);2057 process_info.SetGroupID(gid);2058 } else if (name == "egid") {2059 uint32_t gid = UINT32_MAX;2060 value.getAsInteger(0, gid);2061 process_info.SetEffectiveGroupID(gid);2062 } else if (name == "triple") {2063 StringExtractor extractor(value);2064 std::string triple;2065 extractor.GetHexByteString(triple);2066 process_info.GetArchitecture().SetTriple(triple.c_str());2067 } else if (name == "name") {2068 StringExtractor extractor(value);2069 // The process name from ASCII hex bytes since we can't control the2070 // characters in a process name2071 std::string name;2072 extractor.GetHexByteString(name);2073 process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);2074 } else if (name == "args") {2075 llvm::StringRef encoded_args(value), hex_arg;2076 2077 bool is_arg0 = true;2078 while (!encoded_args.empty()) {2079 std::tie(hex_arg, encoded_args) = encoded_args.split('-');2080 std::string arg;2081 StringExtractor extractor(hex_arg);2082 if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {2083 // In case of wrong encoding, we discard all the arguments2084 process_info.GetArguments().Clear();2085 process_info.SetArg0("");2086 break;2087 }2088 if (is_arg0)2089 process_info.SetArg0(arg);2090 else2091 process_info.GetArguments().AppendArgument(arg);2092 is_arg0 = false;2093 }2094 } else if (name == "cputype") {2095 value.getAsInteger(0, cpu);2096 } else if (name == "cpusubtype") {2097 value.getAsInteger(0, sub);2098 } else if (name == "vendor") {2099 vendor = std::string(value);2100 } else if (name == "ostype") {2101 os_type = std::string(value);2102 }2103 }2104 2105 if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {2106 if (vendor == "apple") {2107 process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,2108 sub);2109 process_info.GetArchitecture().GetTriple().setVendorName(2110 llvm::StringRef(vendor));2111 process_info.GetArchitecture().GetTriple().setOSName(2112 llvm::StringRef(os_type));2113 }2114 }2115 2116 if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)2117 return true;2118 }2119 return false;2120}2121 2122bool GDBRemoteCommunicationClient::GetProcessInfo(2123 lldb::pid_t pid, ProcessInstanceInfo &process_info) {2124 process_info.Clear();2125 2126 if (m_supports_qProcessInfoPID) {2127 char packet[32];2128 const int packet_len =2129 ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);2130 assert(packet_len < (int)sizeof(packet));2131 UNUSED_IF_ASSERT_DISABLED(packet_len);2132 StringExtractorGDBRemote response;2133 if (SendPacketAndWaitForResponse(packet, response) ==2134 PacketResult::Success) {2135 return DecodeProcessInfoResponse(response, process_info);2136 } else {2137 m_supports_qProcessInfoPID = false;2138 return false;2139 }2140 }2141 return false;2142}2143 2144bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {2145 Log *log(GetLog(GDBRLog::Process | GDBRLog::Packets));2146 2147 if (allow_lazy) {2148 if (m_qProcessInfo_is_valid == eLazyBoolYes)2149 return true;2150 if (m_qProcessInfo_is_valid == eLazyBoolNo)2151 return false;2152 }2153 2154 GetHostInfo();2155 2156 StringExtractorGDBRemote response;2157 if (SendPacketAndWaitForResponse("qProcessInfo", response) ==2158 PacketResult::Success) {2159 if (response.IsNormalResponse()) {2160 llvm::StringRef name;2161 llvm::StringRef value;2162 uint32_t cpu = LLDB_INVALID_CPUTYPE;2163 uint32_t sub = 0;2164 std::string os_name;2165 std::string environment;2166 std::string vendor_name;2167 std::string triple;2168 std::string elf_abi;2169 uint32_t pointer_byte_size = 0;2170 StringExtractor extractor;2171 ByteOrder byte_order = eByteOrderInvalid;2172 uint32_t num_keys_decoded = 0;2173 lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;2174 while (response.GetNameColonValue(name, value)) {2175 if (name == "cputype") {2176 if (!value.getAsInteger(16, cpu))2177 ++num_keys_decoded;2178 } else if (name == "cpusubtype") {2179 if (!value.getAsInteger(16, sub)) {2180 ++num_keys_decoded;2181 // Workaround for pre-2024 Apple debugserver, which always2182 // returns arm64e on arm64e-capable hardware regardless of2183 // what the process is. This can be deleted at some point2184 // in the future.2185 if (cpu == llvm::MachO::CPU_TYPE_ARM64 &&2186 sub == llvm::MachO::CPU_SUBTYPE_ARM64E) {2187 if (GetGDBServerVersion())2188 if (m_gdb_server_version >= 1000 &&2189 m_gdb_server_version <= 1504)2190 sub = 0;2191 }2192 }2193 } else if (name == "triple") {2194 StringExtractor extractor(value);2195 extractor.GetHexByteString(triple);2196 ++num_keys_decoded;2197 } else if (name == "ostype") {2198 ParseOSType(value, os_name, environment);2199 ++num_keys_decoded;2200 } else if (name == "vendor") {2201 vendor_name = std::string(value);2202 ++num_keys_decoded;2203 } else if (name == "endian") {2204 byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)2205 .Case("little", eByteOrderLittle)2206 .Case("big", eByteOrderBig)2207 .Case("pdp", eByteOrderPDP)2208 .Default(eByteOrderInvalid);2209 if (byte_order != eByteOrderInvalid)2210 ++num_keys_decoded;2211 } else if (name == "ptrsize") {2212 if (!value.getAsInteger(16, pointer_byte_size))2213 ++num_keys_decoded;2214 } else if (name == "pid") {2215 if (!value.getAsInteger(16, pid))2216 ++num_keys_decoded;2217 } else if (name == "elf_abi") {2218 elf_abi = std::string(value);2219 ++num_keys_decoded;2220 } else if (name == "main-binary-uuid") {2221 m_process_standalone_uuid.SetFromStringRef(value);2222 ++num_keys_decoded;2223 } else if (name == "main-binary-slide") {2224 StringExtractor extractor(value);2225 m_process_standalone_value =2226 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);2227 if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {2228 m_process_standalone_value_is_offset = true;2229 ++num_keys_decoded;2230 }2231 } else if (name == "main-binary-address") {2232 StringExtractor extractor(value);2233 m_process_standalone_value =2234 extractor.GetU64(LLDB_INVALID_ADDRESS, 16);2235 if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {2236 m_process_standalone_value_is_offset = false;2237 ++num_keys_decoded;2238 }2239 } else if (name == "binary-addresses") {2240 m_binary_addresses.clear();2241 ++num_keys_decoded;2242 for (llvm::StringRef x : llvm::split(value, ',')) {2243 addr_t vmaddr;2244 x.consume_front("0x");2245 if (llvm::to_integer(x, vmaddr, 16))2246 m_binary_addresses.push_back(vmaddr);2247 }2248 }2249 }2250 if (num_keys_decoded > 0)2251 m_qProcessInfo_is_valid = eLazyBoolYes;2252 if (pid != LLDB_INVALID_PROCESS_ID) {2253 m_curr_pid_is_valid = eLazyBoolYes;2254 m_curr_pid_run = m_curr_pid = pid;2255 }2256 2257 // Set the ArchSpec from the triple if we have it.2258 if (!triple.empty()) {2259 m_process_arch.SetTriple(triple.c_str());2260 m_process_arch.SetFlags(elf_abi);2261 if (pointer_byte_size) {2262 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());2263 }2264 } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&2265 !vendor_name.empty()) {2266 llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);2267 if (!environment.empty())2268 triple.setEnvironmentName(environment);2269 2270 assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);2271 assert(triple.getObjectFormat() != llvm::Triple::Wasm);2272 assert(triple.getObjectFormat() != llvm::Triple::XCOFF);2273 switch (triple.getObjectFormat()) {2274 case llvm::Triple::MachO:2275 m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);2276 break;2277 case llvm::Triple::ELF:2278 m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);2279 break;2280 case llvm::Triple::COFF:2281 m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);2282 break;2283 case llvm::Triple::GOFF:2284 case llvm::Triple::SPIRV:2285 case llvm::Triple::Wasm:2286 case llvm::Triple::XCOFF:2287 case llvm::Triple::DXContainer:2288 LLDB_LOGF(log, "error: not supported target architecture");2289 return false;2290 case llvm::Triple::UnknownObjectFormat:2291 LLDB_LOGF(log, "error: failed to determine target architecture");2292 return false;2293 }2294 2295 if (pointer_byte_size) {2296 assert(pointer_byte_size == m_process_arch.GetAddressByteSize());2297 }2298 if (byte_order != eByteOrderInvalid) {2299 assert(byte_order == m_process_arch.GetByteOrder());2300 }2301 m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));2302 m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));2303 m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));2304 }2305 return true;2306 }2307 } else {2308 m_qProcessInfo_is_valid = eLazyBoolNo;2309 }2310 2311 return false;2312}2313 2314uint32_t GDBRemoteCommunicationClient::FindProcesses(2315 const ProcessInstanceInfoMatch &match_info,2316 ProcessInstanceInfoList &process_infos) {2317 process_infos.clear();2318 2319 if (m_supports_qfProcessInfo) {2320 StreamString packet;2321 packet.PutCString("qfProcessInfo");2322 if (!match_info.MatchAllProcesses()) {2323 packet.PutChar(':');2324 const char *name = match_info.GetProcessInfo().GetName();2325 bool has_name_match = false;2326 if (name && name[0]) {2327 has_name_match = true;2328 NameMatch name_match_type = match_info.GetNameMatchType();2329 switch (name_match_type) {2330 case NameMatch::Ignore:2331 has_name_match = false;2332 break;2333 2334 case NameMatch::Equals:2335 packet.PutCString("name_match:equals;");2336 break;2337 2338 case NameMatch::Contains:2339 packet.PutCString("name_match:contains;");2340 break;2341 2342 case NameMatch::StartsWith:2343 packet.PutCString("name_match:starts_with;");2344 break;2345 2346 case NameMatch::EndsWith:2347 packet.PutCString("name_match:ends_with;");2348 break;2349 2350 case NameMatch::RegularExpression:2351 packet.PutCString("name_match:regex;");2352 break;2353 }2354 if (has_name_match) {2355 packet.PutCString("name:");2356 packet.PutBytesAsRawHex8(name, ::strlen(name));2357 packet.PutChar(';');2358 }2359 }2360 2361 if (match_info.GetProcessInfo().ProcessIDIsValid())2362 packet.Printf("pid:%" PRIu64 ";",2363 match_info.GetProcessInfo().GetProcessID());2364 if (match_info.GetProcessInfo().ParentProcessIDIsValid())2365 packet.Printf("parent_pid:%" PRIu64 ";",2366 match_info.GetProcessInfo().GetParentProcessID());2367 if (match_info.GetProcessInfo().UserIDIsValid())2368 packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());2369 if (match_info.GetProcessInfo().GroupIDIsValid())2370 packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());2371 if (match_info.GetProcessInfo().EffectiveUserIDIsValid())2372 packet.Printf("euid:%u;",2373 match_info.GetProcessInfo().GetEffectiveUserID());2374 if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())2375 packet.Printf("egid:%u;",2376 match_info.GetProcessInfo().GetEffectiveGroupID());2377 packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);2378 if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {2379 const ArchSpec &match_arch =2380 match_info.GetProcessInfo().GetArchitecture();2381 const llvm::Triple &triple = match_arch.GetTriple();2382 packet.PutCString("triple:");2383 packet.PutCString(triple.getTriple());2384 packet.PutChar(';');2385 }2386 }2387 StringExtractorGDBRemote response;2388 // Increase timeout as the first qfProcessInfo packet takes a long time on2389 // Android. The value of 1min was arrived at empirically.2390 ScopedTimeout timeout(*this, minutes(1));2391 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==2392 PacketResult::Success) {2393 do {2394 ProcessInstanceInfo process_info;2395 if (!DecodeProcessInfoResponse(response, process_info))2396 break;2397 process_infos.push_back(process_info);2398 response = StringExtractorGDBRemote();2399 } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==2400 PacketResult::Success);2401 } else {2402 m_supports_qfProcessInfo = false;2403 return 0;2404 }2405 }2406 return process_infos.size();2407}2408 2409bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,2410 std::string &name) {2411 if (m_supports_qUserName) {2412 char packet[32];2413 const int packet_len =2414 ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);2415 assert(packet_len < (int)sizeof(packet));2416 UNUSED_IF_ASSERT_DISABLED(packet_len);2417 StringExtractorGDBRemote response;2418 if (SendPacketAndWaitForResponse(packet, response) ==2419 PacketResult::Success) {2420 if (response.IsNormalResponse()) {2421 // Make sure we parsed the right number of characters. The response is2422 // the hex encoded user name and should make up the entire packet. If2423 // there are any non-hex ASCII bytes, the length won't match below..2424 if (response.GetHexByteString(name) * 2 ==2425 response.GetStringRef().size())2426 return true;2427 }2428 } else {2429 m_supports_qUserName = false;2430 return false;2431 }2432 }2433 return false;2434}2435 2436bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,2437 std::string &name) {2438 if (m_supports_qGroupName) {2439 char packet[32];2440 const int packet_len =2441 ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);2442 assert(packet_len < (int)sizeof(packet));2443 UNUSED_IF_ASSERT_DISABLED(packet_len);2444 StringExtractorGDBRemote response;2445 if (SendPacketAndWaitForResponse(packet, response) ==2446 PacketResult::Success) {2447 if (response.IsNormalResponse()) {2448 // Make sure we parsed the right number of characters. The response is2449 // the hex encoded group name and should make up the entire packet. If2450 // there are any non-hex ASCII bytes, the length won't match below..2451 if (response.GetHexByteString(name) * 2 ==2452 response.GetStringRef().size())2453 return true;2454 }2455 } else {2456 m_supports_qGroupName = false;2457 return false;2458 }2459 }2460 return false;2461}2462 2463static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,2464 uint32_t recv_size) {2465 packet.Clear();2466 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);2467 uint32_t bytes_left = send_size;2468 while (bytes_left > 0) {2469 if (bytes_left >= 26) {2470 packet.PutCString("abcdefghijklmnopqrstuvwxyz");2471 bytes_left -= 26;2472 } else {2473 packet.Printf("%*.*s;", bytes_left, bytes_left,2474 "abcdefghijklmnopqrstuvwxyz");2475 bytes_left = 0;2476 }2477 }2478}2479 2480duration<float>2481calculate_standard_deviation(const std::vector<duration<float>> &v) {2482 if (v.size() == 0)2483 return duration<float>::zero();2484 using Dur = duration<float>;2485 Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());2486 Dur mean = sum / v.size();2487 float accum = 0;2488 for (auto d : v) {2489 float delta = (d - mean).count();2490 accum += delta * delta;2491 };2492 2493 return Dur(sqrtf(accum / (v.size() - 1)));2494}2495 2496void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,2497 uint32_t max_send,2498 uint32_t max_recv,2499 uint64_t recv_amount,2500 bool json, Stream &strm) {2501 2502 if (SendSpeedTestPacket(0, 0)) {2503 StreamString packet;2504 if (json)2505 strm.Printf("{ \"packet_speeds\" : {\n \"num_packets\" : %u,\n "2506 "\"results\" : [",2507 num_packets);2508 else2509 strm.Printf("Testing sending %u packets of various sizes:\n",2510 num_packets);2511 strm.Flush();2512 2513 uint32_t result_idx = 0;2514 uint32_t send_size;2515 std::vector<duration<float>> packet_times;2516 2517 for (send_size = 0; send_size <= max_send;2518 send_size ? send_size *= 2 : send_size = 4) {2519 for (uint32_t recv_size = 0; recv_size <= max_recv;2520 recv_size ? recv_size *= 2 : recv_size = 4) {2521 MakeSpeedTestPacket(packet, send_size, recv_size);2522 2523 packet_times.clear();2524 // Test how long it takes to send 'num_packets' packets2525 const auto start_time = steady_clock::now();2526 for (uint32_t i = 0; i < num_packets; ++i) {2527 const auto packet_start_time = steady_clock::now();2528 StringExtractorGDBRemote response;2529 SendPacketAndWaitForResponse(packet.GetString(), response);2530 const auto packet_end_time = steady_clock::now();2531 packet_times.push_back(packet_end_time - packet_start_time);2532 }2533 const auto end_time = steady_clock::now();2534 const auto total_time = end_time - start_time;2535 2536 float packets_per_second =2537 ((float)num_packets) / duration<float>(total_time).count();2538 auto average_per_packet = num_packets > 0 ? total_time / num_packets2539 : duration<float>::zero();2540 const duration<float> standard_deviation =2541 calculate_standard_deviation(packet_times);2542 if (json) {2543 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "2544 "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "2545 "\"standard_deviation_nsec\" : {4,9:ns-f0}}",2546 result_idx > 0 ? "," : "", send_size, recv_size,2547 total_time, standard_deviation);2548 ++result_idx;2549 } else {2550 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "2551 "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "2552 "standard deviation of {5,10:ms+f6}\n",2553 send_size, recv_size, duration<float>(total_time),2554 packets_per_second, duration<float>(average_per_packet),2555 standard_deviation);2556 }2557 strm.Flush();2558 }2559 }2560 2561 const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);2562 if (json)2563 strm.Printf("\n ]\n },\n \"download_speed\" : {\n \"byte_size\" "2564 ": %" PRIu64 ",\n \"results\" : [",2565 recv_amount);2566 else2567 strm.Printf("Testing receiving %2.1fMB of data using varying receive "2568 "packet sizes:\n",2569 k_recv_amount_mb);2570 strm.Flush();2571 send_size = 0;2572 result_idx = 0;2573 for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {2574 MakeSpeedTestPacket(packet, send_size, recv_size);2575 2576 // If we have a receive size, test how long it takes to receive 4MB of2577 // data2578 if (recv_size > 0) {2579 const auto start_time = steady_clock::now();2580 uint32_t bytes_read = 0;2581 uint32_t packet_count = 0;2582 while (bytes_read < recv_amount) {2583 StringExtractorGDBRemote response;2584 SendPacketAndWaitForResponse(packet.GetString(), response);2585 bytes_read += recv_size;2586 ++packet_count;2587 }2588 const auto end_time = steady_clock::now();2589 const auto total_time = end_time - start_time;2590 float mb_second = ((float)recv_amount) /2591 duration<float>(total_time).count() /2592 (1024.0 * 1024.0);2593 float packets_per_second =2594 ((float)packet_count) / duration<float>(total_time).count();2595 const auto average_per_packet = packet_count > 02596 ? total_time / packet_count2597 : duration<float>::zero();2598 2599 if (json) {2600 strm.Format("{0}\n {{\"send_size\" : {1,6}, \"recv_size\" : "2601 "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",2602 result_idx > 0 ? "," : "", send_size, recv_size,2603 total_time);2604 ++result_idx;2605 } else {2606 strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "2607 "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "2608 "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",2609 send_size, recv_size, packet_count, k_recv_amount_mb,2610 duration<float>(total_time), mb_second,2611 packets_per_second, duration<float>(average_per_packet));2612 }2613 strm.Flush();2614 }2615 }2616 if (json)2617 strm.Printf("\n ]\n }\n}\n");2618 else2619 strm.EOL();2620 }2621}2622 2623bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,2624 uint32_t recv_size) {2625 StreamString packet;2626 packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);2627 uint32_t bytes_left = send_size;2628 while (bytes_left > 0) {2629 if (bytes_left >= 26) {2630 packet.PutCString("abcdefghijklmnopqrstuvwxyz");2631 bytes_left -= 26;2632 } else {2633 packet.Printf("%*.*s;", bytes_left, bytes_left,2634 "abcdefghijklmnopqrstuvwxyz");2635 bytes_left = 0;2636 }2637 }2638 2639 StringExtractorGDBRemote response;2640 return SendPacketAndWaitForResponse(packet.GetString(), response) ==2641 PacketResult::Success;2642}2643 2644bool GDBRemoteCommunicationClient::LaunchGDBServer(2645 const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,2646 std::string &socket_name) {2647 pid = LLDB_INVALID_PROCESS_ID;2648 port = 0;2649 socket_name.clear();2650 2651 StringExtractorGDBRemote response;2652 StreamString stream;2653 stream.PutCString("qLaunchGDBServer;");2654 std::string hostname;2655 if (remote_accept_hostname && remote_accept_hostname[0])2656 hostname = remote_accept_hostname;2657 else {2658 if (HostInfo::GetHostname(hostname)) {2659 // Make the GDB server we launch only accept connections from this host2660 stream.Printf("host:%s;", hostname.c_str());2661 } else {2662 // Make the GDB server we launch accept connections from any host since2663 // we can't figure out the hostname2664 stream.Printf("host:*;");2665 }2666 }2667 // give the process a few seconds to startup2668 ScopedTimeout timeout(*this, seconds(10));2669 2670 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==2671 PacketResult::Success) {2672 if (response.IsErrorResponse())2673 return false;2674 2675 llvm::StringRef name;2676 llvm::StringRef value;2677 while (response.GetNameColonValue(name, value)) {2678 if (name == "port")2679 value.getAsInteger(0, port);2680 else if (name == "pid")2681 value.getAsInteger(0, pid);2682 else if (name.compare("socket_name") == 0) {2683 StringExtractor extractor(value);2684 extractor.GetHexByteString(socket_name);2685 }2686 }2687 return true;2688 }2689 return false;2690}2691 2692size_t GDBRemoteCommunicationClient::QueryGDBServer(2693 std::vector<std::pair<uint16_t, std::string>> &connection_urls) {2694 connection_urls.clear();2695 2696 StringExtractorGDBRemote response;2697 if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=2698 PacketResult::Success)2699 return 0;2700 2701 StructuredData::ObjectSP data =2702 StructuredData::ParseJSON(response.GetStringRef());2703 if (!data)2704 return 0;2705 2706 StructuredData::Array *array = data->GetAsArray();2707 if (!array)2708 return 0;2709 2710 for (size_t i = 0, count = array->GetSize(); i < count; ++i) {2711 std::optional<StructuredData::Dictionary *> maybe_element =2712 array->GetItemAtIndexAsDictionary(i);2713 if (!maybe_element)2714 continue;2715 2716 StructuredData::Dictionary *element = *maybe_element;2717 uint16_t port = 0;2718 if (StructuredData::ObjectSP port_osp =2719 element->GetValueForKey(llvm::StringRef("port")))2720 port = port_osp->GetUnsignedIntegerValue(0);2721 2722 std::string socket_name;2723 if (StructuredData::ObjectSP socket_name_osp =2724 element->GetValueForKey(llvm::StringRef("socket_name")))2725 socket_name = std::string(socket_name_osp->GetStringValue());2726 2727 if (port != 0 || !socket_name.empty())2728 connection_urls.emplace_back(port, socket_name);2729 }2730 return connection_urls.size();2731}2732 2733bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {2734 StreamString stream;2735 stream.Printf("qKillSpawnedProcess:%" PRId64, pid);2736 2737 StringExtractorGDBRemote response;2738 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==2739 PacketResult::Success) {2740 if (response.IsOKResponse())2741 return true;2742 }2743 return false;2744}2745 2746std::optional<PidTid> GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(2747 uint64_t tid, uint64_t pid, char op) {2748 lldb_private::StreamString packet;2749 packet.PutChar('H');2750 packet.PutChar(op);2751 2752 if (pid != LLDB_INVALID_PROCESS_ID)2753 packet.Printf("p%" PRIx64 ".", pid);2754 2755 if (tid == UINT64_MAX)2756 packet.PutCString("-1");2757 else2758 packet.Printf("%" PRIx64, tid);2759 2760 StringExtractorGDBRemote response;2761 if (SendPacketAndWaitForResponse(packet.GetString(), response) ==2762 PacketResult::Success) {2763 if (response.IsOKResponse())2764 return {{pid, tid}};2765 2766 /*2767 * Connected bare-iron target (like YAMON gdb-stub) may not have support for2768 * Hg packet.2769 * The reply from '?' packet could be as simple as 'S05'. There is no packet2770 * which can2771 * give us pid and/or tid. Assume pid=tid=1 in such cases.2772 */2773 if (response.IsUnsupportedResponse() && IsConnected())2774 return {{1, 1}};2775 }2776 return std::nullopt;2777}2778 2779bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,2780 uint64_t pid) {2781 if (m_curr_tid == tid &&2782 (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))2783 return true;2784 2785 std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');2786 if (ret) {2787 if (ret->pid != LLDB_INVALID_PROCESS_ID)2788 m_curr_pid = ret->pid;2789 m_curr_tid = ret->tid;2790 }2791 return ret.has_value();2792}2793 2794bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,2795 uint64_t pid) {2796 if (m_curr_tid_run == tid &&2797 (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))2798 return true;2799 2800 std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');2801 if (ret) {2802 if (ret->pid != LLDB_INVALID_PROCESS_ID)2803 m_curr_pid_run = ret->pid;2804 m_curr_tid_run = ret->tid;2805 }2806 return ret.has_value();2807}2808 2809bool GDBRemoteCommunicationClient::GetStopReply(2810 StringExtractorGDBRemote &response) {2811 if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)2812 return response.IsNormalResponse();2813 return false;2814}2815 2816bool GDBRemoteCommunicationClient::GetThreadStopInfo(2817 lldb::tid_t tid, StringExtractorGDBRemote &response) {2818 if (m_supports_qThreadStopInfo) {2819 char packet[256];2820 int packet_len =2821 ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);2822 assert(packet_len < (int)sizeof(packet));2823 UNUSED_IF_ASSERT_DISABLED(packet_len);2824 if (SendPacketAndWaitForResponse(packet, response) ==2825 PacketResult::Success) {2826 if (response.IsUnsupportedResponse())2827 m_supports_qThreadStopInfo = false;2828 else if (response.IsNormalResponse())2829 return true;2830 else2831 return false;2832 } else {2833 m_supports_qThreadStopInfo = false;2834 }2835 }2836 return false;2837}2838 2839uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(2840 GDBStoppointType type, bool insert, addr_t addr, uint32_t length,2841 std::chrono::seconds timeout) {2842 Log *log = GetLog(LLDBLog::Breakpoints);2843 LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,2844 __FUNCTION__, insert ? "add" : "remove", addr);2845 2846 // Check if the stub is known not to support this breakpoint type2847 if (!SupportsGDBStoppointPacket(type))2848 return UINT8_MAX;2849 // Construct the breakpoint packet2850 char packet[64];2851 const int packet_len =2852 ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",2853 insert ? 'Z' : 'z', type, addr, length);2854 // Check we haven't overwritten the end of the packet buffer2855 assert(packet_len + 1 < (int)sizeof(packet));2856 UNUSED_IF_ASSERT_DISABLED(packet_len);2857 StringExtractorGDBRemote response;2858 // Make sure the response is either "OK", "EXX" where XX are two hex digits,2859 // or "" (unsupported)2860 response.SetResponseValidatorToOKErrorNotSupported();2861 // Try to send the breakpoint packet, and check that it was correctly sent2862 if (SendPacketAndWaitForResponse(packet, response, timeout) ==2863 PacketResult::Success) {2864 // Receive and OK packet when the breakpoint successfully placed2865 if (response.IsOKResponse())2866 return 0;2867 2868 // Status while setting breakpoint, send back specific error2869 if (response.IsErrorResponse())2870 return response.GetError();2871 2872 // Empty packet informs us that breakpoint is not supported2873 if (response.IsUnsupportedResponse()) {2874 // Disable this breakpoint type since it is unsupported2875 switch (type) {2876 case eBreakpointSoftware:2877 m_supports_z0 = false;2878 break;2879 case eBreakpointHardware:2880 m_supports_z1 = false;2881 break;2882 case eWatchpointWrite:2883 m_supports_z2 = false;2884 break;2885 case eWatchpointRead:2886 m_supports_z3 = false;2887 break;2888 case eWatchpointReadWrite:2889 m_supports_z4 = false;2890 break;2891 case eStoppointInvalid:2892 return UINT8_MAX;2893 }2894 }2895 }2896 // Signal generic failure2897 return UINT8_MAX;2898}2899 2900std::vector<std::pair<lldb::pid_t, lldb::tid_t>>2901GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(2902 bool &sequence_mutex_unavailable) {2903 std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;2904 2905 Lock lock(*this);2906 if (lock) {2907 sequence_mutex_unavailable = false;2908 StringExtractorGDBRemote response;2909 2910 PacketResult packet_result;2911 for (packet_result =2912 SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);2913 packet_result == PacketResult::Success && response.IsNormalResponse();2914 packet_result =2915 SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {2916 char ch = response.GetChar();2917 if (ch == 'l')2918 break;2919 if (ch == 'm') {2920 do {2921 auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);2922 // If we get an invalid response, break out of the loop.2923 // If there are valid tids, they have been added to ids.2924 // If there are no valid tids, we'll fall through to the2925 // bare-iron target handling below.2926 if (!pid_tid)2927 break;2928 2929 ids.push_back(*pid_tid);2930 ch = response.GetChar(); // Skip the command separator2931 } while (ch == ','); // Make sure we got a comma separator2932 }2933 }2934 2935 /*2936 * Connected bare-iron target (like YAMON gdb-stub) may not have support for2937 * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet2938 * could2939 * be as simple as 'S05'. There is no packet which can give us pid and/or2940 * tid.2941 * Assume pid=tid=1 in such cases.2942 */2943 if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&2944 ids.size() == 0 && IsConnected()) {2945 ids.emplace_back(1, 1);2946 }2947 } else {2948 Log *log(GetLog(GDBRLog::Process | GDBRLog::Packets));2949 LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "2950 "packet 'qfThreadInfo'");2951 sequence_mutex_unavailable = true;2952 }2953 2954 return ids;2955}2956 2957size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(2958 std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {2959 lldb::pid_t pid = GetCurrentProcessID();2960 thread_ids.clear();2961 2962 auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);2963 if (ids.empty() || sequence_mutex_unavailable)2964 return 0;2965 2966 for (auto id : ids) {2967 // skip threads that do not belong to the current process2968 if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)2969 continue;2970 if (id.second != LLDB_INVALID_THREAD_ID &&2971 id.second != StringExtractorGDBRemote::AllThreads)2972 thread_ids.push_back(id.second);2973 }2974 2975 return thread_ids.size();2976}2977 2978lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {2979 StringExtractorGDBRemote response;2980 if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=2981 PacketResult::Success ||2982 !response.IsNormalResponse())2983 return LLDB_INVALID_ADDRESS;2984 return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);2985}2986 2987lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(2988 llvm::StringRef command,2989 const FileSpec &2990 working_dir, // Pass empty FileSpec to use the current working directory2991 int *status_ptr, // Pass NULL if you don't want the process exit status2992 int *signo_ptr, // Pass NULL if you don't want the signal that caused the2993 // process to exit2994 std::string2995 *command_output, // Pass NULL if you don't want the command output2996 const Timeout<std::micro> &timeout) {2997 lldb_private::StreamString stream;2998 stream.PutCString("qPlatform_shell:");2999 stream.PutBytesAsRawHex8(command.data(), command.size());3000 stream.PutChar(',');3001 uint32_t timeout_sec = UINT32_MAX;3002 if (timeout) {3003 // TODO: Use chrono version of std::ceil once c++17 is available.3004 timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());3005 }3006 stream.PutHex32(timeout_sec);3007 if (working_dir) {3008 std::string path{working_dir.GetPath(false)};3009 stream.PutChar(',');3010 stream.PutStringAsRawHex8(path);3011 }3012 StringExtractorGDBRemote response;3013 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3014 PacketResult::Success) {3015 if (response.GetChar() != 'F')3016 return Status::FromErrorString("malformed reply");3017 if (response.GetChar() != ',')3018 return Status::FromErrorString("malformed reply");3019 uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);3020 if (exitcode == UINT32_MAX)3021 return Status::FromErrorString("unable to run remote process");3022 else if (status_ptr)3023 *status_ptr = exitcode;3024 if (response.GetChar() != ',')3025 return Status::FromErrorString("malformed reply");3026 uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);3027 if (signo_ptr)3028 *signo_ptr = signo;3029 if (response.GetChar() != ',')3030 return Status::FromErrorString("malformed reply");3031 std::string output;3032 response.GetEscapedBinaryData(output);3033 if (command_output)3034 command_output->assign(output);3035 return Status();3036 }3037 return Status::FromErrorString("unable to send packet");3038}3039 3040Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,3041 uint32_t file_permissions) {3042 std::string path{file_spec.GetPath(false)};3043 lldb_private::StreamString stream;3044 stream.PutCString("qPlatform_mkdir:");3045 stream.PutHex32(file_permissions);3046 stream.PutChar(',');3047 stream.PutStringAsRawHex8(path);3048 llvm::StringRef packet = stream.GetString();3049 StringExtractorGDBRemote response;3050 3051 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)3052 return Status::FromErrorStringWithFormat("failed to send '%s' packet",3053 packet.str().c_str());3054 3055 if (response.GetChar() != 'F')3056 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",3057 packet.str().c_str());3058 3059 return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);3060}3061 3062Status3063GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,3064 uint32_t file_permissions) {3065 std::string path{file_spec.GetPath(false)};3066 lldb_private::StreamString stream;3067 stream.PutCString("qPlatform_chmod:");3068 stream.PutHex32(file_permissions);3069 stream.PutChar(',');3070 stream.PutStringAsRawHex8(path);3071 llvm::StringRef packet = stream.GetString();3072 StringExtractorGDBRemote response;3073 3074 if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)3075 return Status::FromErrorStringWithFormat("failed to send '%s' packet",3076 stream.GetData());3077 3078 if (response.GetChar() != 'F')3079 return Status::FromErrorStringWithFormat("invalid response to '%s' packet",3080 stream.GetData());3081 3082 return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);3083}3084 3085static int gdb_errno_to_system(int err) {3086 switch (err) {3087#define HANDLE_ERRNO(name, value) \3088 case GDB_##name: \3089 return name;3090#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"3091 default:3092 return -1;3093 }3094}3095 3096static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,3097 uint64_t fail_result, Status &error) {3098 response.SetFilePos(0);3099 if (response.GetChar() != 'F')3100 return fail_result;3101 int32_t result = response.GetS32(-2, 16);3102 if (result == -2)3103 return fail_result;3104 if (response.GetChar() == ',') {3105 int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));3106 if (result_errno != -1)3107 error = Status(result_errno, eErrorTypePOSIX);3108 else3109 error = Status(-1, eErrorTypeGeneric);3110 } else3111 error.Clear();3112 return result;3113}3114lldb::user_id_t3115GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,3116 File::OpenOptions flags, mode_t mode,3117 Status &error) {3118 std::string path(file_spec.GetPath(false));3119 lldb_private::StreamString stream;3120 stream.PutCString("vFile:open:");3121 if (path.empty())3122 return UINT64_MAX;3123 stream.PutStringAsRawHex8(path);3124 stream.PutChar(',');3125 stream.PutHex32(flags);3126 stream.PutChar(',');3127 stream.PutHex32(mode);3128 StringExtractorGDBRemote response;3129 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3130 PacketResult::Success) {3131 return ParseHostIOPacketResponse(response, UINT64_MAX, error);3132 }3133 return UINT64_MAX;3134}3135 3136bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,3137 Status &error) {3138 lldb_private::StreamString stream;3139 stream.Printf("vFile:close:%x", (int)fd);3140 StringExtractorGDBRemote response;3141 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3142 PacketResult::Success) {3143 return ParseHostIOPacketResponse(response, -1, error) == 0;3144 }3145 return false;3146}3147 3148std::optional<GDBRemoteFStatData>3149GDBRemoteCommunicationClient::FStat(lldb::user_id_t fd) {3150 lldb_private::StreamString stream;3151 stream.Printf("vFile:fstat:%" PRIx64, fd);3152 StringExtractorGDBRemote response;3153 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3154 PacketResult::Success) {3155 if (response.GetChar() != 'F')3156 return std::nullopt;3157 int64_t size = response.GetS64(-1, 16);3158 if (size > 0 && response.GetChar() == ';') {3159 std::string buffer;3160 if (response.GetEscapedBinaryData(buffer)) {3161 GDBRemoteFStatData out;3162 if (buffer.size() != sizeof(out))3163 return std::nullopt;3164 memcpy(&out, buffer.data(), sizeof(out));3165 return out;3166 }3167 }3168 }3169 return std::nullopt;3170}3171 3172std::optional<GDBRemoteFStatData>3173GDBRemoteCommunicationClient::Stat(const lldb_private::FileSpec &file_spec) {3174 Status error;3175 lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error);3176 if (fd == UINT64_MAX)3177 return std::nullopt;3178 std::optional<GDBRemoteFStatData> st = FStat(fd);3179 CloseFile(fd, error);3180 return st;3181}3182 3183// Extension of host I/O packets to get the file size.3184lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(3185 const lldb_private::FileSpec &file_spec) {3186 if (m_supports_vFileSize) {3187 std::string path(file_spec.GetPath(false));3188 lldb_private::StreamString stream;3189 stream.PutCString("vFile:size:");3190 stream.PutStringAsRawHex8(path);3191 StringExtractorGDBRemote response;3192 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=3193 PacketResult::Success)3194 return UINT64_MAX;3195 3196 if (!response.IsUnsupportedResponse()) {3197 if (response.GetChar() != 'F')3198 return UINT64_MAX;3199 uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);3200 return retcode;3201 }3202 m_supports_vFileSize = false;3203 }3204 3205 // Fallback to fstat.3206 std::optional<GDBRemoteFStatData> st = Stat(file_spec);3207 return st ? st->gdb_st_size : UINT64_MAX;3208}3209 3210void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(3211 CompletionRequest &request, bool only_dir) {3212 lldb_private::StreamString stream;3213 stream.PutCString("qPathComplete:");3214 stream.PutHex32(only_dir ? 1 : 0);3215 stream.PutChar(',');3216 stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());3217 StringExtractorGDBRemote response;3218 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3219 PacketResult::Success) {3220 StreamString strm;3221 char ch = response.GetChar();3222 if (ch != 'M')3223 return;3224 while (response.Peek()) {3225 strm.Clear();3226 while ((ch = response.GetHexU8(0, false)) != '\0')3227 strm.PutChar(ch);3228 request.AddCompletion(strm.GetString());3229 if (response.GetChar() != ',')3230 break;3231 }3232 }3233}3234 3235Status3236GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,3237 uint32_t &file_permissions) {3238 if (m_supports_vFileMode) {3239 std::string path{file_spec.GetPath(false)};3240 Status error;3241 lldb_private::StreamString stream;3242 stream.PutCString("vFile:mode:");3243 stream.PutStringAsRawHex8(path);3244 StringExtractorGDBRemote response;3245 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=3246 PacketResult::Success) {3247 error = Status::FromErrorStringWithFormat("failed to send '%s' packet",3248 stream.GetData());3249 return error;3250 }3251 if (!response.IsUnsupportedResponse()) {3252 if (response.GetChar() != 'F') {3253 error = Status::FromErrorStringWithFormat(3254 "invalid response to '%s' packet", stream.GetData());3255 } else {3256 const uint32_t mode = response.GetS32(-1, 16);3257 if (static_cast<int32_t>(mode) == -1) {3258 if (response.GetChar() == ',') {3259 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3260 if (response_errno > 0)3261 error = Status(response_errno, lldb::eErrorTypePOSIX);3262 else3263 error = Status::FromErrorString("unknown error");3264 } else3265 error = Status::FromErrorString("unknown error");3266 } else {3267 file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);3268 }3269 }3270 return error;3271 } else { // response.IsUnsupportedResponse()3272 m_supports_vFileMode = false;3273 }3274 }3275 3276 // Fallback to fstat.3277 if (std::optional<GDBRemoteFStatData> st = Stat(file_spec)) {3278 file_permissions = st->gdb_st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);3279 return Status();3280 }3281 return Status::FromErrorString("fstat failed");3282}3283 3284uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,3285 uint64_t offset, void *dst,3286 uint64_t dst_len,3287 Status &error) {3288 lldb_private::StreamString stream;3289 stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len,3290 offset);3291 StringExtractorGDBRemote response;3292 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3293 PacketResult::Success) {3294 if (response.GetChar() != 'F')3295 return 0;3296 int64_t retcode = response.GetS64(-1, 16);3297 if (retcode == -1) {3298 error = Status::FromErrorString("unknown error");3299 if (response.GetChar() == ',') {3300 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3301 if (response_errno > 0)3302 error = Status(response_errno, lldb::eErrorTypePOSIX);3303 }3304 return -1;3305 }3306 const char next = (response.Peek() ? *response.Peek() : 0);3307 if (next == ',')3308 return 0;3309 if (next == ';') {3310 response.GetChar(); // skip the semicolon3311 std::string buffer;3312 if (response.GetEscapedBinaryData(buffer)) {3313 const uint64_t data_to_write =3314 std::min<uint64_t>(dst_len, buffer.size());3315 if (data_to_write > 0)3316 memcpy(dst, &buffer[0], data_to_write);3317 return data_to_write;3318 }3319 }3320 }3321 return 0;3322}3323 3324uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,3325 uint64_t offset,3326 const void *src,3327 uint64_t src_len,3328 Status &error) {3329 lldb_private::StreamGDBRemote stream;3330 stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset);3331 stream.PutEscapedBytes(src, src_len);3332 StringExtractorGDBRemote response;3333 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3334 PacketResult::Success) {3335 if (response.GetChar() != 'F') {3336 error = Status::FromErrorStringWithFormat("write file failed");3337 return 0;3338 }3339 int64_t bytes_written = response.GetS64(-1, 16);3340 if (bytes_written == -1) {3341 error = Status::FromErrorString("unknown error");3342 if (response.GetChar() == ',') {3343 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3344 if (response_errno > 0)3345 error = Status(response_errno, lldb::eErrorTypePOSIX);3346 }3347 return -1;3348 }3349 return bytes_written;3350 } else {3351 error = Status::FromErrorString("failed to send vFile:pwrite packet");3352 }3353 return 0;3354}3355 3356Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,3357 const FileSpec &dst) {3358 std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};3359 Status error;3360 lldb_private::StreamGDBRemote stream;3361 stream.PutCString("vFile:symlink:");3362 // the unix symlink() command reverses its parameters where the dst if first,3363 // so we follow suit here3364 stream.PutStringAsRawHex8(dst_path);3365 stream.PutChar(',');3366 stream.PutStringAsRawHex8(src_path);3367 StringExtractorGDBRemote response;3368 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3369 PacketResult::Success) {3370 if (response.GetChar() == 'F') {3371 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);3372 if (result != 0) {3373 error = Status::FromErrorString("unknown error");3374 if (response.GetChar() == ',') {3375 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3376 if (response_errno > 0)3377 error = Status(response_errno, lldb::eErrorTypePOSIX);3378 }3379 }3380 } else {3381 // Should have returned with 'F<result>[,<errno>]'3382 error = Status::FromErrorStringWithFormat("symlink failed");3383 }3384 } else {3385 error = Status::FromErrorString("failed to send vFile:symlink packet");3386 }3387 return error;3388}3389 3390Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {3391 std::string path{file_spec.GetPath(false)};3392 Status error;3393 lldb_private::StreamGDBRemote stream;3394 stream.PutCString("vFile:unlink:");3395 // the unix symlink() command reverses its parameters where the dst if first,3396 // so we follow suit here3397 stream.PutStringAsRawHex8(path);3398 StringExtractorGDBRemote response;3399 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3400 PacketResult::Success) {3401 if (response.GetChar() == 'F') {3402 uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);3403 if (result != 0) {3404 error = Status::FromErrorString("unknown error");3405 if (response.GetChar() == ',') {3406 int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));3407 if (response_errno > 0)3408 error = Status(response_errno, lldb::eErrorTypePOSIX);3409 }3410 }3411 } else {3412 // Should have returned with 'F<result>[,<errno>]'3413 error = Status::FromErrorStringWithFormat("unlink failed");3414 }3415 } else {3416 error = Status::FromErrorString("failed to send vFile:unlink packet");3417 }3418 return error;3419}3420 3421// Extension of host I/O packets to get whether a file exists.3422bool GDBRemoteCommunicationClient::GetFileExists(3423 const lldb_private::FileSpec &file_spec) {3424 if (m_supports_vFileExists) {3425 std::string path(file_spec.GetPath(false));3426 lldb_private::StreamString stream;3427 stream.PutCString("vFile:exists:");3428 stream.PutStringAsRawHex8(path);3429 StringExtractorGDBRemote response;3430 if (SendPacketAndWaitForResponse(stream.GetString(), response) !=3431 PacketResult::Success)3432 return false;3433 if (!response.IsUnsupportedResponse()) {3434 if (response.GetChar() != 'F')3435 return false;3436 if (response.GetChar() != ',')3437 return false;3438 bool retcode = (response.GetChar() != '0');3439 return retcode;3440 } else3441 m_supports_vFileExists = false;3442 }3443 3444 // Fallback to open.3445 Status error;3446 lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error);3447 if (fd == UINT64_MAX)3448 return false;3449 CloseFile(fd, error);3450 return true;3451}3452 3453llvm::ErrorOr<llvm::MD5::MD5Result> GDBRemoteCommunicationClient::CalculateMD5(3454 const lldb_private::FileSpec &file_spec) {3455 std::string path(file_spec.GetPath(false));3456 lldb_private::StreamString stream;3457 stream.PutCString("vFile:MD5:");3458 stream.PutStringAsRawHex8(path);3459 StringExtractorGDBRemote response;3460 if (SendPacketAndWaitForResponse(stream.GetString(), response) ==3461 PacketResult::Success) {3462 if (response.GetChar() != 'F')3463 return std::make_error_code(std::errc::illegal_byte_sequence);3464 if (response.GetChar() != ',')3465 return std::make_error_code(std::errc::illegal_byte_sequence);3466 if (response.Peek() && *response.Peek() == 'x')3467 return std::make_error_code(std::errc::no_such_file_or_directory);3468 3469 // GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 concatenates low and3470 // high hex strings. We can't use response.GetHexMaxU64 because that can't3471 // handle the concatenated hex string. What would happen is parsing the low3472 // would consume the whole response packet which would give incorrect3473 // results. Instead, we get the byte string for each low and high hex3474 // separately, and parse them.3475 //3476 // An alternate way to handle this is to change the server to put a3477 // delimiter between the low/high parts, and change the client to parse the3478 // delimiter. However, we choose not to do this so existing lldb-servers3479 // don't have to be patched3480 3481 // The checksum is 128 bits encoded as hex3482 // This means low/high are halves of 64 bits each, in otherwords, 8 bytes.3483 // Each byte takes 2 hex characters in the response.3484 const size_t MD5_HALF_LENGTH = sizeof(uint64_t) * 2;3485 3486 // Get low part3487 auto part =3488 response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);3489 if (part.size() != MD5_HALF_LENGTH)3490 return std::make_error_code(std::errc::illegal_byte_sequence);3491 response.SetFilePos(response.GetFilePos() + part.size());3492 3493 uint64_t low;3494 if (part.getAsInteger(/*radix=*/16, low))3495 return std::make_error_code(std::errc::illegal_byte_sequence);3496 3497 // Get high part3498 part =3499 response.GetStringRef().substr(response.GetFilePos(), MD5_HALF_LENGTH);3500 if (part.size() != MD5_HALF_LENGTH)3501 return std::make_error_code(std::errc::illegal_byte_sequence);3502 response.SetFilePos(response.GetFilePos() + part.size());3503 3504 uint64_t high;3505 if (part.getAsInteger(/*radix=*/16, high))3506 return std::make_error_code(std::errc::illegal_byte_sequence);3507 3508 llvm::MD5::MD5Result result;3509 llvm::support::endian::write<uint64_t, llvm::endianness::little>(3510 result.data(), low);3511 llvm::support::endian::write<uint64_t, llvm::endianness::little>(3512 result.data() + 8, high);3513 3514 return result;3515 }3516 return std::make_error_code(std::errc::operation_canceled);3517}3518 3519bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {3520 // Some targets have issues with g/G packets and we need to avoid using them3521 if (m_avoid_g_packets == eLazyBoolCalculate) {3522 if (process) {3523 m_avoid_g_packets = eLazyBoolNo;3524 const ArchSpec &arch = process->GetTarget().GetArchitecture();3525 if (arch.IsValid() &&3526 arch.GetTriple().getVendor() == llvm::Triple::Apple &&3527 arch.GetTriple().getOS() == llvm::Triple::IOS &&3528 (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||3529 arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {3530 m_avoid_g_packets = eLazyBoolYes;3531 uint32_t gdb_server_version = GetGDBServerProgramVersion();3532 if (gdb_server_version != 0) {3533 const char *gdb_server_name = GetGDBServerProgramName();3534 if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {3535 if (gdb_server_version >= 310)3536 m_avoid_g_packets = eLazyBoolNo;3537 }3538 }3539 }3540 }3541 }3542 return m_avoid_g_packets == eLazyBoolYes;3543}3544 3545DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,3546 uint32_t reg) {3547 StreamString payload;3548 payload.Printf("p%x", reg);3549 StringExtractorGDBRemote response;3550 if (SendThreadSpecificPacketAndWaitForResponse(3551 tid, std::move(payload), response) != PacketResult::Success ||3552 !response.IsNormalResponse())3553 return nullptr;3554 3555 WritableDataBufferSP buffer_sp(3556 new DataBufferHeap(response.GetStringRef().size() / 2, 0));3557 response.GetHexBytes(buffer_sp->GetData(), '\xcc');3558 return buffer_sp;3559}3560 3561DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {3562 StreamString payload;3563 payload.PutChar('g');3564 StringExtractorGDBRemote response;3565 if (SendThreadSpecificPacketAndWaitForResponse(3566 tid, std::move(payload), response) != PacketResult::Success ||3567 !response.IsNormalResponse())3568 return nullptr;3569 3570 WritableDataBufferSP buffer_sp(3571 new DataBufferHeap(response.GetStringRef().size() / 2, 0));3572 response.GetHexBytes(buffer_sp->GetData(), '\xcc');3573 return buffer_sp;3574}3575 3576bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,3577 uint32_t reg_num,3578 llvm::ArrayRef<uint8_t> data) {3579 StreamString payload;3580 payload.Printf("P%x=", reg_num);3581 payload.PutBytesAsRawHex8(data.data(), data.size(),3582 endian::InlHostByteOrder(),3583 endian::InlHostByteOrder());3584 StringExtractorGDBRemote response;3585 return SendThreadSpecificPacketAndWaitForResponse(3586 tid, std::move(payload), response) == PacketResult::Success &&3587 response.IsOKResponse();3588}3589 3590bool GDBRemoteCommunicationClient::WriteAllRegisters(3591 lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {3592 StreamString payload;3593 payload.PutChar('G');3594 payload.PutBytesAsRawHex8(data.data(), data.size(),3595 endian::InlHostByteOrder(),3596 endian::InlHostByteOrder());3597 StringExtractorGDBRemote response;3598 return SendThreadSpecificPacketAndWaitForResponse(3599 tid, std::move(payload), response) == PacketResult::Success &&3600 response.IsOKResponse();3601}3602 3603bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,3604 uint32_t &save_id) {3605 save_id = 0; // Set to invalid save ID3606 if (m_supports_QSaveRegisterState == eLazyBoolNo)3607 return false;3608 3609 m_supports_QSaveRegisterState = eLazyBoolYes;3610 StreamString payload;3611 payload.PutCString("QSaveRegisterState");3612 StringExtractorGDBRemote response;3613 if (SendThreadSpecificPacketAndWaitForResponse(3614 tid, std::move(payload), response) != PacketResult::Success)3615 return false;3616 3617 if (response.IsUnsupportedResponse())3618 m_supports_QSaveRegisterState = eLazyBoolNo;3619 3620 const uint32_t response_save_id = response.GetU32(0);3621 if (response_save_id == 0)3622 return false;3623 3624 save_id = response_save_id;3625 return true;3626}3627 3628bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,3629 uint32_t save_id) {3630 // We use the "m_supports_QSaveRegisterState" variable here because the3631 // QSaveRegisterState and QRestoreRegisterState packets must both be3632 // supported in order to be useful3633 if (m_supports_QSaveRegisterState == eLazyBoolNo)3634 return false;3635 3636 StreamString payload;3637 payload.Printf("QRestoreRegisterState:%u", save_id);3638 StringExtractorGDBRemote response;3639 if (SendThreadSpecificPacketAndWaitForResponse(3640 tid, std::move(payload), response) != PacketResult::Success)3641 return false;3642 3643 if (response.IsOKResponse())3644 return true;3645 3646 if (response.IsUnsupportedResponse())3647 m_supports_QSaveRegisterState = eLazyBoolNo;3648 return false;3649}3650 3651bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {3652 if (!GetSyncThreadStateSupported())3653 return false;3654 3655 StreamString packet;3656 StringExtractorGDBRemote response;3657 packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);3658 return SendPacketAndWaitForResponse(packet.GetString(), response) ==3659 GDBRemoteCommunication::PacketResult::Success &&3660 response.IsOKResponse();3661}3662 3663llvm::Expected<TraceSupportedResponse>3664GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {3665 Log *log = GetLog(GDBRLog::Process);3666 3667 StreamGDBRemote escaped_packet;3668 escaped_packet.PutCString("jLLDBTraceSupported");3669 3670 StringExtractorGDBRemote response;3671 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3672 timeout) ==3673 GDBRemoteCommunication::PacketResult::Success) {3674 if (response.IsErrorResponse())3675 return response.GetStatus().ToError();3676 if (response.IsUnsupportedResponse())3677 return llvm::createStringError(llvm::inconvertibleErrorCode(),3678 "jLLDBTraceSupported is unsupported");3679 3680 return llvm::json::parse<TraceSupportedResponse>(response.Peek(),3681 "TraceSupportedResponse");3682 }3683 LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");3684 return llvm::createStringError(llvm::inconvertibleErrorCode(),3685 "failed to send packet: jLLDBTraceSupported");3686}3687 3688llvm::Error3689GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,3690 std::chrono::seconds timeout) {3691 Log *log = GetLog(GDBRLog::Process);3692 3693 StreamGDBRemote escaped_packet;3694 escaped_packet.PutCString("jLLDBTraceStop:");3695 3696 std::string json_string;3697 llvm::raw_string_ostream os(json_string);3698 os << toJSON(request);3699 3700 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());3701 3702 StringExtractorGDBRemote response;3703 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3704 timeout) ==3705 GDBRemoteCommunication::PacketResult::Success) {3706 if (response.IsErrorResponse())3707 return response.GetStatus().ToError();3708 if (response.IsUnsupportedResponse())3709 return llvm::createStringError(llvm::inconvertibleErrorCode(),3710 "jLLDBTraceStop is unsupported");3711 if (response.IsOKResponse())3712 return llvm::Error::success();3713 return llvm::createStringError(llvm::inconvertibleErrorCode(),3714 "Invalid jLLDBTraceStart response");3715 }3716 LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");3717 return llvm::createStringError(llvm::inconvertibleErrorCode(),3718 "failed to send packet: jLLDBTraceStop '%s'",3719 escaped_packet.GetData());3720}3721 3722llvm::Error3723GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value ¶ms,3724 std::chrono::seconds timeout) {3725 Log *log = GetLog(GDBRLog::Process);3726 3727 StreamGDBRemote escaped_packet;3728 escaped_packet.PutCString("jLLDBTraceStart:");3729 3730 std::string json_string;3731 llvm::raw_string_ostream os(json_string);3732 os << params;3733 3734 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());3735 3736 StringExtractorGDBRemote response;3737 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3738 timeout) ==3739 GDBRemoteCommunication::PacketResult::Success) {3740 if (response.IsErrorResponse())3741 return response.GetStatus().ToError();3742 if (response.IsUnsupportedResponse())3743 return llvm::createStringError(llvm::inconvertibleErrorCode(),3744 "jLLDBTraceStart is unsupported");3745 if (response.IsOKResponse())3746 return llvm::Error::success();3747 return llvm::createStringError(llvm::inconvertibleErrorCode(),3748 "Invalid jLLDBTraceStart response");3749 }3750 LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");3751 return llvm::createStringError(llvm::inconvertibleErrorCode(),3752 "failed to send packet: jLLDBTraceStart '%s'",3753 escaped_packet.GetData());3754}3755 3756llvm::Expected<std::string>3757GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,3758 std::chrono::seconds timeout) {3759 Log *log = GetLog(GDBRLog::Process);3760 3761 StreamGDBRemote escaped_packet;3762 escaped_packet.PutCString("jLLDBTraceGetState:");3763 3764 std::string json_string;3765 llvm::raw_string_ostream os(json_string);3766 os << toJSON(TraceGetStateRequest{type.str()});3767 3768 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());3769 3770 StringExtractorGDBRemote response;3771 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3772 timeout) ==3773 GDBRemoteCommunication::PacketResult::Success) {3774 if (response.IsErrorResponse())3775 return response.GetStatus().ToError();3776 if (response.IsUnsupportedResponse())3777 return llvm::createStringError(llvm::inconvertibleErrorCode(),3778 "jLLDBTraceGetState is unsupported");3779 return std::string(response.Peek());3780 }3781 3782 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");3783 return llvm::createStringError(3784 llvm::inconvertibleErrorCode(),3785 "failed to send packet: jLLDBTraceGetState '%s'",3786 escaped_packet.GetData());3787}3788 3789llvm::Expected<std::vector<uint8_t>>3790GDBRemoteCommunicationClient::SendTraceGetBinaryData(3791 const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {3792 Log *log = GetLog(GDBRLog::Process);3793 3794 StreamGDBRemote escaped_packet;3795 escaped_packet.PutCString("jLLDBTraceGetBinaryData:");3796 3797 std::string json_string;3798 llvm::raw_string_ostream os(json_string);3799 os << toJSON(request);3800 3801 escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());3802 3803 StringExtractorGDBRemote response;3804 if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,3805 timeout) ==3806 GDBRemoteCommunication::PacketResult::Success) {3807 if (response.IsErrorResponse())3808 return response.GetStatus().ToError();3809 std::string data;3810 response.GetEscapedBinaryData(data);3811 return std::vector<uint8_t>(data.begin(), data.end());3812 }3813 LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");3814 return llvm::createStringError(3815 llvm::inconvertibleErrorCode(),3816 "failed to send packet: jLLDBTraceGetBinaryData '%s'",3817 escaped_packet.GetData());3818}3819 3820std::optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {3821 StringExtractorGDBRemote response;3822 if (SendPacketAndWaitForResponse("qOffsets", response) !=3823 PacketResult::Success)3824 return std::nullopt;3825 if (!response.IsNormalResponse())3826 return std::nullopt;3827 3828 QOffsets result;3829 llvm::StringRef ref = response.GetStringRef();3830 const auto &GetOffset = [&] {3831 addr_t offset;3832 if (ref.consumeInteger(16, offset))3833 return false;3834 result.offsets.push_back(offset);3835 return true;3836 };3837 3838 if (ref.consume_front("Text=")) {3839 result.segments = false;3840 if (!GetOffset())3841 return std::nullopt;3842 if (!ref.consume_front(";Data=") || !GetOffset())3843 return std::nullopt;3844 if (ref.empty())3845 return result;3846 if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())3847 return result;3848 } else if (ref.consume_front("TextSeg=")) {3849 result.segments = true;3850 if (!GetOffset())3851 return std::nullopt;3852 if (ref.empty())3853 return result;3854 if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())3855 return result;3856 }3857 return std::nullopt;3858}3859 3860bool GDBRemoteCommunicationClient::GetModuleInfo(3861 const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,3862 ModuleSpec &module_spec) {3863 if (!m_supports_qModuleInfo)3864 return false;3865 3866 std::string module_path = module_file_spec.GetPath(false);3867 if (module_path.empty())3868 return false;3869 3870 StreamString packet;3871 packet.PutCString("qModuleInfo:");3872 packet.PutStringAsRawHex8(module_path);3873 packet.PutCString(";");3874 const auto &triple = arch_spec.GetTriple().getTriple();3875 packet.PutStringAsRawHex8(triple);3876 3877 StringExtractorGDBRemote response;3878 if (SendPacketAndWaitForResponse(packet.GetString(), response) !=3879 PacketResult::Success)3880 return false;3881 3882 if (response.IsErrorResponse())3883 return false;3884 3885 if (response.IsUnsupportedResponse()) {3886 m_supports_qModuleInfo = false;3887 return false;3888 }3889 3890 llvm::StringRef name;3891 llvm::StringRef value;3892 3893 module_spec.Clear();3894 module_spec.GetFileSpec() = module_file_spec;3895 3896 while (response.GetNameColonValue(name, value)) {3897 if (name == "uuid" || name == "md5") {3898 StringExtractor extractor(value);3899 std::string uuid;3900 extractor.GetHexByteString(uuid);3901 module_spec.GetUUID().SetFromStringRef(uuid);3902 } else if (name == "triple") {3903 StringExtractor extractor(value);3904 std::string triple;3905 extractor.GetHexByteString(triple);3906 module_spec.GetArchitecture().SetTriple(triple.c_str());3907 } else if (name == "file_offset") {3908 uint64_t ival = 0;3909 if (!value.getAsInteger(16, ival))3910 module_spec.SetObjectOffset(ival);3911 } else if (name == "file_size") {3912 uint64_t ival = 0;3913 if (!value.getAsInteger(16, ival))3914 module_spec.SetObjectSize(ival);3915 } else if (name == "file_path") {3916 StringExtractor extractor(value);3917 std::string path;3918 extractor.GetHexByteString(path);3919 module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());3920 }3921 }3922 3923 return true;3924}3925 3926static std::optional<ModuleSpec>3927ParseModuleSpec(StructuredData::Dictionary *dict) {3928 ModuleSpec result;3929 if (!dict)3930 return std::nullopt;3931 3932 llvm::StringRef string;3933 uint64_t integer;3934 3935 if (!dict->GetValueForKeyAsString("uuid", string))3936 return std::nullopt;3937 if (!result.GetUUID().SetFromStringRef(string))3938 return std::nullopt;3939 3940 if (!dict->GetValueForKeyAsInteger("file_offset", integer))3941 return std::nullopt;3942 result.SetObjectOffset(integer);3943 3944 if (!dict->GetValueForKeyAsInteger("file_size", integer))3945 return std::nullopt;3946 result.SetObjectSize(integer);3947 3948 if (!dict->GetValueForKeyAsString("triple", string))3949 return std::nullopt;3950 result.GetArchitecture().SetTriple(string);3951 3952 if (!dict->GetValueForKeyAsString("file_path", string))3953 return std::nullopt;3954 result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());3955 3956 return result;3957}3958 3959std::optional<std::vector<ModuleSpec>>3960GDBRemoteCommunicationClient::GetModulesInfo(3961 llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {3962 namespace json = llvm::json;3963 3964 if (!m_supports_jModulesInfo)3965 return std::nullopt;3966 3967 json::Array module_array;3968 for (const FileSpec &module_file_spec : module_file_specs) {3969 module_array.push_back(3970 json::Object{{"file", module_file_spec.GetPath(false)},3971 {"triple", triple.getTriple()}});3972 }3973 StreamString unescaped_payload;3974 unescaped_payload.PutCString("jModulesInfo:");3975 unescaped_payload.AsRawOstream() << std::move(module_array);3976 3977 StreamGDBRemote payload;3978 payload.PutEscapedBytes(unescaped_payload.GetString().data(),3979 unescaped_payload.GetSize());3980 3981 // Increase the timeout for jModulesInfo since this packet can take longer.3982 ScopedTimeout timeout(*this, std::chrono::seconds(10));3983 3984 StringExtractorGDBRemote response;3985 if (SendPacketAndWaitForResponse(payload.GetString(), response) !=3986 PacketResult::Success ||3987 response.IsErrorResponse())3988 return std::nullopt;3989 3990 if (response.IsUnsupportedResponse()) {3991 m_supports_jModulesInfo = false;3992 return std::nullopt;3993 }3994 3995 StructuredData::ObjectSP response_object_sp =3996 StructuredData::ParseJSON(response.GetStringRef());3997 if (!response_object_sp)3998 return std::nullopt;3999 4000 StructuredData::Array *response_array = response_object_sp->GetAsArray();4001 if (!response_array)4002 return std::nullopt;4003 4004 std::vector<ModuleSpec> result;4005 for (size_t i = 0; i < response_array->GetSize(); ++i) {4006 if (std::optional<ModuleSpec> module_spec = ParseModuleSpec(4007 response_array->GetItemAtIndex(i)->GetAsDictionary()))4008 result.push_back(*module_spec);4009 }4010 4011 return result;4012}4013 4014// query the target remote for extended information using the qXfer packet4015//4016// example: object='features', annex='target.xml'4017// return: <xml output> or error4018llvm::Expected<std::string>4019GDBRemoteCommunicationClient::ReadExtFeature(llvm::StringRef object,4020 llvm::StringRef annex) {4021 4022 std::string output;4023 llvm::raw_string_ostream output_stream(output);4024 StringExtractorGDBRemote chunk;4025 4026 uint64_t size = GetRemoteMaxPacketSize();4027 if (size == 0)4028 size = 0x1000;4029 size = size - 1; // Leave space for the 'm' or 'l' character in the response4030 int offset = 0;4031 bool active = true;4032 4033 // loop until all data has been read4034 while (active) {4035 4036 // send query extended feature packet4037 std::string packet =4038 ("qXfer:" + object + ":read:" + annex + ":" +4039 llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size))4040 .str();4041 4042 GDBRemoteCommunication::PacketResult res =4043 SendPacketAndWaitForResponse(packet, chunk);4044 4045 if (res != GDBRemoteCommunication::PacketResult::Success ||4046 chunk.GetStringRef().empty()) {4047 return llvm::createStringError(llvm::inconvertibleErrorCode(),4048 "Error sending $qXfer packet");4049 }4050 4051 // check packet code4052 switch (chunk.GetStringRef()[0]) {4053 // last chunk4054 case ('l'):4055 active = false;4056 [[fallthrough]];4057 4058 // more chunks4059 case ('m'):4060 output_stream << chunk.GetStringRef().drop_front();4061 offset += chunk.GetStringRef().size() - 1;4062 break;4063 4064 // unknown chunk4065 default:4066 return llvm::createStringError(4067 llvm::inconvertibleErrorCode(),4068 "Invalid continuation code from $qXfer packet");4069 }4070 }4071 4072 return output;4073}4074 4075// Notify the target that gdb is prepared to serve symbol lookup requests.4076// packet: "qSymbol::"4077// reply:4078// OK The target does not need to look up any (more) symbols.4079// qSymbol:<sym_name> The target requests the value of symbol sym_name (hex4080// encoded).4081// LLDB may provide the value by sending another qSymbol4082// packet4083// in the form of"qSymbol:<sym_value>:<sym_name>".4084//4085// Three examples:4086//4087// lldb sends: qSymbol::4088// lldb receives: OK4089// Remote gdb stub does not need to know the addresses of any symbols, lldb4090// does not4091// need to ask again in this session.4092//4093// lldb sends: qSymbol::4094// lldb receives: qSymbol:64697370617463685f71756575655f6f6666736574734095// lldb sends: qSymbol::64697370617463685f71756575655f6f6666736574734096// lldb receives: OK4097// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb does4098// not know4099// the address at this time. lldb needs to send qSymbol:: again when it has4100// more4101// solibs loaded.4102//4103// lldb sends: qSymbol::4104// lldb receives: qSymbol:64697370617463685f71756575655f6f6666736574734105// lldb sends: qSymbol:2bc97554:64697370617463685f71756575655f6f6666736574734106// lldb receives: OK4107// Remote gdb stub asks for address of 'dispatch_queue_offsets'. lldb says4108// that it4109// is at address 0x2bc97554. Remote gdb stub sends 'OK' indicating that it4110// does not4111// need any more symbols. lldb does not need to ask again in this session.4112 4113void GDBRemoteCommunicationClient::ServeSymbolLookups(4114 lldb_private::Process *process) {4115 // Set to true once we've resolved a symbol to an address for the remote4116 // stub. If we get an 'OK' response after this, the remote stub doesn't need4117 // any more symbols and we can stop asking.4118 bool symbol_response_provided = false;4119 4120 // Is this the initial qSymbol:: packet?4121 bool first_qsymbol_query = true;4122 4123 if (m_supports_qSymbol && !m_qSymbol_requests_done) {4124 Lock lock(*this);4125 if (lock) {4126 StreamString packet;4127 packet.PutCString("qSymbol::");4128 StringExtractorGDBRemote response;4129 while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==4130 PacketResult::Success) {4131 if (response.IsOKResponse()) {4132 if (symbol_response_provided || first_qsymbol_query) {4133 m_qSymbol_requests_done = true;4134 }4135 4136 // We are done serving symbols requests4137 return;4138 }4139 first_qsymbol_query = false;4140 4141 if (response.IsUnsupportedResponse()) {4142 // qSymbol is not supported by the current GDB server we are4143 // connected to4144 m_supports_qSymbol = false;4145 return;4146 } else {4147 llvm::StringRef response_str(response.GetStringRef());4148 if (response_str.starts_with("qSymbol:")) {4149 response.SetFilePos(strlen("qSymbol:"));4150 std::string symbol_name;4151 if (response.GetHexByteString(symbol_name)) {4152 if (symbol_name.empty())4153 return;4154 4155 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;4156 lldb_private::SymbolContextList sc_list;4157 process->GetTarget().GetImages().FindSymbolsWithNameAndType(4158 ConstString(symbol_name), eSymbolTypeAny, sc_list);4159 for (const SymbolContext &sc : sc_list) {4160 if (symbol_load_addr != LLDB_INVALID_ADDRESS)4161 break;4162 if (sc.symbol) {4163 switch (sc.symbol->GetType()) {4164 case eSymbolTypeInvalid:4165 case eSymbolTypeAbsolute:4166 case eSymbolTypeUndefined:4167 case eSymbolTypeSourceFile:4168 case eSymbolTypeHeaderFile:4169 case eSymbolTypeObjectFile:4170 case eSymbolTypeCommonBlock:4171 case eSymbolTypeBlock:4172 case eSymbolTypeLocal:4173 case eSymbolTypeParam:4174 case eSymbolTypeVariable:4175 case eSymbolTypeVariableType:4176 case eSymbolTypeLineEntry:4177 case eSymbolTypeLineHeader:4178 case eSymbolTypeScopeBegin:4179 case eSymbolTypeScopeEnd:4180 case eSymbolTypeAdditional:4181 case eSymbolTypeCompiler:4182 case eSymbolTypeInstrumentation:4183 case eSymbolTypeTrampoline:4184 break;4185 4186 case eSymbolTypeCode:4187 case eSymbolTypeResolver:4188 case eSymbolTypeData:4189 case eSymbolTypeRuntime:4190 case eSymbolTypeException:4191 case eSymbolTypeObjCClass:4192 case eSymbolTypeObjCMetaClass:4193 case eSymbolTypeObjCIVar:4194 case eSymbolTypeReExported:4195 symbol_load_addr =4196 sc.symbol->GetLoadAddress(&process->GetTarget());4197 break;4198 }4199 }4200 }4201 // This is the normal path where our symbol lookup was successful4202 // and we want to send a packet with the new symbol value and see4203 // if another lookup needs to be done.4204 4205 // Change "packet" to contain the requested symbol value and name4206 packet.Clear();4207 packet.PutCString("qSymbol:");4208 if (symbol_load_addr != LLDB_INVALID_ADDRESS) {4209 packet.Printf("%" PRIx64, symbol_load_addr);4210 symbol_response_provided = true;4211 } else {4212 symbol_response_provided = false;4213 }4214 packet.PutCString(":");4215 packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());4216 continue; // go back to the while loop and send "packet" and wait4217 // for another response4218 }4219 }4220 }4221 }4222 // If we make it here, the symbol request packet response wasn't valid or4223 // our symbol lookup failed so we must abort4224 return;4225 4226 } else if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets)) {4227 LLDB_LOGF(log,4228 "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",4229 __FUNCTION__);4230 }4231 }4232}4233 4234StructuredData::Array *4235GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {4236 if (!m_supported_async_json_packets_is_valid) {4237 // Query the server for the array of supported asynchronous JSON packets.4238 m_supported_async_json_packets_is_valid = true;4239 4240 Log *log = GetLog(GDBRLog::Process);4241 4242 // Poll it now.4243 StringExtractorGDBRemote response;4244 if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==4245 PacketResult::Success) {4246 m_supported_async_json_packets_sp =4247 StructuredData::ParseJSON(response.GetStringRef());4248 if (m_supported_async_json_packets_sp &&4249 !m_supported_async_json_packets_sp->GetAsArray()) {4250 // We were returned something other than a JSON array. This is4251 // invalid. Clear it out.4252 LLDB_LOGF(log,4253 "GDBRemoteCommunicationClient::%s(): "4254 "QSupportedAsyncJSONPackets returned invalid "4255 "result: %s",4256 __FUNCTION__, response.GetStringRef().data());4257 m_supported_async_json_packets_sp.reset();4258 }4259 } else {4260 LLDB_LOGF(log,4261 "GDBRemoteCommunicationClient::%s(): "4262 "QSupportedAsyncJSONPackets unsupported",4263 __FUNCTION__);4264 }4265 4266 if (log && m_supported_async_json_packets_sp) {4267 StreamString stream;4268 m_supported_async_json_packets_sp->Dump(stream);4269 LLDB_LOGF(log,4270 "GDBRemoteCommunicationClient::%s(): supported async "4271 "JSON packets: %s",4272 __FUNCTION__, stream.GetData());4273 }4274 }4275 4276 return m_supported_async_json_packets_sp4277 ? m_supported_async_json_packets_sp->GetAsArray()4278 : nullptr;4279}4280 4281Status GDBRemoteCommunicationClient::SendSignalsToIgnore(4282 llvm::ArrayRef<int32_t> signals) {4283 // Format packet:4284 // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>4285 auto range = llvm::make_range(signals.begin(), signals.end());4286 std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();4287 4288 StringExtractorGDBRemote response;4289 auto send_status = SendPacketAndWaitForResponse(packet, response);4290 4291 if (send_status != GDBRemoteCommunication::PacketResult::Success)4292 return Status::FromErrorString("Sending QPassSignals packet failed");4293 4294 if (response.IsOKResponse()) {4295 return Status();4296 } else {4297 return Status::FromErrorString(4298 "Unknown error happened during sending QPassSignals packet.");4299 }4300}4301 4302Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(4303 llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) {4304 Status error;4305 4306 if (type_name.empty()) {4307 error = Status::FromErrorString("invalid type_name argument");4308 return error;4309 }4310 4311 // Build command: Configure{type_name}: serialized config data.4312 StreamGDBRemote stream;4313 stream.PutCString("QConfigure");4314 stream.PutCString(type_name);4315 stream.PutChar(':');4316 if (config_sp) {4317 // Gather the plain-text version of the configuration data.4318 StreamString unescaped_stream;4319 config_sp->Dump(unescaped_stream);4320 unescaped_stream.Flush();4321 4322 // Add it to the stream in escaped fashion.4323 stream.PutEscapedBytes(unescaped_stream.GetString().data(),4324 unescaped_stream.GetSize());4325 }4326 stream.Flush();4327 4328 // Send the packet.4329 StringExtractorGDBRemote response;4330 auto result = SendPacketAndWaitForResponse(stream.GetString(), response);4331 if (result == PacketResult::Success) {4332 // We failed if the config result comes back other than OK.4333 if (response.GetStringRef() == "OK") {4334 // Okay!4335 error.Clear();4336 } else {4337 error = Status::FromErrorStringWithFormatv(4338 "configuring StructuredData feature {0} failed with error {1}",4339 type_name, response.GetStringRef());4340 }4341 } else {4342 // Can we get more data here on the failure?4343 error = Status::FromErrorStringWithFormatv(4344 "configuring StructuredData feature {0} failed when sending packet: "4345 "PacketResult={1}",4346 type_name, (int)result);4347 }4348 return error;4349}4350 4351void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {4352 GDBRemoteClientBase::OnRunPacketSent(first);4353 m_curr_tid = LLDB_INVALID_THREAD_ID;4354}4355 4356bool GDBRemoteCommunicationClient::UsesNativeSignals() {4357 if (m_uses_native_signals == eLazyBoolCalculate)4358 GetRemoteQSupported();4359 if (m_uses_native_signals == eLazyBoolYes)4360 return true;4361 4362 // If the remote didn't indicate native-signal support explicitly,4363 // check whether it is an old version of lldb-server.4364 return GetThreadSuffixSupported();4365}4366 4367llvm::Expected<int> GDBRemoteCommunicationClient::KillProcess(lldb::pid_t pid) {4368 StringExtractorGDBRemote response;4369 GDBRemoteCommunication::ScopedTimeout(*this, seconds(3));4370 4371 // LLDB server typically sends no response for "k", so we shouldn't try4372 // to sync on timeout.4373 if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout(), false) !=4374 PacketResult::Success)4375 return llvm::createStringError(llvm::inconvertibleErrorCode(),4376 "failed to send k packet");4377 4378 char packet_cmd = response.GetChar(0);4379 if (packet_cmd == 'W' || packet_cmd == 'X')4380 return response.GetHexU8();4381 4382 return llvm::createStringError(llvm::inconvertibleErrorCode(),4383 "unexpected response to k packet: %s",4384 response.GetStringRef().str().c_str());4385}4386