brintos

brintos / llvm-project-archived public Read only

0
0
Text · 152.3 KiB · 11f164c Raw
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 &region_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 &region) {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          [&region](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 &params,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