//===-- GDBRemoteCommunicationClient.cpp ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "GDBRemoteCommunicationClient.h"

#include <cmath>
#include <sys/stat.h>

#include <numeric>
#include <optional>
#include <sstream>

#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/XML.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
#include "lldb/Utility/StreamString.h"

#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
#include "lldb/Host/Config.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"

#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/JSON.h"

#if defined(HAVE_LIBCOMPRESSION)
#include <compression.h>
#endif

using namespace lldb;
using namespace lldb_private::process_gdb_remote;
using namespace lldb_private;
using namespace std::chrono;

llvm::raw_ostream &process_gdb_remote::operator<<(llvm::raw_ostream &os,
                                                  const QOffsets &offsets) {
  return os << llvm::formatv(
             "QOffsets({0}, [{1:@[x]}])", offsets.segments,
             llvm::make_range(offsets.offsets.begin(), offsets.offsets.end()));
}

// GDBRemoteCommunicationClient constructor
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
    : GDBRemoteClientBase("gdb-remote.client"),

      m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
      m_supports_qUserName(true), m_supports_qGroupName(true),
      m_supports_qThreadStopInfo(true), m_supports_z0(true),
      m_supports_z1(true), m_supports_z2(true), m_supports_z3(true),
      m_supports_z4(true), m_supports_QEnvironment(true),
      m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true),
      m_qSymbol_requests_done(false), m_supports_qModuleInfo(true),
      m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
      m_supports_vFileSize(true), m_supports_vFileMode(true),
      m_supports_vFileExists(true), m_supports_vRun(true),

      m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(),
      m_os_kernel(), m_hostname(), m_gdb_server_name(),
      m_default_packet_timeout(0), m_qSupported_response(),
      m_supported_async_json_packets_sp(), m_qXfer_memory_map() {}

// Destructor
GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
  if (IsConnected())
    Disconnect();
}

bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) {
  ResetDiscoverableSettings(false);

  // Start the read thread after we send the handshake ack since if we fail to
  // send the handshake ack, there is no reason to continue...
  std::chrono::steady_clock::time_point start_of_handshake =
      std::chrono::steady_clock::now();
  if (SendAck()) {
    // The return value from QueryNoAckModeSupported() is true if the packet
    // was sent and _any_ response (including UNIMPLEMENTED) was received), or
    // false if no response was received. This quickly tells us if we have a
    // live connection to a remote GDB server...
    if (QueryNoAckModeSupported()) {
      return true;
    } else {
      std::chrono::steady_clock::time_point end_of_handshake =
          std::chrono::steady_clock::now();
      auto handshake_timeout =
          std::chrono::duration<double>(end_of_handshake - start_of_handshake)
              .count();
      if (error_ptr) {
        if (!IsConnected())
          error_ptr->SetErrorString("Connection shut down by remote side "
                                    "while waiting for reply to initial "
                                    "handshake packet");
        else
          error_ptr->SetErrorStringWithFormat(
              "failed to get reply to handshake packet within timeout of "
              "%.1f seconds",
              handshake_timeout);
      }
    }
  } else {
    if (error_ptr)
      error_ptr->SetErrorString("failed to send the handshake ack");
  }
  return false;
}

bool GDBRemoteCommunicationClient::GetEchoSupported() {
  if (m_supports_qEcho == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qEcho == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
  if (m_supports_QPassSignals == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_QPassSignals == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
  if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
  if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
  if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qXfer_libraries_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
  if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qXfer_auxv_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
  if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qXfer_features_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQXferMemoryMapReadSupported() {
  if (m_supports_qXfer_memory_map_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qXfer_memory_map_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {
  if (m_supports_qXfer_siginfo_read == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_qXfer_siginfo_read == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {
  if (m_supports_memory_tagging == eLazyBoolCalculate)
    GetRemoteQSupported();
  return m_supports_multiprocess == eLazyBoolYes;
}

uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
  if (m_max_packet_size == 0) {
    GetRemoteQSupported();
  }
  return m_max_packet_size;
}

bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
  if (m_supports_not_sending_acks == eLazyBoolCalculate) {
    m_send_acks = true;
    m_supports_not_sending_acks = eLazyBoolNo;

    // This is the first real packet that we'll send in a debug session and it
    // may take a little longer than normal to receive a reply.  Wait at least
    // 6 seconds for a reply to this packet.

    ScopedTimeout timeout(*this, std::max(GetPacketTimeout(), seconds(6)));

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("QStartNoAckMode", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse()) {
        m_send_acks = false;
        m_supports_not_sending_acks = eLazyBoolYes;
      }
      return true;
    }
  }
  return false;
}

void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
  if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
    m_supports_threads_in_stop_reply = eLazyBoolNo;

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        m_supports_threads_in_stop_reply = eLazyBoolYes;
    }
  }
}

bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
  if (m_attach_or_wait_reply == eLazyBoolCalculate) {
    m_attach_or_wait_reply = eLazyBoolNo;

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        m_attach_or_wait_reply = eLazyBoolYes;
    }
  }
  return m_attach_or_wait_reply == eLazyBoolYes;
}

bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
  if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
    m_prepare_for_reg_writing_reply = eLazyBoolNo;

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        m_prepare_for_reg_writing_reply = eLazyBoolYes;
    }
  }
  return m_prepare_for_reg_writing_reply == eLazyBoolYes;
}

void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
  if (!did_exec) {
    // Hard reset everything, this is when we first connect to a GDB server
    m_supports_not_sending_acks = eLazyBoolCalculate;
    m_supports_thread_suffix = eLazyBoolCalculate;
    m_supports_threads_in_stop_reply = eLazyBoolCalculate;
    m_supports_vCont_c = eLazyBoolCalculate;
    m_supports_vCont_C = eLazyBoolCalculate;
    m_supports_vCont_s = eLazyBoolCalculate;
    m_supports_vCont_S = eLazyBoolCalculate;
    m_supports_p = eLazyBoolCalculate;
    m_supports_x = eLazyBoolCalculate;
    m_supports_QSaveRegisterState = eLazyBoolCalculate;
    m_qHostInfo_is_valid = eLazyBoolCalculate;
    m_curr_pid_is_valid = eLazyBoolCalculate;
    m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
    m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
    m_supports_memory_region_info = eLazyBoolCalculate;
    m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
    m_attach_or_wait_reply = eLazyBoolCalculate;
    m_avoid_g_packets = eLazyBoolCalculate;
    m_supports_multiprocess = eLazyBoolCalculate;
    m_supports_qSaveCore = eLazyBoolCalculate;
    m_supports_qXfer_auxv_read = eLazyBoolCalculate;
    m_supports_qXfer_libraries_read = eLazyBoolCalculate;
    m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
    m_supports_qXfer_features_read = eLazyBoolCalculate;
    m_supports_qXfer_memory_map_read = eLazyBoolCalculate;
    m_supports_qXfer_siginfo_read = eLazyBoolCalculate;
    m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
    m_uses_native_signals = eLazyBoolCalculate;
    m_supports_qProcessInfoPID = true;
    m_supports_qfProcessInfo = true;
    m_supports_qUserName = true;
    m_supports_qGroupName = true;
    m_supports_qThreadStopInfo = true;
    m_supports_z0 = true;
    m_supports_z1 = true;
    m_supports_z2 = true;
    m_supports_z3 = true;
    m_supports_z4 = true;
    m_supports_QEnvironment = true;
    m_supports_QEnvironmentHexEncoded = true;
    m_supports_qSymbol = true;
    m_qSymbol_requests_done = false;
    m_supports_qModuleInfo = true;
    m_host_arch.Clear();
    m_host_distribution_id.clear();
    m_os_version = llvm::VersionTuple();
    m_os_build.clear();
    m_os_kernel.clear();
    m_hostname.clear();
    m_gdb_server_name.clear();
    m_gdb_server_version = UINT32_MAX;
    m_default_packet_timeout = seconds(0);
    m_target_vm_page_size = 0;
    m_max_packet_size = 0;
    m_qSupported_response.clear();
    m_supported_async_json_packets_is_valid = false;
    m_supported_async_json_packets_sp.reset();
    m_supports_jModulesInfo = true;
  }

  // These flags should be reset when we first connect to a GDB server and when
  // our inferior process execs
  m_qProcessInfo_is_valid = eLazyBoolCalculate;
  m_process_arch.Clear();
}

void GDBRemoteCommunicationClient::GetRemoteQSupported() {
  // Clear out any capabilities we expect to see in the qSupported response
  m_supports_qXfer_auxv_read = eLazyBoolNo;
  m_supports_qXfer_libraries_read = eLazyBoolNo;
  m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
  m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
  m_supports_qXfer_features_read = eLazyBoolNo;
  m_supports_qXfer_memory_map_read = eLazyBoolNo;
  m_supports_qXfer_siginfo_read = eLazyBoolNo;
  m_supports_multiprocess = eLazyBoolNo;
  m_supports_qEcho = eLazyBoolNo;
  m_supports_QPassSignals = eLazyBoolNo;
  m_supports_memory_tagging = eLazyBoolNo;
  m_supports_qSaveCore = eLazyBoolNo;
  m_uses_native_signals = eLazyBoolNo;

  m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
                                  // not, we assume no limit

  // build the qSupported packet
  std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc",
                                       "multiprocess+", "fork-events+",
                                       "vfork-events+"};
  StreamString packet;
  packet.PutCString("qSupported");
  for (uint32_t i = 0; i < features.size(); ++i) {
    packet.PutCString(i == 0 ? ":" : ";");
    packet.PutCString(features[i]);
  }

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
      PacketResult::Success) {
    // Hang on to the qSupported packet, so that platforms can do custom
    // configuration of the transport before attaching/launching the process.
    m_qSupported_response = response.GetStringRef().str();

    for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) {
      if (x == "qXfer:auxv:read+")
        m_supports_qXfer_auxv_read = eLazyBoolYes;
      else if (x == "qXfer:libraries-svr4:read+")
        m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
      else if (x == "augmented-libraries-svr4-read") {
        m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
        m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
      } else if (x == "qXfer:libraries:read+")
        m_supports_qXfer_libraries_read = eLazyBoolYes;
      else if (x == "qXfer:features:read+")
        m_supports_qXfer_features_read = eLazyBoolYes;
      else if (x == "qXfer:memory-map:read+")
        m_supports_qXfer_memory_map_read = eLazyBoolYes;
      else if (x == "qXfer:siginfo:read+")
        m_supports_qXfer_siginfo_read = eLazyBoolYes;
      else if (x == "qEcho")
        m_supports_qEcho = eLazyBoolYes;
      else if (x == "QPassSignals+")
        m_supports_QPassSignals = eLazyBoolYes;
      else if (x == "multiprocess+")
        m_supports_multiprocess = eLazyBoolYes;
      else if (x == "memory-tagging+")
        m_supports_memory_tagging = eLazyBoolYes;
      else if (x == "qSaveCore+")
        m_supports_qSaveCore = eLazyBoolYes;
      else if (x == "native-signals+")
        m_uses_native_signals = eLazyBoolYes;
      // Look for a list of compressions in the features list e.g.
      // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
      // deflate,lzma
      else if (x.consume_front("SupportedCompressions=")) {
        llvm::SmallVector<llvm::StringRef, 4> compressions;
        x.split(compressions, ',');
        if (!compressions.empty())
          MaybeEnableCompression(compressions);
      } else if (x.consume_front("PacketSize=")) {
        StringExtractorGDBRemote packet_response(x);
        m_max_packet_size =
            packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
        if (m_max_packet_size == 0) {
          m_max_packet_size = UINT64_MAX; // Must have been a garbled response
          Log *log(GetLog(GDBRLog::Process));
          LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
        }
      }
    }
  }
}

bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
  if (m_supports_thread_suffix == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_thread_suffix = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        m_supports_thread_suffix = eLazyBoolYes;
    }
  }
  return m_supports_thread_suffix;
}
bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
  if (m_supports_vCont_c == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_vCont_any = eLazyBoolNo;
    m_supports_vCont_all = eLazyBoolNo;
    m_supports_vCont_c = eLazyBoolNo;
    m_supports_vCont_C = eLazyBoolNo;
    m_supports_vCont_s = eLazyBoolNo;
    m_supports_vCont_S = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("vCont?", response) ==
        PacketResult::Success) {
      const char *response_cstr = response.GetStringRef().data();
      if (::strstr(response_cstr, ";c"))
        m_supports_vCont_c = eLazyBoolYes;

      if (::strstr(response_cstr, ";C"))
        m_supports_vCont_C = eLazyBoolYes;

      if (::strstr(response_cstr, ";s"))
        m_supports_vCont_s = eLazyBoolYes;

      if (::strstr(response_cstr, ";S"))
        m_supports_vCont_S = eLazyBoolYes;

      if (m_supports_vCont_c == eLazyBoolYes &&
          m_supports_vCont_C == eLazyBoolYes &&
          m_supports_vCont_s == eLazyBoolYes &&
          m_supports_vCont_S == eLazyBoolYes) {
        m_supports_vCont_all = eLazyBoolYes;
      }

      if (m_supports_vCont_c == eLazyBoolYes ||
          m_supports_vCont_C == eLazyBoolYes ||
          m_supports_vCont_s == eLazyBoolYes ||
          m_supports_vCont_S == eLazyBoolYes) {
        m_supports_vCont_any = eLazyBoolYes;
      }
    }
  }

  switch (flavor) {
  case 'a':
    return m_supports_vCont_any;
  case 'A':
    return m_supports_vCont_all;
  case 'c':
    return m_supports_vCont_c;
  case 'C':
    return m_supports_vCont_C;
  case 's':
    return m_supports_vCont_s;
  case 'S':
    return m_supports_vCont_S;
  default:
    break;
  }
  return false;
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
    lldb::tid_t tid, StreamString &&payload,
    StringExtractorGDBRemote &response) {
  Lock lock(*this);
  if (!lock) {
    if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets))
      LLDB_LOGF(log,
                "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
                "for %s packet.",
                __FUNCTION__, payload.GetData());
    return PacketResult::ErrorNoSequenceLock;
  }

  if (GetThreadSuffixSupported())
    payload.Printf(";thread:%4.4" PRIx64 ";", tid);
  else {
    if (!SetCurrentThread(tid))
      return PacketResult::ErrorSendFailed;
  }

  return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
}

// Check if the target supports 'p' packet. It sends out a 'p' packet and
// checks the response. A normal packet will tell us that support is available.
//
// Takes a valid thread ID because p needs to apply to a thread.
bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
  if (m_supports_p == eLazyBoolCalculate)
    m_supports_p = GetThreadPacketSupported(tid, "p0");
  return m_supports_p;
}

LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported(
    lldb::tid_t tid, llvm::StringRef packetStr) {
  StreamString payload;
  payload.PutCString(packetStr);
  StringExtractorGDBRemote response;
  if (SendThreadSpecificPacketAndWaitForResponse(
          tid, std::move(payload), response) == PacketResult::Success &&
      response.IsNormalResponse()) {
    return eLazyBoolYes;
  }
  return eLazyBoolNo;
}

bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const {
  return m_supports_qSaveCore == eLazyBoolYes;
}

StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
  // Get information on all threads at one using the "jThreadsInfo" packet
  StructuredData::ObjectSP object_sp;

  if (m_supports_jThreadsInfo) {
    StringExtractorGDBRemote response;
    response.SetResponseValidatorToJSON();
    if (SendPacketAndWaitForResponse("jThreadsInfo", response) ==
        PacketResult::Success) {
      if (response.IsUnsupportedResponse()) {
        m_supports_jThreadsInfo = false;
      } else if (!response.Empty()) {
        object_sp = StructuredData::ParseJSON(response.GetStringRef());
      }
    }
  }
  return object_sp;
}

bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
  if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_jThreadExtendedInfo = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse()) {
        m_supports_jThreadExtendedInfo = eLazyBoolYes;
      }
    }
  }
  return m_supports_jThreadExtendedInfo;
}

void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
  if (m_supports_error_string_reply == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    // We try to enable error strings in remote packets but if we fail, we just
    // work in the older way.
    m_supports_error_string_reply = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("QEnableErrorStrings", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse()) {
        m_supports_error_string_reply = eLazyBoolYes;
      }
    }
  }
}

bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
  if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
                                     response) == PacketResult::Success) {
      if (response.IsOKResponse()) {
        m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
      }
    }
  }
  return m_supports_jLoadedDynamicLibrariesInfos;
}

bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
  if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_jGetSharedCacheInfo = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response) ==
        PacketResult::Success) {
      if (response.IsOKResponse()) {
        m_supports_jGetSharedCacheInfo = eLazyBoolYes;
      }
    }
  }
  return m_supports_jGetSharedCacheInfo;
}

bool GDBRemoteCommunicationClient::GetDynamicLoaderProcessStateSupported() {
  if (m_supports_jGetDyldProcessState == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_jGetDyldProcessState = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("jGetDyldProcessState", response) ==
        PacketResult::Success) {
      if (!response.IsUnsupportedResponse())
        m_supports_jGetDyldProcessState = eLazyBoolYes;
    }
  }
  return m_supports_jGetDyldProcessState;
}

bool GDBRemoteCommunicationClient::GetMemoryTaggingSupported() {
  if (m_supports_memory_tagging == eLazyBoolCalculate) {
    GetRemoteQSupported();
  }
  return m_supports_memory_tagging == eLazyBoolYes;
}

DataBufferSP GDBRemoteCommunicationClient::ReadMemoryTags(lldb::addr_t addr,
                                                          size_t len,
                                                          int32_t type) {
  StreamString packet;
  packet.Printf("qMemTags:%" PRIx64 ",%zx:%" PRIx32, addr, len, type);
  StringExtractorGDBRemote response;

  Log *log = GetLog(GDBRLog::Memory);

  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
          PacketResult::Success ||
      !response.IsNormalResponse()) {
    LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s: qMemTags packet failed",
              __FUNCTION__);
    return nullptr;
  }

  // We are expecting
  // m<hex encoded bytes>

  if (response.GetChar() != 'm') {
    LLDB_LOGF(log,
              "GDBRemoteCommunicationClient::%s: qMemTags response did not "
              "begin with \"m\"",
              __FUNCTION__);
    return nullptr;
  }

  size_t expected_bytes = response.GetBytesLeft() / 2;
  WritableDataBufferSP buffer_sp(new DataBufferHeap(expected_bytes, 0));
  size_t got_bytes = response.GetHexBytesAvail(buffer_sp->GetData());
  // Check both because in some situations chars are consumed even
  // if the decoding fails.
  if (response.GetBytesLeft() || (expected_bytes != got_bytes)) {
    LLDB_LOGF(
        log,
        "GDBRemoteCommunicationClient::%s: Invalid data in qMemTags response",
        __FUNCTION__);
    return nullptr;
  }

  return buffer_sp;
}

Status GDBRemoteCommunicationClient::WriteMemoryTags(
    lldb::addr_t addr, size_t len, int32_t type,
    const std::vector<uint8_t> &tags) {
  // Format QMemTags:address,length:type:tags
  StreamString packet;
  packet.Printf("QMemTags:%" PRIx64 ",%zx:%" PRIx32 ":", addr, len, type);
  packet.PutBytesAsRawHex8(tags.data(), tags.size());

  Status status;
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
          PacketResult::Success ||
      !response.IsOKResponse()) {
    status.SetErrorString("QMemTags packet failed");
  }
  return status;
}

bool GDBRemoteCommunicationClient::GetxPacketSupported() {
  if (m_supports_x == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_x = eLazyBoolNo;
    char packet[256];
    snprintf(packet, sizeof(packet), "x0,0");
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        m_supports_x = eLazyBoolYes;
    }
  }
  return m_supports_x;
}

lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
  if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
    return m_curr_pid;

  // First try to retrieve the pid via the qProcessInfo request.
  GetCurrentProcessInfo(allow_lazy);
  if (m_curr_pid_is_valid == eLazyBoolYes) {
    // We really got it.
    return m_curr_pid;
  } else {
    // If we don't get a response for qProcessInfo, check if $qC gives us a
    // result. $qC only returns a real process id on older debugserver and
    // lldb-platform stubs. The gdb remote protocol documents $qC as returning
    // the thread id, which newer debugserver and lldb-gdbserver stubs return
    // correctly.
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qC", response) == PacketResult::Success) {
      if (response.GetChar() == 'Q') {
        if (response.GetChar() == 'C') {
          m_curr_pid_run = m_curr_pid =
              response.GetHexMaxU64(false, LLDB_INVALID_PROCESS_ID);
          if (m_curr_pid != LLDB_INVALID_PROCESS_ID) {
            m_curr_pid_is_valid = eLazyBoolYes;
            return m_curr_pid;
          }
        }
      }
    }

    // If we don't get a response for $qC, check if $qfThreadID gives us a
    // result.
    if (m_curr_pid == LLDB_INVALID_PROCESS_ID) {
      bool sequence_mutex_unavailable;
      auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
      if (!ids.empty() && !sequence_mutex_unavailable) {
        // If server returned an explicit PID, use that.
        m_curr_pid_run = m_curr_pid = ids.front().first;
        // Otherwise, use the TID of the first thread (Linux hack).
        if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
          m_curr_pid_run = m_curr_pid = ids.front().second;
        m_curr_pid_is_valid = eLazyBoolYes;
        return m_curr_pid;
      }
    }
  }

  return LLDB_INVALID_PROCESS_ID;
}

llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) {
  if (!args.GetArgumentAtIndex(0))
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Nothing to launch");
  // try vRun first
  if (m_supports_vRun) {
    StreamString packet;
    packet.PutCString("vRun");
    for (const Args::ArgEntry &arg : args) {
      packet.PutChar(';');
      packet.PutStringAsRawHex8(arg.ref());
    }

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
        PacketResult::Success)
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Sending vRun packet failed");

    if (response.IsErrorResponse())
      return response.GetStatus().ToError();

    // vRun replies with a stop reason packet
    // FIXME: right now we just discard the packet and LLDB queries
    // for stop reason again
    if (!response.IsUnsupportedResponse())
      return llvm::Error::success();

    m_supports_vRun = false;
  }

  // fallback to A
  StreamString packet;
  packet.PutChar('A');
  llvm::ListSeparator LS(",");
  for (const auto &arg : llvm::enumerate(args)) {
    packet << LS;
    packet.Format("{0},{1},", arg.value().ref().size() * 2, arg.index());
    packet.PutStringAsRawHex8(arg.value().ref());
  }

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
      PacketResult::Success) {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Sending A packet failed");
  }
  if (!response.IsOKResponse())
    return response.GetStatus().ToError();

  if (SendPacketAndWaitForResponse("qLaunchSuccess", response) !=
      PacketResult::Success) {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Sending qLaunchSuccess packet failed");
  }
  if (response.IsOKResponse())
    return llvm::Error::success();
  if (response.GetChar() == 'E') {
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   response.GetStringRef().substr(1));
  }
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "unknown error occurred launching process");
}

int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) {
  for (const auto &KV : env) {
    int r = SendEnvironmentPacket(Environment::compose(KV).c_str());
    if (r != 0)
      return r;
  }
  return 0;
}

int GDBRemoteCommunicationClient::SendEnvironmentPacket(
    char const *name_equal_value) {
  if (name_equal_value && name_equal_value[0]) {
    bool send_hex_encoding = false;
    for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding;
         ++p) {
      if (llvm::isPrint(*p)) {
        switch (*p) {
        case '$':
        case '#':
        case '*':
        case '}':
          send_hex_encoding = true;
          break;
        default:
          break;
        }
      } else {
        // We have non printable characters, lets hex encode this...
        send_hex_encoding = true;
      }
    }

    StringExtractorGDBRemote response;
    // Prefer sending unencoded, if possible and the server supports it.
    if (!send_hex_encoding && m_supports_QEnvironment) {
      StreamString packet;
      packet.Printf("QEnvironment:%s", name_equal_value);
      if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
          PacketResult::Success)
        return -1;

      if (response.IsOKResponse())
        return 0;
      if (response.IsUnsupportedResponse())
        m_supports_QEnvironment = false;
      else {
        uint8_t error = response.GetError();
        if (error)
          return error;
        return -1;
      }
    }

    if (m_supports_QEnvironmentHexEncoded) {
      StreamString packet;
      packet.PutCString("QEnvironmentHexEncoded:");
      packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
      if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
          PacketResult::Success)
        return -1;

      if (response.IsOKResponse())
        return 0;
      if (response.IsUnsupportedResponse())
        m_supports_QEnvironmentHexEncoded = false;
      else {
        uint8_t error = response.GetError();
        if (error)
          return error;
        return -1;
      }
    }
  }
  return -1;
}

int GDBRemoteCommunicationClient::SendLaunchArchPacket(char const *arch) {
  if (arch && arch[0]) {
    StreamString packet;
    packet.Printf("QLaunchArch:%s", arch);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        return 0;
      uint8_t error = response.GetError();
      if (error)
        return error;
    }
  }
  return -1;
}

int GDBRemoteCommunicationClient::SendLaunchEventDataPacket(
    char const *data, bool *was_supported) {
  if (data && *data != '\0') {
    StreamString packet;
    packet.Printf("QSetProcessEvent:%s", data);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      if (response.IsOKResponse()) {
        if (was_supported)
          *was_supported = true;
        return 0;
      } else if (response.IsUnsupportedResponse()) {
        if (was_supported)
          *was_supported = false;
        return -1;
      } else {
        uint8_t error = response.GetError();
        if (was_supported)
          *was_supported = true;
        if (error)
          return error;
      }
    }
  }
  return -1;
}

llvm::VersionTuple GDBRemoteCommunicationClient::GetOSVersion() {
  GetHostInfo();
  return m_os_version;
}

llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() {
  GetHostInfo();
  return m_maccatalyst_version;
}

std::optional<std::string> GDBRemoteCommunicationClient::GetOSBuildString() {
  if (GetHostInfo()) {
    if (!m_os_build.empty())
      return m_os_build;
  }
  return std::nullopt;
}

std::optional<std::string>
GDBRemoteCommunicationClient::GetOSKernelDescription() {
  if (GetHostInfo()) {
    if (!m_os_kernel.empty())
      return m_os_kernel;
  }
  return std::nullopt;
}

bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
  if (GetHostInfo()) {
    if (!m_hostname.empty()) {
      s = m_hostname;
      return true;
    }
  }
  s.clear();
  return false;
}

ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
  if (GetHostInfo())
    return m_host_arch;
  return ArchSpec();
}

const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetProcessArchitecture() {
  if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
    GetCurrentProcessInfo();
  return m_process_arch;
}

bool GDBRemoteCommunicationClient::GetProcessStandaloneBinary(
    UUID &uuid, addr_t &value, bool &value_is_offset) {
  if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
    GetCurrentProcessInfo();

  // Return true if we have a UUID or an address/offset of the
  // main standalone / firmware binary being used.
  if (!m_process_standalone_uuid.IsValid() &&
      m_process_standalone_value == LLDB_INVALID_ADDRESS)
    return false;

  uuid = m_process_standalone_uuid;
  value = m_process_standalone_value;
  value_is_offset = m_process_standalone_value_is_offset;
  return true;
}

std::vector<addr_t>
GDBRemoteCommunicationClient::GetProcessStandaloneBinaries() {
  if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
    GetCurrentProcessInfo();
  return m_binary_addresses;
}

bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
  if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
    m_gdb_server_name.clear();
    m_gdb_server_version = 0;
    m_qGDBServerVersion_is_valid = eLazyBoolNo;

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qGDBServerVersion", response) ==
        PacketResult::Success) {
      if (response.IsNormalResponse()) {
        llvm::StringRef name, value;
        bool success = false;
        while (response.GetNameColonValue(name, value)) {
          if (name.equals("name")) {
            success = true;
            m_gdb_server_name = std::string(value);
          } else if (name.equals("version")) {
            llvm::StringRef major, minor;
            std::tie(major, minor) = value.split('.');
            if (!major.getAsInteger(0, m_gdb_server_version))
              success = true;
          }
        }
        if (success)
          m_qGDBServerVersion_is_valid = eLazyBoolYes;
      }
    }
  }
  return m_qGDBServerVersion_is_valid == eLazyBoolYes;
}

void GDBRemoteCommunicationClient::MaybeEnableCompression(
    llvm::ArrayRef<llvm::StringRef> supported_compressions) {
  CompressionType avail_type = CompressionType::None;
  llvm::StringRef avail_name;

#if defined(HAVE_LIBCOMPRESSION)
  if (avail_type == CompressionType::None) {
    for (auto compression : supported_compressions) {
      if (compression == "lzfse") {
        avail_type = CompressionType::LZFSE;
        avail_name = compression;
        break;
      }
    }
  }
#endif

#if defined(HAVE_LIBCOMPRESSION)
  if (avail_type == CompressionType::None) {
    for (auto compression : supported_compressions) {
      if (compression == "zlib-deflate") {
        avail_type = CompressionType::ZlibDeflate;
        avail_name = compression;
        break;
      }
    }
  }
#endif

#if LLVM_ENABLE_ZLIB
  if (avail_type == CompressionType::None) {
    for (auto compression : supported_compressions) {
      if (compression == "zlib-deflate") {
        avail_type = CompressionType::ZlibDeflate;
        avail_name = compression;
        break;
      }
    }
  }
#endif

#if defined(HAVE_LIBCOMPRESSION)
  if (avail_type == CompressionType::None) {
    for (auto compression : supported_compressions) {
      if (compression == "lz4") {
        avail_type = CompressionType::LZ4;
        avail_name = compression;
        break;
      }
    }
  }
#endif

#if defined(HAVE_LIBCOMPRESSION)
  if (avail_type == CompressionType::None) {
    for (auto compression : supported_compressions) {
      if (compression == "lzma") {
        avail_type = CompressionType::LZMA;
        avail_name = compression;
        break;
      }
    }
  }
#endif

  if (avail_type != CompressionType::None) {
    StringExtractorGDBRemote response;
    std::string packet = "QEnableCompression:type:" + avail_name.str() + ";";
    if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
      return;

    if (response.IsOKResponse()) {
      m_compression_type = avail_type;
    }
  }
}

const char *GDBRemoteCommunicationClient::GetGDBServerProgramName() {
  if (GetGDBServerVersion()) {
    if (!m_gdb_server_name.empty())
      return m_gdb_server_name.c_str();
  }
  return nullptr;
}

uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
  if (GetGDBServerVersion())
    return m_gdb_server_version;
  return 0;
}

bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qC", response) != PacketResult::Success)
    return false;

  if (!response.IsNormalResponse())
    return false;

  if (response.GetChar() == 'Q' && response.GetChar() == 'C') {
    auto pid_tid = response.GetPidTid(0);
    if (!pid_tid)
      return false;

    lldb::pid_t pid = pid_tid->first;
    // invalid
    if (pid == StringExtractorGDBRemote::AllProcesses)
      return false;

    // if we get pid as well, update m_curr_pid
    if (pid != 0) {
      m_curr_pid_run = m_curr_pid = pid;
      m_curr_pid_is_valid = eLazyBoolYes;
    }
    tid = pid_tid->second;
  }

  return true;
}

static void ParseOSType(llvm::StringRef value, std::string &os_name,
                        std::string &environment) {
  if (value.equals("iossimulator") || value.equals("tvossimulator") ||
      value.equals("watchossimulator")) {
    environment = "simulator";
    os_name = value.drop_back(environment.size()).str();
  } else if (value.equals("maccatalyst")) {
    os_name = "ios";
    environment = "macabi";
  } else {
    os_name = value.str();
  }
}

bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
  Log *log = GetLog(GDBRLog::Process);

  if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
    // host info computation can require DNS traffic and shelling out to external processes.
    // Increase the timeout to account for that.
    ScopedTimeout timeout(*this, seconds(10));
    m_qHostInfo_is_valid = eLazyBoolNo;
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qHostInfo", response) ==
        PacketResult::Success) {
      if (response.IsNormalResponse()) {
        llvm::StringRef name;
        llvm::StringRef value;
        uint32_t cpu = LLDB_INVALID_CPUTYPE;
        uint32_t sub = 0;
        std::string arch_name;
        std::string os_name;
        std::string environment;
        std::string vendor_name;
        std::string triple;
        uint32_t pointer_byte_size = 0;
        ByteOrder byte_order = eByteOrderInvalid;
        uint32_t num_keys_decoded = 0;
        while (response.GetNameColonValue(name, value)) {
          if (name.equals("cputype")) {
            // exception type in big endian hex
            if (!value.getAsInteger(0, cpu))
              ++num_keys_decoded;
          } else if (name.equals("cpusubtype")) {
            // exception count in big endian hex
            if (!value.getAsInteger(0, sub))
              ++num_keys_decoded;
          } else if (name.equals("arch")) {
            arch_name = std::string(value);
            ++num_keys_decoded;
          } else if (name.equals("triple")) {
            StringExtractor extractor(value);
            extractor.GetHexByteString(triple);
            ++num_keys_decoded;
          } else if (name.equals("distribution_id")) {
            StringExtractor extractor(value);
            extractor.GetHexByteString(m_host_distribution_id);
            ++num_keys_decoded;
          } else if (name.equals("os_build")) {
            StringExtractor extractor(value);
            extractor.GetHexByteString(m_os_build);
            ++num_keys_decoded;
          } else if (name.equals("hostname")) {
            StringExtractor extractor(value);
            extractor.GetHexByteString(m_hostname);
            ++num_keys_decoded;
          } else if (name.equals("os_kernel")) {
            StringExtractor extractor(value);
            extractor.GetHexByteString(m_os_kernel);
            ++num_keys_decoded;
          } else if (name.equals("ostype")) {
            ParseOSType(value, os_name, environment);
            ++num_keys_decoded;
          } else if (name.equals("vendor")) {
            vendor_name = std::string(value);
            ++num_keys_decoded;
          } else if (name.equals("endian")) {
            byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
                             .Case("little", eByteOrderLittle)
                             .Case("big", eByteOrderBig)
                             .Case("pdp", eByteOrderPDP)
                             .Default(eByteOrderInvalid);
            if (byte_order != eByteOrderInvalid)
              ++num_keys_decoded;
          } else if (name.equals("ptrsize")) {
            if (!value.getAsInteger(0, pointer_byte_size))
              ++num_keys_decoded;
          } else if (name.equals("addressing_bits")) {
            if (!value.getAsInteger(0, m_addressing_bits))
              ++num_keys_decoded;
          } else if (name.equals("os_version") ||
                     name.equals("version")) // Older debugserver binaries used
                                             // the "version" key instead of
                                             // "os_version"...
          {
            if (!m_os_version.tryParse(value))
              ++num_keys_decoded;
          } else if (name.equals("maccatalyst_version")) {
            if (!m_maccatalyst_version.tryParse(value))
              ++num_keys_decoded;
          } else if (name.equals("watchpoint_exceptions_received")) {
            m_watchpoints_trigger_after_instruction =
                llvm::StringSwitch<LazyBool>(value)
                    .Case("before", eLazyBoolNo)
                    .Case("after", eLazyBoolYes)
                    .Default(eLazyBoolCalculate);
            if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
              ++num_keys_decoded;
          } else if (name.equals("default_packet_timeout")) {
            uint32_t timeout_seconds;
            if (!value.getAsInteger(0, timeout_seconds)) {
              m_default_packet_timeout = seconds(timeout_seconds);
              SetPacketTimeout(m_default_packet_timeout);
              ++num_keys_decoded;
            }
          } else if (name.equals("vm-page-size")) {
            int page_size;
            if (!value.getAsInteger(0, page_size)) {
              m_target_vm_page_size = page_size;
              ++num_keys_decoded;
            }
          }
        }

        if (num_keys_decoded > 0)
          m_qHostInfo_is_valid = eLazyBoolYes;

        if (triple.empty()) {
          if (arch_name.empty()) {
            if (cpu != LLDB_INVALID_CPUTYPE) {
              m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
              if (pointer_byte_size) {
                assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
              }
              if (byte_order != eByteOrderInvalid) {
                assert(byte_order == m_host_arch.GetByteOrder());
              }

              if (!vendor_name.empty())
                m_host_arch.GetTriple().setVendorName(
                    llvm::StringRef(vendor_name));
              if (!os_name.empty())
                m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
              if (!environment.empty())
                m_host_arch.GetTriple().setEnvironmentName(environment);
            }
          } else {
            std::string triple;
            triple += arch_name;
            if (!vendor_name.empty() || !os_name.empty()) {
              triple += '-';
              if (vendor_name.empty())
                triple += "unknown";
              else
                triple += vendor_name;
              triple += '-';
              if (os_name.empty())
                triple += "unknown";
              else
                triple += os_name;
            }
            m_host_arch.SetTriple(triple.c_str());

            llvm::Triple &host_triple = m_host_arch.GetTriple();
            if (host_triple.getVendor() == llvm::Triple::Apple &&
                host_triple.getOS() == llvm::Triple::Darwin) {
              switch (m_host_arch.GetMachine()) {
              case llvm::Triple::aarch64:
              case llvm::Triple::aarch64_32:
              case llvm::Triple::arm:
              case llvm::Triple::thumb:
                host_triple.setOS(llvm::Triple::IOS);
                break;
              default:
                host_triple.setOS(llvm::Triple::MacOSX);
                break;
              }
            }
            if (pointer_byte_size) {
              assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
            }
            if (byte_order != eByteOrderInvalid) {
              assert(byte_order == m_host_arch.GetByteOrder());
            }
          }
        } else {
          m_host_arch.SetTriple(triple.c_str());
          if (pointer_byte_size) {
            assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
          }
          if (byte_order != eByteOrderInvalid) {
            assert(byte_order == m_host_arch.GetByteOrder());
          }

          LLDB_LOGF(log,
                    "GDBRemoteCommunicationClient::%s parsed host "
                    "architecture as %s, triple as %s from triple text %s",
                    __FUNCTION__,
                    m_host_arch.GetArchitectureName()
                        ? m_host_arch.GetArchitectureName()
                        : "<null-arch-name>",
                    m_host_arch.GetTriple().getTriple().c_str(),
                    triple.c_str());
        }
      }
    }
  }
  return m_qHostInfo_is_valid == eLazyBoolYes;
}

int GDBRemoteCommunicationClient::SendStdinNotification(const char *data,
                                                        size_t data_len) {
  StreamString packet;
  packet.PutCString("I");
  packet.PutBytesAsRawHex8(data, data_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
      PacketResult::Success) {
    return 0;
  }
  return response.GetError();
}

const lldb_private::ArchSpec &
GDBRemoteCommunicationClient::GetHostArchitecture() {
  if (m_qHostInfo_is_valid == eLazyBoolCalculate)
    GetHostInfo();
  return m_host_arch;
}

uint32_t GDBRemoteCommunicationClient::GetAddressingBits() {
  if (m_qHostInfo_is_valid == eLazyBoolCalculate)
    GetHostInfo();
  return m_addressing_bits;
}
seconds GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout() {
  if (m_qHostInfo_is_valid == eLazyBoolCalculate)
    GetHostInfo();
  return m_default_packet_timeout;
}

addr_t GDBRemoteCommunicationClient::AllocateMemory(size_t size,
                                                    uint32_t permissions) {
  if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
    m_supports_alloc_dealloc_memory = eLazyBoolYes;
    char packet[64];
    const int packet_len = ::snprintf(
        packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s", (uint64_t)size,
        permissions & lldb::ePermissionsReadable ? "r" : "",
        permissions & lldb::ePermissionsWritable ? "w" : "",
        permissions & lldb::ePermissionsExecutable ? "x" : "");
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      if (response.IsUnsupportedResponse())
        m_supports_alloc_dealloc_memory = eLazyBoolNo;
      else if (!response.IsErrorResponse())
        return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
    } else {
      m_supports_alloc_dealloc_memory = eLazyBoolNo;
    }
  }
  return LLDB_INVALID_ADDRESS;
}

bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
  if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
    m_supports_alloc_dealloc_memory = eLazyBoolYes;
    char packet[64];
    const int packet_len =
        ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      if (response.IsUnsupportedResponse())
        m_supports_alloc_dealloc_memory = eLazyBoolNo;
      else if (response.IsOKResponse())
        return true;
    } else {
      m_supports_alloc_dealloc_memory = eLazyBoolNo;
    }
  }
  return false;
}

Status GDBRemoteCommunicationClient::Detach(bool keep_stopped,
                                            lldb::pid_t pid) {
  Status error;
  lldb_private::StreamString packet;

  packet.PutChar('D');
  if (keep_stopped) {
    if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
      char packet[64];
      const int packet_len =
          ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
      assert(packet_len < (int)sizeof(packet));
      UNUSED_IF_ASSERT_DISABLED(packet_len);
      StringExtractorGDBRemote response;
      if (SendPacketAndWaitForResponse(packet, response) ==
              PacketResult::Success &&
          response.IsOKResponse()) {
        m_supports_detach_stay_stopped = eLazyBoolYes;
      } else {
        m_supports_detach_stay_stopped = eLazyBoolNo;
      }
    }

    if (m_supports_detach_stay_stopped == eLazyBoolNo) {
      error.SetErrorString("Stays stopped not supported by this target.");
      return error;
    } else {
      packet.PutChar('1');
    }
  }

  if (GetMultiprocessSupported()) {
    // Some servers (e.g. qemu) require specifying the PID even if only a single
    // process is running.
    if (pid == LLDB_INVALID_PROCESS_ID)
      pid = GetCurrentProcessID();
    packet.PutChar(';');
    packet.PutHex64(pid);
  } else if (pid != LLDB_INVALID_PROCESS_ID) {
    error.SetErrorString("Multiprocess extension not supported by the server.");
    return error;
  }

  StringExtractorGDBRemote response;
  PacketResult packet_result =
      SendPacketAndWaitForResponse(packet.GetString(), response);
  if (packet_result != PacketResult::Success)
    error.SetErrorString("Sending isconnect packet failed.");
  return error;
}

Status GDBRemoteCommunicationClient::GetMemoryRegionInfo(
    lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
  Status error;
  region_info.Clear();

  if (m_supports_memory_region_info != eLazyBoolNo) {
    m_supports_memory_region_info = eLazyBoolYes;
    char packet[64];
    const int packet_len = ::snprintf(
        packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, response) ==
            PacketResult::Success &&
        response.GetResponseType() == StringExtractorGDBRemote::eResponse) {
      llvm::StringRef name;
      llvm::StringRef value;
      addr_t addr_value = LLDB_INVALID_ADDRESS;
      bool success = true;
      bool saw_permissions = false;
      while (success && response.GetNameColonValue(name, value)) {
        if (name.equals("start")) {
          if (!value.getAsInteger(16, addr_value))
            region_info.GetRange().SetRangeBase(addr_value);
        } else if (name.equals("size")) {
          if (!value.getAsInteger(16, addr_value)) {
            region_info.GetRange().SetByteSize(addr_value);
            if (region_info.GetRange().GetRangeEnd() <
                region_info.GetRange().GetRangeBase()) {
              // Range size overflowed, truncate it.
              region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
            }
          }
        } else if (name.equals("permissions") &&
                   region_info.GetRange().IsValid()) {
          saw_permissions = true;
          if (region_info.GetRange().Contains(addr)) {
            if (value.contains('r'))
              region_info.SetReadable(MemoryRegionInfo::eYes);
            else
              region_info.SetReadable(MemoryRegionInfo::eNo);

            if (value.contains('w'))
              region_info.SetWritable(MemoryRegionInfo::eYes);
            else
              region_info.SetWritable(MemoryRegionInfo::eNo);

            if (value.contains('x'))
              region_info.SetExecutable(MemoryRegionInfo::eYes);
            else
              region_info.SetExecutable(MemoryRegionInfo::eNo);

            region_info.SetMapped(MemoryRegionInfo::eYes);
          } else {
            // The reported region does not contain this address -- we're
            // looking at an unmapped page
            region_info.SetReadable(MemoryRegionInfo::eNo);
            region_info.SetWritable(MemoryRegionInfo::eNo);
            region_info.SetExecutable(MemoryRegionInfo::eNo);
            region_info.SetMapped(MemoryRegionInfo::eNo);
          }
        } else if (name.equals("name")) {
          StringExtractorGDBRemote name_extractor(value);
          std::string name;
          name_extractor.GetHexByteString(name);
          region_info.SetName(name.c_str());
        } else if (name.equals("flags")) {
          region_info.SetMemoryTagged(MemoryRegionInfo::eNo);

          llvm::StringRef flags = value;
          llvm::StringRef flag;
          while (flags.size()) {
            flags = flags.ltrim();
            std::tie(flag, flags) = flags.split(' ');
            // To account for trailing whitespace
            if (flag.size()) {
              if (flag == "mt") {
                region_info.SetMemoryTagged(MemoryRegionInfo::eYes);
                break;
              }
            }
          }
        } else if (name.equals("type")) {
          std::string comma_sep_str = value.str();
          size_t comma_pos;
          while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) {
            comma_sep_str[comma_pos] = '\0';
            if (comma_sep_str == "stack") {
              region_info.SetIsStackMemory(MemoryRegionInfo::eYes);
            }
          }
          // handle final (or only) type of "stack"
          if (comma_sep_str == "stack") {
            region_info.SetIsStackMemory(MemoryRegionInfo::eYes);
          }
        } else if (name.equals("error")) {
          StringExtractorGDBRemote error_extractor(value);
          std::string error_string;
          // Now convert the HEX bytes into a string value
          error_extractor.GetHexByteString(error_string);
          error.SetErrorString(error_string.c_str());
        } else if (name.equals("dirty-pages")) {
          std::vector<addr_t> dirty_page_list;
          for (llvm::StringRef x : llvm::split(value, ',')) {
            addr_t page;
            x.consume_front("0x");
            if (llvm::to_integer(x, page, 16))
              dirty_page_list.push_back(page);
          }
          region_info.SetDirtyPageList(dirty_page_list);
        }
      }

      if (m_target_vm_page_size != 0)
        region_info.SetPageSize(m_target_vm_page_size);

      if (region_info.GetRange().IsValid()) {
        // We got a valid address range back but no permissions -- which means
        // this is an unmapped page
        if (!saw_permissions) {
          region_info.SetReadable(MemoryRegionInfo::eNo);
          region_info.SetWritable(MemoryRegionInfo::eNo);
          region_info.SetExecutable(MemoryRegionInfo::eNo);
          region_info.SetMapped(MemoryRegionInfo::eNo);
        }
      } else {
        // We got an invalid address range back
        error.SetErrorString("Server returned invalid range");
      }
    } else {
      m_supports_memory_region_info = eLazyBoolNo;
    }
  }

  if (m_supports_memory_region_info == eLazyBoolNo) {
    error.SetErrorString("qMemoryRegionInfo is not supported");
  }

  // Try qXfer:memory-map:read to get region information not included in
  // qMemoryRegionInfo
  MemoryRegionInfo qXfer_region_info;
  Status qXfer_error = GetQXferMemoryMapRegionInfo(addr, qXfer_region_info);

  if (error.Fail()) {
    // If qMemoryRegionInfo failed, but qXfer:memory-map:read succeeded, use
    // the qXfer result as a fallback
    if (qXfer_error.Success()) {
      region_info = qXfer_region_info;
      error.Clear();
    } else {
      region_info.Clear();
    }
  } else if (qXfer_error.Success()) {
    // If both qMemoryRegionInfo and qXfer:memory-map:read succeeded, and if
    // both regions are the same range, update the result to include the flash-
    // memory information that is specific to the qXfer result.
    if (region_info.GetRange() == qXfer_region_info.GetRange()) {
      region_info.SetFlash(qXfer_region_info.GetFlash());
      region_info.SetBlocksize(qXfer_region_info.GetBlocksize());
    }
  }
  return error;
}

Status GDBRemoteCommunicationClient::GetQXferMemoryMapRegionInfo(
    lldb::addr_t addr, MemoryRegionInfo &region) {
  Status error = LoadQXferMemoryMap();
  if (!error.Success())
    return error;
  for (const auto &map_region : m_qXfer_memory_map) {
    if (map_region.GetRange().Contains(addr)) {
      region = map_region;
      return error;
    }
  }
  error.SetErrorString("Region not found");
  return error;
}

Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() {

  Status error;

  if (m_qXfer_memory_map_loaded)
    // Already loaded, return success
    return error;

  if (!XMLDocument::XMLEnabled()) {
    error.SetErrorString("XML is not supported");
    return error;
  }

  if (!GetQXferMemoryMapReadSupported()) {
    error.SetErrorString("Memory map is not supported");
    return error;
  }

  llvm::Expected<std::string> xml = ReadExtFeature("memory-map", "");
  if (!xml)
    return Status(xml.takeError());

  XMLDocument xml_document;

  if (!xml_document.ParseMemory(xml->c_str(), xml->size())) {
    error.SetErrorString("Failed to parse memory map xml");
    return error;
  }

  XMLNode map_node = xml_document.GetRootElement("memory-map");
  if (!map_node) {
    error.SetErrorString("Invalid root node in memory map xml");
    return error;
  }

  m_qXfer_memory_map.clear();

  map_node.ForEachChildElement([this](const XMLNode &memory_node) -> bool {
    if (!memory_node.IsElement())
      return true;
    if (memory_node.GetName() != "memory")
      return true;
    auto type = memory_node.GetAttributeValue("type", "");
    uint64_t start;
    uint64_t length;
    if (!memory_node.GetAttributeValueAsUnsigned("start", start))
      return true;
    if (!memory_node.GetAttributeValueAsUnsigned("length", length))
      return true;
    MemoryRegionInfo region;
    region.GetRange().SetRangeBase(start);
    region.GetRange().SetByteSize(length);
    if (type == "rom") {
      region.SetReadable(MemoryRegionInfo::eYes);
      this->m_qXfer_memory_map.push_back(region);
    } else if (type == "ram") {
      region.SetReadable(MemoryRegionInfo::eYes);
      region.SetWritable(MemoryRegionInfo::eYes);
      this->m_qXfer_memory_map.push_back(region);
    } else if (type == "flash") {
      region.SetFlash(MemoryRegionInfo::eYes);
      memory_node.ForEachChildElement(
          [&region](const XMLNode &prop_node) -> bool {
            if (!prop_node.IsElement())
              return true;
            if (prop_node.GetName() != "property")
              return true;
            auto propname = prop_node.GetAttributeValue("name", "");
            if (propname == "blocksize") {
              uint64_t blocksize;
              if (prop_node.GetElementTextAsUnsigned(blocksize))
                region.SetBlocksize(blocksize);
            }
            return true;
          });
      this->m_qXfer_memory_map.push_back(region);
    }
    return true;
  });

  m_qXfer_memory_map_loaded = true;

  return error;
}

std::optional<uint32_t> GDBRemoteCommunicationClient::GetWatchpointSlotCount() {
  if (m_supports_watchpoint_support_info == eLazyBoolYes) {
    return m_num_supported_hardware_watchpoints;
  }

  std::optional<uint32_t> num;
  if (m_supports_watchpoint_support_info != eLazyBoolNo) {
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) ==
        PacketResult::Success) {
      m_supports_watchpoint_support_info = eLazyBoolYes;
      llvm::StringRef name;
      llvm::StringRef value;
      while (response.GetNameColonValue(name, value)) {
        if (name.equals("num")) {
          value.getAsInteger(0, m_num_supported_hardware_watchpoints);
          num = m_num_supported_hardware_watchpoints;
        }
      }
      if (!num) {
        m_supports_watchpoint_support_info = eLazyBoolNo;
      }
    } else {
      m_supports_watchpoint_support_info = eLazyBoolNo;
    }
  }

  return num;
}

std::optional<bool> GDBRemoteCommunicationClient::GetWatchpointReportedAfter() {
  if (m_qHostInfo_is_valid == eLazyBoolCalculate)
    GetHostInfo();

  // Process determines this by target CPU, but allow for the
  // remote stub to override it via the qHostInfo
  // watchpoint_exceptions_received key, if it is present.
  if (m_qHostInfo_is_valid == eLazyBoolYes) {
    if (m_watchpoints_trigger_after_instruction == eLazyBoolNo)
      return false;
    if (m_watchpoints_trigger_after_instruction == eLazyBoolYes)
      return true;
  }

  return std::nullopt;
}

int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
  if (file_spec) {
    std::string path{file_spec.GetPath(false)};
    StreamString packet;
    packet.PutCString("QSetSTDIN:");
    packet.PutStringAsRawHex8(path);

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        return 0;
      uint8_t error = response.GetError();
      if (error)
        return error;
    }
  }
  return -1;
}

int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
  if (file_spec) {
    std::string path{file_spec.GetPath(false)};
    StreamString packet;
    packet.PutCString("QSetSTDOUT:");
    packet.PutStringAsRawHex8(path);

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        return 0;
      uint8_t error = response.GetError();
      if (error)
        return error;
    }
  }
  return -1;
}

int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
  if (file_spec) {
    std::string path{file_spec.GetPath(false)};
    StreamString packet;
    packet.PutCString("QSetSTDERR:");
    packet.PutStringAsRawHex8(path);

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        return 0;
      uint8_t error = response.GetError();
      if (error)
        return error;
    }
  }
  return -1;
}

bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qGetWorkingDir", response) ==
      PacketResult::Success) {
    if (response.IsUnsupportedResponse())
      return false;
    if (response.IsErrorResponse())
      return false;
    std::string cwd;
    response.GetHexByteString(cwd);
    working_dir.SetFile(cwd, GetHostArchitecture().GetTriple());
    return !cwd.empty();
  }
  return false;
}

int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
  if (working_dir) {
    std::string path{working_dir.GetPath(false)};
    StreamString packet;
    packet.PutCString("QSetWorkingDir:");
    packet.PutStringAsRawHex8(path);

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        return 0;
      uint8_t error = response.GetError();
      if (error)
        return error;
    }
  }
  return -1;
}

int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
  char packet[32];
  const int packet_len =
      ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
  assert(packet_len < (int)sizeof(packet));
  UNUSED_IF_ASSERT_DISABLED(packet_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
    if (response.IsOKResponse())
      return 0;
    uint8_t error = response.GetError();
    if (error)
      return error;
  }
  return -1;
}

int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
  char packet[32];
  const int packet_len = ::snprintf(packet, sizeof(packet),
                                    "QSetDetachOnError:%i", enable ? 1 : 0);
  assert(packet_len < (int)sizeof(packet));
  UNUSED_IF_ASSERT_DISABLED(packet_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) {
    if (response.IsOKResponse())
      return 0;
    uint8_t error = response.GetError();
    if (error)
      return error;
  }
  return -1;
}

bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
    StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
  if (response.IsNormalResponse()) {
    llvm::StringRef name;
    llvm::StringRef value;
    StringExtractor extractor;

    uint32_t cpu = LLDB_INVALID_CPUTYPE;
    uint32_t sub = 0;
    std::string vendor;
    std::string os_type;

    while (response.GetNameColonValue(name, value)) {
      if (name.equals("pid")) {
        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
        value.getAsInteger(0, pid);
        process_info.SetProcessID(pid);
      } else if (name.equals("ppid")) {
        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
        value.getAsInteger(0, pid);
        process_info.SetParentProcessID(pid);
      } else if (name.equals("uid")) {
        uint32_t uid = UINT32_MAX;
        value.getAsInteger(0, uid);
        process_info.SetUserID(uid);
      } else if (name.equals("euid")) {
        uint32_t uid = UINT32_MAX;
        value.getAsInteger(0, uid);
        process_info.SetEffectiveUserID(uid);
      } else if (name.equals("gid")) {
        uint32_t gid = UINT32_MAX;
        value.getAsInteger(0, gid);
        process_info.SetGroupID(gid);
      } else if (name.equals("egid")) {
        uint32_t gid = UINT32_MAX;
        value.getAsInteger(0, gid);
        process_info.SetEffectiveGroupID(gid);
      } else if (name.equals("triple")) {
        StringExtractor extractor(value);
        std::string triple;
        extractor.GetHexByteString(triple);
        process_info.GetArchitecture().SetTriple(triple.c_str());
      } else if (name.equals("name")) {
        StringExtractor extractor(value);
        // The process name from ASCII hex bytes since we can't control the
        // characters in a process name
        std::string name;
        extractor.GetHexByteString(name);
        process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native);
      } else if (name.equals("args")) {
        llvm::StringRef encoded_args(value), hex_arg;

        bool is_arg0 = true;
        while (!encoded_args.empty()) {
          std::tie(hex_arg, encoded_args) = encoded_args.split('-');
          std::string arg;
          StringExtractor extractor(hex_arg);
          if (extractor.GetHexByteString(arg) * 2 != hex_arg.size()) {
            // In case of wrong encoding, we discard all the arguments
            process_info.GetArguments().Clear();
            process_info.SetArg0("");
            break;
          }
          if (is_arg0)
            process_info.SetArg0(arg);
          else
            process_info.GetArguments().AppendArgument(arg);
          is_arg0 = false;
        }
      } else if (name.equals("cputype")) {
        value.getAsInteger(0, cpu);
      } else if (name.equals("cpusubtype")) {
        value.getAsInteger(0, sub);
      } else if (name.equals("vendor")) {
        vendor = std::string(value);
      } else if (name.equals("ostype")) {
        os_type = std::string(value);
      }
    }

    if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty()) {
      if (vendor == "apple") {
        process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu,
                                                       sub);
        process_info.GetArchitecture().GetTriple().setVendorName(
            llvm::StringRef(vendor));
        process_info.GetArchitecture().GetTriple().setOSName(
            llvm::StringRef(os_type));
      }
    }

    if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
      return true;
  }
  return false;
}

bool GDBRemoteCommunicationClient::GetProcessInfo(
    lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  process_info.Clear();

  if (m_supports_qProcessInfoPID) {
    char packet[32];
    const int packet_len =
        ::snprintf(packet, sizeof(packet), "qProcessInfoPID:%" PRIu64, pid);
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      return DecodeProcessInfoResponse(response, process_info);
    } else {
      m_supports_qProcessInfoPID = false;
      return false;
    }
  }
  return false;
}

bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
  Log *log(GetLog(GDBRLog::Process | GDBRLog::Packets));

  if (allow_lazy) {
    if (m_qProcessInfo_is_valid == eLazyBoolYes)
      return true;
    if (m_qProcessInfo_is_valid == eLazyBoolNo)
      return false;
  }

  GetHostInfo();

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qProcessInfo", response) ==
      PacketResult::Success) {
    if (response.IsNormalResponse()) {
      llvm::StringRef name;
      llvm::StringRef value;
      uint32_t cpu = LLDB_INVALID_CPUTYPE;
      uint32_t sub = 0;
      std::string arch_name;
      std::string os_name;
      std::string environment;
      std::string vendor_name;
      std::string triple;
      std::string elf_abi;
      uint32_t pointer_byte_size = 0;
      StringExtractor extractor;
      ByteOrder byte_order = eByteOrderInvalid;
      uint32_t num_keys_decoded = 0;
      lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
      while (response.GetNameColonValue(name, value)) {
        if (name.equals("cputype")) {
          if (!value.getAsInteger(16, cpu))
            ++num_keys_decoded;
        } else if (name.equals("cpusubtype")) {
          if (!value.getAsInteger(16, sub))
            ++num_keys_decoded;
        } else if (name.equals("triple")) {
          StringExtractor extractor(value);
          extractor.GetHexByteString(triple);
          ++num_keys_decoded;
        } else if (name.equals("ostype")) {
          ParseOSType(value, os_name, environment);
          ++num_keys_decoded;
        } else if (name.equals("vendor")) {
          vendor_name = std::string(value);
          ++num_keys_decoded;
        } else if (name.equals("endian")) {
          byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
                           .Case("little", eByteOrderLittle)
                           .Case("big", eByteOrderBig)
                           .Case("pdp", eByteOrderPDP)
                           .Default(eByteOrderInvalid);
          if (byte_order != eByteOrderInvalid)
            ++num_keys_decoded;
        } else if (name.equals("ptrsize")) {
          if (!value.getAsInteger(16, pointer_byte_size))
            ++num_keys_decoded;
        } else if (name.equals("pid")) {
          if (!value.getAsInteger(16, pid))
            ++num_keys_decoded;
        } else if (name.equals("elf_abi")) {
          elf_abi = std::string(value);
          ++num_keys_decoded;
        } else if (name.equals("main-binary-uuid")) {
          m_process_standalone_uuid.SetFromStringRef(value);
          ++num_keys_decoded;
        } else if (name.equals("main-binary-slide")) {
          StringExtractor extractor(value);
          m_process_standalone_value =
              extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
          if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
            m_process_standalone_value_is_offset = true;
            ++num_keys_decoded;
          }
        } else if (name.equals("main-binary-address")) {
          StringExtractor extractor(value);
          m_process_standalone_value =
              extractor.GetU64(LLDB_INVALID_ADDRESS, 16);
          if (m_process_standalone_value != LLDB_INVALID_ADDRESS) {
            m_process_standalone_value_is_offset = false;
            ++num_keys_decoded;
          }
        } else if (name.equals("binary-addresses")) {
          m_binary_addresses.clear();
          ++num_keys_decoded;
          for (llvm::StringRef x : llvm::split(value, ',')) {
            addr_t vmaddr;
            x.consume_front("0x");
            if (llvm::to_integer(x, vmaddr, 16))
              m_binary_addresses.push_back(vmaddr);
          }
        }
      }
      if (num_keys_decoded > 0)
        m_qProcessInfo_is_valid = eLazyBoolYes;
      if (pid != LLDB_INVALID_PROCESS_ID) {
        m_curr_pid_is_valid = eLazyBoolYes;
        m_curr_pid_run = m_curr_pid = pid;
      }

      // Set the ArchSpec from the triple if we have it.
      if (!triple.empty()) {
        m_process_arch.SetTriple(triple.c_str());
        m_process_arch.SetFlags(elf_abi);
        if (pointer_byte_size) {
          assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
        }
      } else if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() &&
                 !vendor_name.empty()) {
        llvm::Triple triple(llvm::Twine("-") + vendor_name + "-" + os_name);
        if (!environment.empty())
            triple.setEnvironmentName(environment);

        assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
        assert(triple.getObjectFormat() != llvm::Triple::Wasm);
        assert(triple.getObjectFormat() != llvm::Triple::XCOFF);
        switch (triple.getObjectFormat()) {
        case llvm::Triple::MachO:
          m_process_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
          break;
        case llvm::Triple::ELF:
          m_process_arch.SetArchitecture(eArchTypeELF, cpu, sub);
          break;
        case llvm::Triple::COFF:
          m_process_arch.SetArchitecture(eArchTypeCOFF, cpu, sub);
          break;
        case llvm::Triple::GOFF:
        case llvm::Triple::SPIRV:
        case llvm::Triple::Wasm:
        case llvm::Triple::XCOFF:
        case llvm::Triple::DXContainer:
          LLDB_LOGF(log, "error: not supported target architecture");
          return false;
        case llvm::Triple::UnknownObjectFormat:
          LLDB_LOGF(log, "error: failed to determine target architecture");
          return false;
        }

        if (pointer_byte_size) {
          assert(pointer_byte_size == m_process_arch.GetAddressByteSize());
        }
        if (byte_order != eByteOrderInvalid) {
          assert(byte_order == m_process_arch.GetByteOrder());
        }
        m_process_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
        m_process_arch.GetTriple().setOSName(llvm::StringRef(os_name));
        m_process_arch.GetTriple().setEnvironmentName(llvm::StringRef(environment));
      }
      return true;
    }
  } else {
    m_qProcessInfo_is_valid = eLazyBoolNo;
  }

  return false;
}

uint32_t GDBRemoteCommunicationClient::FindProcesses(
    const ProcessInstanceInfoMatch &match_info,
    ProcessInstanceInfoList &process_infos) {
  process_infos.clear();

  if (m_supports_qfProcessInfo) {
    StreamString packet;
    packet.PutCString("qfProcessInfo");
    if (!match_info.MatchAllProcesses()) {
      packet.PutChar(':');
      const char *name = match_info.GetProcessInfo().GetName();
      bool has_name_match = false;
      if (name && name[0]) {
        has_name_match = true;
        NameMatch name_match_type = match_info.GetNameMatchType();
        switch (name_match_type) {
        case NameMatch::Ignore:
          has_name_match = false;
          break;

        case NameMatch::Equals:
          packet.PutCString("name_match:equals;");
          break;

        case NameMatch::Contains:
          packet.PutCString("name_match:contains;");
          break;

        case NameMatch::StartsWith:
          packet.PutCString("name_match:starts_with;");
          break;

        case NameMatch::EndsWith:
          packet.PutCString("name_match:ends_with;");
          break;

        case NameMatch::RegularExpression:
          packet.PutCString("name_match:regex;");
          break;
        }
        if (has_name_match) {
          packet.PutCString("name:");
          packet.PutBytesAsRawHex8(name, ::strlen(name));
          packet.PutChar(';');
        }
      }

      if (match_info.GetProcessInfo().ProcessIDIsValid())
        packet.Printf("pid:%" PRIu64 ";",
                      match_info.GetProcessInfo().GetProcessID());
      if (match_info.GetProcessInfo().ParentProcessIDIsValid())
        packet.Printf("parent_pid:%" PRIu64 ";",
                      match_info.GetProcessInfo().GetParentProcessID());
      if (match_info.GetProcessInfo().UserIDIsValid())
        packet.Printf("uid:%u;", match_info.GetProcessInfo().GetUserID());
      if (match_info.GetProcessInfo().GroupIDIsValid())
        packet.Printf("gid:%u;", match_info.GetProcessInfo().GetGroupID());
      if (match_info.GetProcessInfo().EffectiveUserIDIsValid())
        packet.Printf("euid:%u;",
                      match_info.GetProcessInfo().GetEffectiveUserID());
      if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
        packet.Printf("egid:%u;",
                      match_info.GetProcessInfo().GetEffectiveGroupID());
      packet.Printf("all_users:%u;", match_info.GetMatchAllUsers() ? 1 : 0);
      if (match_info.GetProcessInfo().GetArchitecture().IsValid()) {
        const ArchSpec &match_arch =
            match_info.GetProcessInfo().GetArchitecture();
        const llvm::Triple &triple = match_arch.GetTriple();
        packet.PutCString("triple:");
        packet.PutCString(triple.getTriple());
        packet.PutChar(';');
      }
    }
    StringExtractorGDBRemote response;
    // Increase timeout as the first qfProcessInfo packet takes a long time on
    // Android. The value of 1min was arrived at empirically.
    ScopedTimeout timeout(*this, minutes(1));
    if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
        PacketResult::Success) {
      do {
        ProcessInstanceInfo process_info;
        if (!DecodeProcessInfoResponse(response, process_info))
          break;
        process_infos.push_back(process_info);
        response = StringExtractorGDBRemote();
      } while (SendPacketAndWaitForResponse("qsProcessInfo", response) ==
               PacketResult::Success);
    } else {
      m_supports_qfProcessInfo = false;
      return 0;
    }
  }
  return process_infos.size();
}

bool GDBRemoteCommunicationClient::GetUserName(uint32_t uid,
                                               std::string &name) {
  if (m_supports_qUserName) {
    char packet[32];
    const int packet_len =
        ::snprintf(packet, sizeof(packet), "qUserName:%i", uid);
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      if (response.IsNormalResponse()) {
        // Make sure we parsed the right number of characters. The response is
        // the hex encoded user name and should make up the entire packet. If
        // there are any non-hex ASCII bytes, the length won't match below..
        if (response.GetHexByteString(name) * 2 ==
            response.GetStringRef().size())
          return true;
      }
    } else {
      m_supports_qUserName = false;
      return false;
    }
  }
  return false;
}

bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid,
                                                std::string &name) {
  if (m_supports_qGroupName) {
    char packet[32];
    const int packet_len =
        ::snprintf(packet, sizeof(packet), "qGroupName:%i", gid);
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      if (response.IsNormalResponse()) {
        // Make sure we parsed the right number of characters. The response is
        // the hex encoded group name and should make up the entire packet. If
        // there are any non-hex ASCII bytes, the length won't match below..
        if (response.GetHexByteString(name) * 2 ==
            response.GetStringRef().size())
          return true;
      }
    } else {
      m_supports_qGroupName = false;
      return false;
    }
  }
  return false;
}

static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size,
                                uint32_t recv_size) {
  packet.Clear();
  packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
  uint32_t bytes_left = send_size;
  while (bytes_left > 0) {
    if (bytes_left >= 26) {
      packet.PutCString("abcdefghijklmnopqrstuvwxyz");
      bytes_left -= 26;
    } else {
      packet.Printf("%*.*s;", bytes_left, bytes_left,
                    "abcdefghijklmnopqrstuvwxyz");
      bytes_left = 0;
    }
  }
}

duration<float>
calculate_standard_deviation(const std::vector<duration<float>> &v) {
  if (v.size() == 0)
    return duration<float>::zero();
  using Dur = duration<float>;
  Dur sum = std::accumulate(std::begin(v), std::end(v), Dur());
  Dur mean = sum / v.size();
  float accum = 0;
  for (auto d : v) {
    float delta = (d - mean).count();
    accum += delta * delta;
  };

  return Dur(sqrtf(accum / (v.size() - 1)));
}

void GDBRemoteCommunicationClient::TestPacketSpeed(const uint32_t num_packets,
                                                   uint32_t max_send,
                                                   uint32_t max_recv,
                                                   uint64_t recv_amount,
                                                   bool json, Stream &strm) {

  if (SendSpeedTestPacket(0, 0)) {
    StreamString packet;
    if (json)
      strm.Printf("{ \"packet_speeds\" : {\n    \"num_packets\" : %u,\n    "
                  "\"results\" : [",
                  num_packets);
    else
      strm.Printf("Testing sending %u packets of various sizes:\n",
                  num_packets);
    strm.Flush();

    uint32_t result_idx = 0;
    uint32_t send_size;
    std::vector<duration<float>> packet_times;

    for (send_size = 0; send_size <= max_send;
         send_size ? send_size *= 2 : send_size = 4) {
      for (uint32_t recv_size = 0; recv_size <= max_recv;
           recv_size ? recv_size *= 2 : recv_size = 4) {
        MakeSpeedTestPacket(packet, send_size, recv_size);

        packet_times.clear();
        // Test how long it takes to send 'num_packets' packets
        const auto start_time = steady_clock::now();
        for (uint32_t i = 0; i < num_packets; ++i) {
          const auto packet_start_time = steady_clock::now();
          StringExtractorGDBRemote response;
          SendPacketAndWaitForResponse(packet.GetString(), response);
          const auto packet_end_time = steady_clock::now();
          packet_times.push_back(packet_end_time - packet_start_time);
        }
        const auto end_time = steady_clock::now();
        const auto total_time = end_time - start_time;

        float packets_per_second =
            ((float)num_packets) / duration<float>(total_time).count();
        auto average_per_packet = num_packets > 0 ? total_time / num_packets
                                                  : duration<float>::zero();
        const duration<float> standard_deviation =
            calculate_standard_deviation(packet_times);
        if (json) {
          strm.Format("{0}\n     {{\"send_size\" : {1,6}, \"recv_size\" : "
                      "{2,6}, \"total_time_nsec\" : {3,12:ns-}, "
                      "\"standard_deviation_nsec\" : {4,9:ns-f0}}",
                      result_idx > 0 ? "," : "", send_size, recv_size,
                      total_time, standard_deviation);
          ++result_idx;
        } else {
          strm.Format("qSpeedTest(send={0,7}, recv={1,7}) in {2:s+f9} for "
                      "{3,9:f2} packets/s ({4,10:ms+f6} per packet) with "
                      "standard deviation of {5,10:ms+f6}\n",
                      send_size, recv_size, duration<float>(total_time),
                      packets_per_second, duration<float>(average_per_packet),
                      standard_deviation);
        }
        strm.Flush();
      }
    }

    const float k_recv_amount_mb = (float)recv_amount / (1024.0f * 1024.0f);
    if (json)
      strm.Printf("\n    ]\n  },\n  \"download_speed\" : {\n    \"byte_size\" "
                  ": %" PRIu64 ",\n    \"results\" : [",
                  recv_amount);
    else
      strm.Printf("Testing receiving %2.1fMB of data using varying receive "
                  "packet sizes:\n",
                  k_recv_amount_mb);
    strm.Flush();
    send_size = 0;
    result_idx = 0;
    for (uint32_t recv_size = 32; recv_size <= max_recv; recv_size *= 2) {
      MakeSpeedTestPacket(packet, send_size, recv_size);

      // If we have a receive size, test how long it takes to receive 4MB of
      // data
      if (recv_size > 0) {
        const auto start_time = steady_clock::now();
        uint32_t bytes_read = 0;
        uint32_t packet_count = 0;
        while (bytes_read < recv_amount) {
          StringExtractorGDBRemote response;
          SendPacketAndWaitForResponse(packet.GetString(), response);
          bytes_read += recv_size;
          ++packet_count;
        }
        const auto end_time = steady_clock::now();
        const auto total_time = end_time - start_time;
        float mb_second = ((float)recv_amount) /
                          duration<float>(total_time).count() /
                          (1024.0 * 1024.0);
        float packets_per_second =
            ((float)packet_count) / duration<float>(total_time).count();
        const auto average_per_packet = packet_count > 0
                                            ? total_time / packet_count
                                            : duration<float>::zero();

        if (json) {
          strm.Format("{0}\n     {{\"send_size\" : {1,6}, \"recv_size\" : "
                      "{2,6}, \"total_time_nsec\" : {3,12:ns-}}",
                      result_idx > 0 ? "," : "", send_size, recv_size,
                      total_time);
          ++result_idx;
        } else {
          strm.Format("qSpeedTest(send={0,7}, recv={1,7}) {2,6} packets needed "
                      "to receive {3:f1}MB in {4:s+f9} for {5} MB/sec for "
                      "{6,9:f2} packets/sec ({7,10:ms+f6} per packet)\n",
                      send_size, recv_size, packet_count, k_recv_amount_mb,
                      duration<float>(total_time), mb_second,
                      packets_per_second, duration<float>(average_per_packet));
        }
        strm.Flush();
      }
    }
    if (json)
      strm.Printf("\n    ]\n  }\n}\n");
    else
      strm.EOL();
  }
}

bool GDBRemoteCommunicationClient::SendSpeedTestPacket(uint32_t send_size,
                                                       uint32_t recv_size) {
  StreamString packet;
  packet.Printf("qSpeedTest:response_size:%i;data:", recv_size);
  uint32_t bytes_left = send_size;
  while (bytes_left > 0) {
    if (bytes_left >= 26) {
      packet.PutCString("abcdefghijklmnopqrstuvwxyz");
      bytes_left -= 26;
    } else {
      packet.Printf("%*.*s;", bytes_left, bytes_left,
                    "abcdefghijklmnopqrstuvwxyz");
      bytes_left = 0;
    }
  }

  StringExtractorGDBRemote response;
  return SendPacketAndWaitForResponse(packet.GetString(), response) ==
         PacketResult::Success;
}

bool GDBRemoteCommunicationClient::LaunchGDBServer(
    const char *remote_accept_hostname, lldb::pid_t &pid, uint16_t &port,
    std::string &socket_name) {
  pid = LLDB_INVALID_PROCESS_ID;
  port = 0;
  socket_name.clear();

  StringExtractorGDBRemote response;
  StreamString stream;
  stream.PutCString("qLaunchGDBServer;");
  std::string hostname;
  if (remote_accept_hostname && remote_accept_hostname[0])
    hostname = remote_accept_hostname;
  else {
    if (HostInfo::GetHostname(hostname)) {
      // Make the GDB server we launch only accept connections from this host
      stream.Printf("host:%s;", hostname.c_str());
    } else {
      // Make the GDB server we launch accept connections from any host since
      // we can't figure out the hostname
      stream.Printf("host:*;");
    }
  }
  // give the process a few seconds to startup
  ScopedTimeout timeout(*this, seconds(10));

  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    llvm::StringRef name;
    llvm::StringRef value;
    while (response.GetNameColonValue(name, value)) {
      if (name.equals("port"))
        value.getAsInteger(0, port);
      else if (name.equals("pid"))
        value.getAsInteger(0, pid);
      else if (name.compare("socket_name") == 0) {
        StringExtractor extractor(value);
        extractor.GetHexByteString(socket_name);
      }
    }
    return true;
  }
  return false;
}

size_t GDBRemoteCommunicationClient::QueryGDBServer(
    std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
  connection_urls.clear();

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qQueryGDBServer", response) !=
      PacketResult::Success)
    return 0;

  StructuredData::ObjectSP data =
      StructuredData::ParseJSON(response.GetStringRef());
  if (!data)
    return 0;

  StructuredData::Array *array = data->GetAsArray();
  if (!array)
    return 0;

  for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
    StructuredData::Dictionary *element = nullptr;
    if (!array->GetItemAtIndexAsDictionary(i, element))
      continue;

    uint16_t port = 0;
    if (StructuredData::ObjectSP port_osp =
            element->GetValueForKey(llvm::StringRef("port")))
      port = port_osp->GetUnsignedIntegerValue(0);

    std::string socket_name;
    if (StructuredData::ObjectSP socket_name_osp =
            element->GetValueForKey(llvm::StringRef("socket_name")))
      socket_name = std::string(socket_name_osp->GetStringValue());

    if (port != 0 || !socket_name.empty())
      connection_urls.emplace_back(port, socket_name);
  }
  return connection_urls.size();
}

bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
  StreamString stream;
  stream.Printf("qKillSpawnedProcess:%" PRId64, pid);

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.IsOKResponse())
      return true;
  }
  return false;
}

std::optional<PidTid> GDBRemoteCommunicationClient::SendSetCurrentThreadPacket(
    uint64_t tid, uint64_t pid, char op) {
  lldb_private::StreamString packet;
  packet.PutChar('H');
  packet.PutChar(op);

  if (pid != LLDB_INVALID_PROCESS_ID)
    packet.Printf("p%" PRIx64 ".", pid);

  if (tid == UINT64_MAX)
    packet.PutCString("-1");
  else
    packet.Printf("%" PRIx64, tid);

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet.GetString(), response) ==
      PacketResult::Success) {
    if (response.IsOKResponse())
      return {{pid, tid}};

    /*
     * Connected bare-iron target (like YAMON gdb-stub) may not have support for
     * Hg packet.
     * The reply from '?' packet could be as simple as 'S05'. There is no packet
     * which can
     * give us pid and/or tid. Assume pid=tid=1 in such cases.
     */
    if (response.IsUnsupportedResponse() && IsConnected())
      return {{1, 1}};
  }
  return std::nullopt;
}

bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid,
                                                    uint64_t pid) {
  if (m_curr_tid == tid &&
      (m_curr_pid == pid || LLDB_INVALID_PROCESS_ID == pid))
    return true;

  std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'g');
  if (ret) {
    if (ret->pid != LLDB_INVALID_PROCESS_ID)
      m_curr_pid = ret->pid;
    m_curr_tid = ret->tid;
  }
  return ret.has_value();
}

bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid,
                                                          uint64_t pid) {
  if (m_curr_tid_run == tid &&
      (m_curr_pid_run == pid || LLDB_INVALID_PROCESS_ID == pid))
    return true;

  std::optional<PidTid> ret = SendSetCurrentThreadPacket(tid, pid, 'c');
  if (ret) {
    if (ret->pid != LLDB_INVALID_PROCESS_ID)
      m_curr_pid_run = ret->pid;
    m_curr_tid_run = ret->tid;
  }
  return ret.has_value();
}

bool GDBRemoteCommunicationClient::GetStopReply(
    StringExtractorGDBRemote &response) {
  if (SendPacketAndWaitForResponse("?", response) == PacketResult::Success)
    return response.IsNormalResponse();
  return false;
}

bool GDBRemoteCommunicationClient::GetThreadStopInfo(
    lldb::tid_t tid, StringExtractorGDBRemote &response) {
  if (m_supports_qThreadStopInfo) {
    char packet[256];
    int packet_len =
        ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
    assert(packet_len < (int)sizeof(packet));
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    if (SendPacketAndWaitForResponse(packet, response) ==
        PacketResult::Success) {
      if (response.IsUnsupportedResponse())
        m_supports_qThreadStopInfo = false;
      else if (response.IsNormalResponse())
        return true;
      else
        return false;
    } else {
      m_supports_qThreadStopInfo = false;
    }
  }
  return false;
}

uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
    GDBStoppointType type, bool insert, addr_t addr, uint32_t length,
    std::chrono::seconds timeout) {
  Log *log = GetLog(LLDBLog::Breakpoints);
  LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
            __FUNCTION__, insert ? "add" : "remove", addr);

  // Check if the stub is known not to support this breakpoint type
  if (!SupportsGDBStoppointPacket(type))
    return UINT8_MAX;
  // Construct the breakpoint packet
  char packet[64];
  const int packet_len =
      ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
                 insert ? 'Z' : 'z', type, addr, length);
  // Check we haven't overwritten the end of the packet buffer
  assert(packet_len + 1 < (int)sizeof(packet));
  UNUSED_IF_ASSERT_DISABLED(packet_len);
  StringExtractorGDBRemote response;
  // Make sure the response is either "OK", "EXX" where XX are two hex digits,
  // or "" (unsupported)
  response.SetResponseValidatorToOKErrorNotSupported();
  // Try to send the breakpoint packet, and check that it was correctly sent
  if (SendPacketAndWaitForResponse(packet, response, timeout) ==
      PacketResult::Success) {
    // Receive and OK packet when the breakpoint successfully placed
    if (response.IsOKResponse())
      return 0;

    // Status while setting breakpoint, send back specific error
    if (response.IsErrorResponse())
      return response.GetError();

    // Empty packet informs us that breakpoint is not supported
    if (response.IsUnsupportedResponse()) {
      // Disable this breakpoint type since it is unsupported
      switch (type) {
      case eBreakpointSoftware:
        m_supports_z0 = false;
        break;
      case eBreakpointHardware:
        m_supports_z1 = false;
        break;
      case eWatchpointWrite:
        m_supports_z2 = false;
        break;
      case eWatchpointRead:
        m_supports_z3 = false;
        break;
      case eWatchpointReadWrite:
        m_supports_z4 = false;
        break;
      case eStoppointInvalid:
        return UINT8_MAX;
      }
    }
  }
  // Signal generic failure
  return UINT8_MAX;
}

std::vector<std::pair<lldb::pid_t, lldb::tid_t>>
GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs(
    bool &sequence_mutex_unavailable) {
  std::vector<std::pair<lldb::pid_t, lldb::tid_t>> ids;

  Lock lock(*this);
  if (lock) {
    sequence_mutex_unavailable = false;
    StringExtractorGDBRemote response;

    PacketResult packet_result;
    for (packet_result =
             SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
         packet_result == PacketResult::Success && response.IsNormalResponse();
         packet_result =
             SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
      char ch = response.GetChar();
      if (ch == 'l')
        break;
      if (ch == 'm') {
        do {
          auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID);
          // If we get an invalid response, break out of the loop.
          // If there are valid tids, they have been added to ids.
          // If there are no valid tids, we'll fall through to the
          // bare-iron target handling below.
          if (!pid_tid)
            break;

          ids.push_back(*pid_tid);
          ch = response.GetChar(); // Skip the command separator
        } while (ch == ',');       // Make sure we got a comma separator
      }
    }

    /*
     * Connected bare-iron target (like YAMON gdb-stub) may not have support for
     * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet
     * could
     * be as simple as 'S05'. There is no packet which can give us pid and/or
     * tid.
     * Assume pid=tid=1 in such cases.
     */
    if ((response.IsUnsupportedResponse() || response.IsNormalResponse()) &&
        ids.size() == 0 && IsConnected()) {
      ids.emplace_back(1, 1);
    }
  } else {
    Log *log(GetLog(GDBRLog::Process | GDBRLog::Packets));
    LLDB_LOG(log, "error: failed to get packet sequence mutex, not sending "
                  "packet 'qfThreadInfo'");
    sequence_mutex_unavailable = true;
  }

  return ids;
}

size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
    std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
  lldb::pid_t pid = GetCurrentProcessID();
  thread_ids.clear();

  auto ids = GetCurrentProcessAndThreadIDs(sequence_mutex_unavailable);
  if (ids.empty() || sequence_mutex_unavailable)
    return 0;

  for (auto id : ids) {
    // skip threads that do not belong to the current process
    if (id.first != LLDB_INVALID_PROCESS_ID && id.first != pid)
      continue;
    if (id.second != LLDB_INVALID_THREAD_ID &&
        id.second != StringExtractorGDBRemote::AllThreads)
      thread_ids.push_back(id.second);
  }

  return thread_ids.size();
}

lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qShlibInfoAddr", response) !=
          PacketResult::Success ||
      !response.IsNormalResponse())
    return LLDB_INVALID_ADDRESS;
  return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
}

lldb_private::Status GDBRemoteCommunicationClient::RunShellCommand(
    llvm::StringRef command,
    const FileSpec &
        working_dir, // Pass empty FileSpec to use the current working directory
    int *status_ptr, // Pass NULL if you don't want the process exit status
    int *signo_ptr,  // Pass NULL if you don't want the signal that caused the
                     // process to exit
    std::string
        *command_output, // Pass NULL if you don't want the command output
    const Timeout<std::micro> &timeout) {
  lldb_private::StreamString stream;
  stream.PutCString("qPlatform_shell:");
  stream.PutBytesAsRawHex8(command.data(), command.size());
  stream.PutChar(',');
  uint32_t timeout_sec = UINT32_MAX;
  if (timeout) {
    // TODO: Use chrono version of std::ceil once c++17 is available.
    timeout_sec = std::ceil(std::chrono::duration<double>(*timeout).count());
  }
  stream.PutHex32(timeout_sec);
  if (working_dir) {
    std::string path{working_dir.GetPath(false)};
    stream.PutChar(',');
    stream.PutStringAsRawHex8(path);
  }
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return Status("malformed reply");
    if (response.GetChar() != ',')
      return Status("malformed reply");
    uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
    if (exitcode == UINT32_MAX)
      return Status("unable to run remote process");
    else if (status_ptr)
      *status_ptr = exitcode;
    if (response.GetChar() != ',')
      return Status("malformed reply");
    uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
    if (signo_ptr)
      *signo_ptr = signo;
    if (response.GetChar() != ',')
      return Status("malformed reply");
    std::string output;
    response.GetEscapedBinaryData(output);
    if (command_output)
      command_output->assign(output);
    return Status();
  }
  return Status("unable to send packet");
}

Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec,
                                                   uint32_t file_permissions) {
  std::string path{file_spec.GetPath(false)};
  lldb_private::StreamString stream;
  stream.PutCString("qPlatform_mkdir:");
  stream.PutHex32(file_permissions);
  stream.PutChar(',');
  stream.PutStringAsRawHex8(path);
  llvm::StringRef packet = stream.GetString();
  StringExtractorGDBRemote response;

  if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
    return Status("failed to send '%s' packet", packet.str().c_str());

  if (response.GetChar() != 'F')
    return Status("invalid response to '%s' packet", packet.str().c_str());

  return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
}

Status
GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
                                                 uint32_t file_permissions) {
  std::string path{file_spec.GetPath(false)};
  lldb_private::StreamString stream;
  stream.PutCString("qPlatform_chmod:");
  stream.PutHex32(file_permissions);
  stream.PutChar(',');
  stream.PutStringAsRawHex8(path);
  llvm::StringRef packet = stream.GetString();
  StringExtractorGDBRemote response;

  if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success)
    return Status("failed to send '%s' packet", stream.GetData());

  if (response.GetChar() != 'F')
    return Status("invalid response to '%s' packet", stream.GetData());

  return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
}

static int gdb_errno_to_system(int err) {
  switch (err) {
#define HANDLE_ERRNO(name, value)                                              \
  case GDB_##name:                                                             \
    return name;
#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def"
  default:
    return -1;
  }
}

static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response,
                                          uint64_t fail_result, Status &error) {
  response.SetFilePos(0);
  if (response.GetChar() != 'F')
    return fail_result;
  int32_t result = response.GetS32(-2, 16);
  if (result == -2)
    return fail_result;
  if (response.GetChar() == ',') {
    int result_errno = gdb_errno_to_system(response.GetS32(-1, 16));
    if (result_errno != -1)
      error.SetError(result_errno, eErrorTypePOSIX);
    else
      error.SetError(-1, eErrorTypeGeneric);
  } else
    error.Clear();
  return result;
}
lldb::user_id_t
GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec,
                                       File::OpenOptions flags, mode_t mode,
                                       Status &error) {
  std::string path(file_spec.GetPath(false));
  lldb_private::StreamString stream;
  stream.PutCString("vFile:open:");
  if (path.empty())
    return UINT64_MAX;
  stream.PutStringAsRawHex8(path);
  stream.PutChar(',');
  stream.PutHex32(flags);
  stream.PutChar(',');
  stream.PutHex32(mode);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    return ParseHostIOPacketResponse(response, UINT64_MAX, error);
  }
  return UINT64_MAX;
}

bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd,
                                             Status &error) {
  lldb_private::StreamString stream;
  stream.Printf("vFile:close:%x", (int)fd);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    return ParseHostIOPacketResponse(response, -1, error) == 0;
  }
  return false;
}

std::optional<GDBRemoteFStatData>
GDBRemoteCommunicationClient::FStat(lldb::user_id_t fd) {
  lldb_private::StreamString stream;
  stream.Printf("vFile:fstat:%" PRIx64, fd);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return std::nullopt;
    int64_t size = response.GetS64(-1, 16);
    if (size > 0 && response.GetChar() == ';') {
      std::string buffer;
      if (response.GetEscapedBinaryData(buffer)) {
        GDBRemoteFStatData out;
        if (buffer.size() != sizeof(out))
          return std::nullopt;
        memcpy(&out, buffer.data(), sizeof(out));
        return out;
      }
    }
  }
  return std::nullopt;
}

std::optional<GDBRemoteFStatData>
GDBRemoteCommunicationClient::Stat(const lldb_private::FileSpec &file_spec) {
  Status error;
  lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error);
  if (fd == UINT64_MAX)
    return std::nullopt;
  std::optional<GDBRemoteFStatData> st = FStat(fd);
  CloseFile(fd, error);
  return st;
}

// Extension of host I/O packets to get the file size.
lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
    const lldb_private::FileSpec &file_spec) {
  if (m_supports_vFileSize) {
    std::string path(file_spec.GetPath(false));
    lldb_private::StreamString stream;
    stream.PutCString("vFile:size:");
    stream.PutStringAsRawHex8(path);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
        PacketResult::Success)
      return UINT64_MAX;

    if (!response.IsUnsupportedResponse()) {
      if (response.GetChar() != 'F')
        return UINT64_MAX;
      uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
      return retcode;
    }
    m_supports_vFileSize = false;
  }

  // Fallback to fstat.
  std::optional<GDBRemoteFStatData> st = Stat(file_spec);
  return st ? st->gdb_st_size : UINT64_MAX;
}

void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory(
    CompletionRequest &request, bool only_dir) {
  lldb_private::StreamString stream;
  stream.PutCString("qPathComplete:");
  stream.PutHex32(only_dir ? 1 : 0);
  stream.PutChar(',');
  stream.PutStringAsRawHex8(request.GetCursorArgumentPrefix());
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    StreamString strm;
    char ch = response.GetChar();
    if (ch != 'M')
      return;
    while (response.Peek()) {
      strm.Clear();
      while ((ch = response.GetHexU8(0, false)) != '\0')
        strm.PutChar(ch);
      request.AddCompletion(strm.GetString());
      if (response.GetChar() != ',')
        break;
    }
  }
}

Status
GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
                                                 uint32_t &file_permissions) {
  if (m_supports_vFileMode) {
    std::string path{file_spec.GetPath(false)};
    Status error;
    lldb_private::StreamString stream;
    stream.PutCString("vFile:mode:");
    stream.PutStringAsRawHex8(path);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
        PacketResult::Success) {
      error.SetErrorStringWithFormat("failed to send '%s' packet",
                                     stream.GetData());
      return error;
    }
    if (!response.IsUnsupportedResponse()) {
      if (response.GetChar() != 'F') {
        error.SetErrorStringWithFormat("invalid response to '%s' packet",
                                       stream.GetData());
      } else {
        const uint32_t mode = response.GetS32(-1, 16);
        if (static_cast<int32_t>(mode) == -1) {
          if (response.GetChar() == ',') {
            int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
            if (response_errno > 0)
              error.SetError(response_errno, lldb::eErrorTypePOSIX);
            else
              error.SetErrorToGenericError();
          } else
            error.SetErrorToGenericError();
        } else {
          file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
        }
      }
      return error;
    } else { // response.IsUnsupportedResponse()
      m_supports_vFileMode = false;
    }
  }

  // Fallback to fstat.
  if (std::optional<GDBRemoteFStatData> st = Stat(file_spec)) {
    file_permissions = st->gdb_st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
    return Status();
  }
  return Status("fstat failed");
}

uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd,
                                                uint64_t offset, void *dst,
                                                uint64_t dst_len,
                                                Status &error) {
  lldb_private::StreamString stream;
  stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len,
                offset);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return 0;
    int64_t retcode = response.GetS64(-1, 16);
    if (retcode == -1) {
      error.SetErrorToGenericError();
      if (response.GetChar() == ',') {
        int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
        if (response_errno > 0)
          error.SetError(response_errno, lldb::eErrorTypePOSIX);
      }
      return -1;
    }
    const char next = (response.Peek() ? *response.Peek() : 0);
    if (next == ',')
      return 0;
    if (next == ';') {
      response.GetChar(); // skip the semicolon
      std::string buffer;
      if (response.GetEscapedBinaryData(buffer)) {
        const uint64_t data_to_write =
            std::min<uint64_t>(dst_len, buffer.size());
        if (data_to_write > 0)
          memcpy(dst, &buffer[0], data_to_write);
        return data_to_write;
      }
    }
  }
  return 0;
}

uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd,
                                                 uint64_t offset,
                                                 const void *src,
                                                 uint64_t src_len,
                                                 Status &error) {
  lldb_private::StreamGDBRemote stream;
  stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset);
  stream.PutEscapedBytes(src, src_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F') {
      error.SetErrorStringWithFormat("write file failed");
      return 0;
    }
    int64_t bytes_written = response.GetS64(-1, 16);
    if (bytes_written == -1) {
      error.SetErrorToGenericError();
      if (response.GetChar() == ',') {
        int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
        if (response_errno > 0)
          error.SetError(response_errno, lldb::eErrorTypePOSIX);
      }
      return -1;
    }
    return bytes_written;
  } else {
    error.SetErrorString("failed to send vFile:pwrite packet");
  }
  return 0;
}

Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
                                                   const FileSpec &dst) {
  std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
  Status error;
  lldb_private::StreamGDBRemote stream;
  stream.PutCString("vFile:symlink:");
  // the unix symlink() command reverses its parameters where the dst if first,
  // so we follow suit here
  stream.PutStringAsRawHex8(dst_path);
  stream.PutChar(',');
  stream.PutStringAsRawHex8(src_path);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() == 'F') {
      uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
      if (result != 0) {
        error.SetErrorToGenericError();
        if (response.GetChar() == ',') {
          int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
          if (response_errno > 0)
            error.SetError(response_errno, lldb::eErrorTypePOSIX);
        }
      }
    } else {
      // Should have returned with 'F<result>[,<errno>]'
      error.SetErrorStringWithFormat("symlink failed");
    }
  } else {
    error.SetErrorString("failed to send vFile:symlink packet");
  }
  return error;
}

Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
  std::string path{file_spec.GetPath(false)};
  Status error;
  lldb_private::StreamGDBRemote stream;
  stream.PutCString("vFile:unlink:");
  // the unix symlink() command reverses its parameters where the dst if first,
  // so we follow suit here
  stream.PutStringAsRawHex8(path);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() == 'F') {
      uint32_t result = response.GetHexMaxU32(false, UINT32_MAX);
      if (result != 0) {
        error.SetErrorToGenericError();
        if (response.GetChar() == ',') {
          int response_errno = gdb_errno_to_system(response.GetS32(-1, 16));
          if (response_errno > 0)
            error.SetError(response_errno, lldb::eErrorTypePOSIX);
        }
      }
    } else {
      // Should have returned with 'F<result>[,<errno>]'
      error.SetErrorStringWithFormat("unlink failed");
    }
  } else {
    error.SetErrorString("failed to send vFile:unlink packet");
  }
  return error;
}

// Extension of host I/O packets to get whether a file exists.
bool GDBRemoteCommunicationClient::GetFileExists(
    const lldb_private::FileSpec &file_spec) {
  if (m_supports_vFileExists) {
    std::string path(file_spec.GetPath(false));
    lldb_private::StreamString stream;
    stream.PutCString("vFile:exists:");
    stream.PutStringAsRawHex8(path);
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(stream.GetString(), response) !=
        PacketResult::Success)
      return false;
    if (!response.IsUnsupportedResponse()) {
      if (response.GetChar() != 'F')
        return false;
      if (response.GetChar() != ',')
        return false;
      bool retcode = (response.GetChar() != '0');
      return retcode;
    } else
      m_supports_vFileExists = false;
  }

  // Fallback to open.
  Status error;
  lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error);
  if (fd == UINT64_MAX)
    return false;
  CloseFile(fd, error);
  return true;
}

bool GDBRemoteCommunicationClient::CalculateMD5(
    const lldb_private::FileSpec &file_spec, uint64_t &high, uint64_t &low) {
  std::string path(file_spec.GetPath(false));
  lldb_private::StreamString stream;
  stream.PutCString("vFile:MD5:");
  stream.PutStringAsRawHex8(path);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return false;
    if (response.GetChar() != ',')
      return false;
    if (response.Peek() && *response.Peek() == 'x')
      return false;
    low = response.GetHexMaxU64(false, UINT64_MAX);
    high = response.GetHexMaxU64(false, UINT64_MAX);
    return true;
  }
  return false;
}

bool GDBRemoteCommunicationClient::AvoidGPackets(ProcessGDBRemote *process) {
  // Some targets have issues with g/G packets and we need to avoid using them
  if (m_avoid_g_packets == eLazyBoolCalculate) {
    if (process) {
      m_avoid_g_packets = eLazyBoolNo;
      const ArchSpec &arch = process->GetTarget().GetArchitecture();
      if (arch.IsValid() &&
          arch.GetTriple().getVendor() == llvm::Triple::Apple &&
          arch.GetTriple().getOS() == llvm::Triple::IOS &&
          (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
           arch.GetTriple().getArch() == llvm::Triple::aarch64_32)) {
        m_avoid_g_packets = eLazyBoolYes;
        uint32_t gdb_server_version = GetGDBServerProgramVersion();
        if (gdb_server_version != 0) {
          const char *gdb_server_name = GetGDBServerProgramName();
          if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0) {
            if (gdb_server_version >= 310)
              m_avoid_g_packets = eLazyBoolNo;
          }
        }
      }
    }
  }
  return m_avoid_g_packets == eLazyBoolYes;
}

DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
                                                        uint32_t reg) {
  StreamString payload;
  payload.Printf("p%x", reg);
  StringExtractorGDBRemote response;
  if (SendThreadSpecificPacketAndWaitForResponse(
          tid, std::move(payload), response) != PacketResult::Success ||
      !response.IsNormalResponse())
    return nullptr;

  WritableDataBufferSP buffer_sp(
      new DataBufferHeap(response.GetStringRef().size() / 2, 0));
  response.GetHexBytes(buffer_sp->GetData(), '\xcc');
  return buffer_sp;
}

DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
  StreamString payload;
  payload.PutChar('g');
  StringExtractorGDBRemote response;
  if (SendThreadSpecificPacketAndWaitForResponse(
          tid, std::move(payload), response) != PacketResult::Success ||
      !response.IsNormalResponse())
    return nullptr;

  WritableDataBufferSP buffer_sp(
      new DataBufferHeap(response.GetStringRef().size() / 2, 0));
  response.GetHexBytes(buffer_sp->GetData(), '\xcc');
  return buffer_sp;
}

bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
                                                 uint32_t reg_num,
                                                 llvm::ArrayRef<uint8_t> data) {
  StreamString payload;
  payload.Printf("P%x=", reg_num);
  payload.PutBytesAsRawHex8(data.data(), data.size(),
                            endian::InlHostByteOrder(),
                            endian::InlHostByteOrder());
  StringExtractorGDBRemote response;
  return SendThreadSpecificPacketAndWaitForResponse(
             tid, std::move(payload), response) == PacketResult::Success &&
         response.IsOKResponse();
}

bool GDBRemoteCommunicationClient::WriteAllRegisters(
    lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
  StreamString payload;
  payload.PutChar('G');
  payload.PutBytesAsRawHex8(data.data(), data.size(),
                            endian::InlHostByteOrder(),
                            endian::InlHostByteOrder());
  StringExtractorGDBRemote response;
  return SendThreadSpecificPacketAndWaitForResponse(
             tid, std::move(payload), response) == PacketResult::Success &&
         response.IsOKResponse();
}

bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
                                                     uint32_t &save_id) {
  save_id = 0; // Set to invalid save ID
  if (m_supports_QSaveRegisterState == eLazyBoolNo)
    return false;

  m_supports_QSaveRegisterState = eLazyBoolYes;
  StreamString payload;
  payload.PutCString("QSaveRegisterState");
  StringExtractorGDBRemote response;
  if (SendThreadSpecificPacketAndWaitForResponse(
          tid, std::move(payload), response) != PacketResult::Success)
    return false;

  if (response.IsUnsupportedResponse())
    m_supports_QSaveRegisterState = eLazyBoolNo;

  const uint32_t response_save_id = response.GetU32(0);
  if (response_save_id == 0)
    return false;

  save_id = response_save_id;
  return true;
}

bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
                                                        uint32_t save_id) {
  // We use the "m_supports_QSaveRegisterState" variable here because the
  // QSaveRegisterState and QRestoreRegisterState packets must both be
  // supported in order to be useful
  if (m_supports_QSaveRegisterState == eLazyBoolNo)
    return false;

  StreamString payload;
  payload.Printf("QRestoreRegisterState:%u", save_id);
  StringExtractorGDBRemote response;
  if (SendThreadSpecificPacketAndWaitForResponse(
          tid, std::move(payload), response) != PacketResult::Success)
    return false;

  if (response.IsOKResponse())
    return true;

  if (response.IsUnsupportedResponse())
    m_supports_QSaveRegisterState = eLazyBoolNo;
  return false;
}

bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
  if (!GetSyncThreadStateSupported())
    return false;

  StreamString packet;
  StringExtractorGDBRemote response;
  packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
  return SendPacketAndWaitForResponse(packet.GetString(), response) ==
             GDBRemoteCommunication::PacketResult::Success &&
         response.IsOKResponse();
}

llvm::Expected<TraceSupportedResponse>
GDBRemoteCommunicationClient::SendTraceSupported(std::chrono::seconds timeout) {
  Log *log = GetLog(GDBRLog::Process);

  StreamGDBRemote escaped_packet;
  escaped_packet.PutCString("jLLDBTraceSupported");

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
                                   timeout) ==
      GDBRemoteCommunication::PacketResult::Success) {
    if (response.IsErrorResponse())
      return response.GetStatus().ToError();
    if (response.IsUnsupportedResponse())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "jLLDBTraceSupported is unsupported");

    return llvm::json::parse<TraceSupportedResponse>(response.Peek(),
                                                     "TraceSupportedResponse");
  }
  LLDB_LOG(log, "failed to send packet: jLLDBTraceSupported");
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "failed to send packet: jLLDBTraceSupported");
}

llvm::Error
GDBRemoteCommunicationClient::SendTraceStop(const TraceStopRequest &request,
                                            std::chrono::seconds timeout) {
  Log *log = GetLog(GDBRLog::Process);

  StreamGDBRemote escaped_packet;
  escaped_packet.PutCString("jLLDBTraceStop:");

  std::string json_string;
  llvm::raw_string_ostream os(json_string);
  os << toJSON(request);
  os.flush();

  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
                                   timeout) ==
      GDBRemoteCommunication::PacketResult::Success) {
    if (response.IsErrorResponse())
      return response.GetStatus().ToError();
    if (response.IsUnsupportedResponse())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "jLLDBTraceStop is unsupported");
    if (response.IsOKResponse())
      return llvm::Error::success();
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Invalid jLLDBTraceStart response");
  }
  LLDB_LOG(log, "failed to send packet: jLLDBTraceStop");
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "failed to send packet: jLLDBTraceStop '%s'",
                                 escaped_packet.GetData());
}

llvm::Error
GDBRemoteCommunicationClient::SendTraceStart(const llvm::json::Value &params,
                                             std::chrono::seconds timeout) {
  Log *log = GetLog(GDBRLog::Process);

  StreamGDBRemote escaped_packet;
  escaped_packet.PutCString("jLLDBTraceStart:");

  std::string json_string;
  llvm::raw_string_ostream os(json_string);
  os << params;
  os.flush();

  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
                                   timeout) ==
      GDBRemoteCommunication::PacketResult::Success) {
    if (response.IsErrorResponse())
      return response.GetStatus().ToError();
    if (response.IsUnsupportedResponse())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "jLLDBTraceStart is unsupported");
    if (response.IsOKResponse())
      return llvm::Error::success();
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Invalid jLLDBTraceStart response");
  }
  LLDB_LOG(log, "failed to send packet: jLLDBTraceStart");
  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "failed to send packet: jLLDBTraceStart '%s'",
                                 escaped_packet.GetData());
}

llvm::Expected<std::string>
GDBRemoteCommunicationClient::SendTraceGetState(llvm::StringRef type,
                                                std::chrono::seconds timeout) {
  Log *log = GetLog(GDBRLog::Process);

  StreamGDBRemote escaped_packet;
  escaped_packet.PutCString("jLLDBTraceGetState:");

  std::string json_string;
  llvm::raw_string_ostream os(json_string);
  os << toJSON(TraceGetStateRequest{type.str()});
  os.flush();

  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
                                   timeout) ==
      GDBRemoteCommunication::PacketResult::Success) {
    if (response.IsErrorResponse())
      return response.GetStatus().ToError();
    if (response.IsUnsupportedResponse())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "jLLDBTraceGetState is unsupported");
    return std::string(response.Peek());
  }

  LLDB_LOG(log, "failed to send packet: jLLDBTraceGetState");
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "failed to send packet: jLLDBTraceGetState '%s'",
      escaped_packet.GetData());
}

llvm::Expected<std::vector<uint8_t>>
GDBRemoteCommunicationClient::SendTraceGetBinaryData(
    const TraceGetBinaryDataRequest &request, std::chrono::seconds timeout) {
  Log *log = GetLog(GDBRLog::Process);

  StreamGDBRemote escaped_packet;
  escaped_packet.PutCString("jLLDBTraceGetBinaryData:");

  std::string json_string;
  llvm::raw_string_ostream os(json_string);
  os << toJSON(request);
  os.flush();

  escaped_packet.PutEscapedBytes(json_string.c_str(), json_string.size());

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
                                   timeout) ==
      GDBRemoteCommunication::PacketResult::Success) {
    if (response.IsErrorResponse())
      return response.GetStatus().ToError();
    std::string data;
    response.GetEscapedBinaryData(data);
    return std::vector<uint8_t>(data.begin(), data.end());
  }
  LLDB_LOG(log, "failed to send packet: jLLDBTraceGetBinaryData");
  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "failed to send packet: jLLDBTraceGetBinaryData '%s'",
      escaped_packet.GetData());
}

std::optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qOffsets", response) !=
      PacketResult::Success)
    return std::nullopt;
  if (!response.IsNormalResponse())
    return std::nullopt;

  QOffsets result;
  llvm::StringRef ref = response.GetStringRef();
  const auto &GetOffset = [&] {
    addr_t offset;
    if (ref.consumeInteger(16, offset))
      return false;
    result.offsets.push_back(offset);
    return true;
  };

  if (ref.consume_front("Text=")) {
    result.segments = false;
    if (!GetOffset())
      return std::nullopt;
    if (!ref.consume_front(";Data=") || !GetOffset())
      return std::nullopt;
    if (ref.empty())
      return result;
    if (ref.consume_front(";Bss=") && GetOffset() && ref.empty())
      return result;
  } else if (ref.consume_front("TextSeg=")) {
    result.segments = true;
    if (!GetOffset())
      return std::nullopt;
    if (ref.empty())
      return result;
    if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
      return result;
  }
  return std::nullopt;
}

bool GDBRemoteCommunicationClient::GetModuleInfo(
    const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
    ModuleSpec &module_spec) {
  if (!m_supports_qModuleInfo)
    return false;

  std::string module_path = module_file_spec.GetPath(false);
  if (module_path.empty())
    return false;

  StreamString packet;
  packet.PutCString("qModuleInfo:");
  packet.PutStringAsRawHex8(module_path);
  packet.PutCString(";");
  const auto &triple = arch_spec.GetTriple().getTriple();
  packet.PutStringAsRawHex8(triple);

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet.GetString(), response) !=
      PacketResult::Success)
    return false;

  if (response.IsErrorResponse())
    return false;

  if (response.IsUnsupportedResponse()) {
    m_supports_qModuleInfo = false;
    return false;
  }

  llvm::StringRef name;
  llvm::StringRef value;

  module_spec.Clear();
  module_spec.GetFileSpec() = module_file_spec;

  while (response.GetNameColonValue(name, value)) {
    if (name == "uuid" || name == "md5") {
      StringExtractor extractor(value);
      std::string uuid;
      extractor.GetHexByteString(uuid);
      module_spec.GetUUID().SetFromStringRef(uuid);
    } else if (name == "triple") {
      StringExtractor extractor(value);
      std::string triple;
      extractor.GetHexByteString(triple);
      module_spec.GetArchitecture().SetTriple(triple.c_str());
    } else if (name == "file_offset") {
      uint64_t ival = 0;
      if (!value.getAsInteger(16, ival))
        module_spec.SetObjectOffset(ival);
    } else if (name == "file_size") {
      uint64_t ival = 0;
      if (!value.getAsInteger(16, ival))
        module_spec.SetObjectSize(ival);
    } else if (name == "file_path") {
      StringExtractor extractor(value);
      std::string path;
      extractor.GetHexByteString(path);
      module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple());
    }
  }

  return true;
}

static std::optional<ModuleSpec>
ParseModuleSpec(StructuredData::Dictionary *dict) {
  ModuleSpec result;
  if (!dict)
    return std::nullopt;

  llvm::StringRef string;
  uint64_t integer;

  if (!dict->GetValueForKeyAsString("uuid", string))
    return std::nullopt;
  if (!result.GetUUID().SetFromStringRef(string))
    return std::nullopt;

  if (!dict->GetValueForKeyAsInteger("file_offset", integer))
    return std::nullopt;
  result.SetObjectOffset(integer);

  if (!dict->GetValueForKeyAsInteger("file_size", integer))
    return std::nullopt;
  result.SetObjectSize(integer);

  if (!dict->GetValueForKeyAsString("triple", string))
    return std::nullopt;
  result.GetArchitecture().SetTriple(string);

  if (!dict->GetValueForKeyAsString("file_path", string))
    return std::nullopt;
  result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple());

  return result;
}

std::optional<std::vector<ModuleSpec>>
GDBRemoteCommunicationClient::GetModulesInfo(
    llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple) {
  namespace json = llvm::json;

  if (!m_supports_jModulesInfo)
    return std::nullopt;

  json::Array module_array;
  for (const FileSpec &module_file_spec : module_file_specs) {
    module_array.push_back(
        json::Object{{"file", module_file_spec.GetPath(false)},
                     {"triple", triple.getTriple()}});
  }
  StreamString unescaped_payload;
  unescaped_payload.PutCString("jModulesInfo:");
  unescaped_payload.AsRawOstream() << std::move(module_array);

  StreamGDBRemote payload;
  payload.PutEscapedBytes(unescaped_payload.GetString().data(),
                          unescaped_payload.GetSize());

  // Increase the timeout for jModulesInfo since this packet can take longer.
  ScopedTimeout timeout(*this, std::chrono::seconds(10));

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(payload.GetString(), response) !=
          PacketResult::Success ||
      response.IsErrorResponse())
    return std::nullopt;

  if (response.IsUnsupportedResponse()) {
    m_supports_jModulesInfo = false;
    return std::nullopt;
  }

  StructuredData::ObjectSP response_object_sp =
      StructuredData::ParseJSON(response.GetStringRef());
  if (!response_object_sp)
    return std::nullopt;

  StructuredData::Array *response_array = response_object_sp->GetAsArray();
  if (!response_array)
    return std::nullopt;

  std::vector<ModuleSpec> result;
  for (size_t i = 0; i < response_array->GetSize(); ++i) {
    if (std::optional<ModuleSpec> module_spec = ParseModuleSpec(
            response_array->GetItemAtIndex(i)->GetAsDictionary()))
      result.push_back(*module_spec);
  }

  return result;
}

// query the target remote for extended information using the qXfer packet
//
// example: object='features', annex='target.xml'
// return: <xml output> or error
llvm::Expected<std::string>
GDBRemoteCommunicationClient::ReadExtFeature(llvm::StringRef object,
                                             llvm::StringRef annex) {

  std::string output;
  llvm::raw_string_ostream output_stream(output);
  StringExtractorGDBRemote chunk;

  uint64_t size = GetRemoteMaxPacketSize();
  if (size == 0)
    size = 0x1000;
  size = size - 1; // Leave space for the 'm' or 'l' character in the response
  int offset = 0;
  bool active = true;

  // loop until all data has been read
  while (active) {

    // send query extended feature packet
    std::string packet =
        ("qXfer:" + object + ":read:" + annex + ":" +
         llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size))
            .str();

    GDBRemoteCommunication::PacketResult res =
        SendPacketAndWaitForResponse(packet, chunk);

    if (res != GDBRemoteCommunication::PacketResult::Success ||
        chunk.GetStringRef().empty()) {
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "Error sending $qXfer packet");
    }

    // check packet code
    switch (chunk.GetStringRef()[0]) {
    // last chunk
    case ('l'):
      active = false;
      [[fallthrough]];

    // more chunks
    case ('m'):
      output_stream << chunk.GetStringRef().drop_front();
      offset += chunk.GetStringRef().size() - 1;
      break;

    // unknown chunk
    default:
      return llvm::createStringError(
          llvm::inconvertibleErrorCode(),
          "Invalid continuation code from $qXfer packet");
    }
  }

  return output_stream.str();
}

// Notify the target that gdb is prepared to serve symbol lookup requests.
//  packet: "qSymbol::"
//  reply:
//  OK                  The target does not need to look up any (more) symbols.
//  qSymbol:<sym_name>  The target requests the value of symbol sym_name (hex
//  encoded).
//                      LLDB may provide the value by sending another qSymbol
//                      packet
//                      in the form of"qSymbol:<sym_value>:<sym_name>".
//
//  Three examples:
//
//  lldb sends:    qSymbol::
//  lldb receives: OK
//     Remote gdb stub does not need to know the addresses of any symbols, lldb
//     does not
//     need to ask again in this session.
//
//  lldb sends:    qSymbol::
//  lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
//  lldb sends:    qSymbol::64697370617463685f71756575655f6f666673657473
//  lldb receives: OK
//     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb does
//     not know
//     the address at this time.  lldb needs to send qSymbol:: again when it has
//     more
//     solibs loaded.
//
//  lldb sends:    qSymbol::
//  lldb receives: qSymbol:64697370617463685f71756575655f6f666673657473
//  lldb sends:    qSymbol:2bc97554:64697370617463685f71756575655f6f666673657473
//  lldb receives: OK
//     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb says
//     that it
//     is at address 0x2bc97554.  Remote gdb stub sends 'OK' indicating that it
//     does not
//     need any more symbols.  lldb does not need to ask again in this session.

void GDBRemoteCommunicationClient::ServeSymbolLookups(
    lldb_private::Process *process) {
  // Set to true once we've resolved a symbol to an address for the remote
  // stub. If we get an 'OK' response after this, the remote stub doesn't need
  // any more symbols and we can stop asking.
  bool symbol_response_provided = false;

  // Is this the initial qSymbol:: packet?
  bool first_qsymbol_query = true;

  if (m_supports_qSymbol && !m_qSymbol_requests_done) {
    Lock lock(*this);
    if (lock) {
      StreamString packet;
      packet.PutCString("qSymbol::");
      StringExtractorGDBRemote response;
      while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
             PacketResult::Success) {
        if (response.IsOKResponse()) {
          if (symbol_response_provided || first_qsymbol_query) {
            m_qSymbol_requests_done = true;
          }

          // We are done serving symbols requests
          return;
        }
        first_qsymbol_query = false;

        if (response.IsUnsupportedResponse()) {
          // qSymbol is not supported by the current GDB server we are
          // connected to
          m_supports_qSymbol = false;
          return;
        } else {
          llvm::StringRef response_str(response.GetStringRef());
          if (response_str.startswith("qSymbol:")) {
            response.SetFilePos(strlen("qSymbol:"));
            std::string symbol_name;
            if (response.GetHexByteString(symbol_name)) {
              if (symbol_name.empty())
                return;

              addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
              lldb_private::SymbolContextList sc_list;
              process->GetTarget().GetImages().FindSymbolsWithNameAndType(
                  ConstString(symbol_name), eSymbolTypeAny, sc_list);
              for (const SymbolContext &sc : sc_list) {
                if (symbol_load_addr != LLDB_INVALID_ADDRESS)
                  break;
                if (sc.symbol) {
                  switch (sc.symbol->GetType()) {
                  case eSymbolTypeInvalid:
                  case eSymbolTypeAbsolute:
                  case eSymbolTypeUndefined:
                  case eSymbolTypeSourceFile:
                  case eSymbolTypeHeaderFile:
                  case eSymbolTypeObjectFile:
                  case eSymbolTypeCommonBlock:
                  case eSymbolTypeBlock:
                  case eSymbolTypeLocal:
                  case eSymbolTypeParam:
                  case eSymbolTypeVariable:
                  case eSymbolTypeVariableType:
                  case eSymbolTypeLineEntry:
                  case eSymbolTypeLineHeader:
                  case eSymbolTypeScopeBegin:
                  case eSymbolTypeScopeEnd:
                  case eSymbolTypeAdditional:
                  case eSymbolTypeCompiler:
                  case eSymbolTypeInstrumentation:
                  case eSymbolTypeTrampoline:
                    break;

                  case eSymbolTypeCode:
                  case eSymbolTypeResolver:
                  case eSymbolTypeData:
                  case eSymbolTypeRuntime:
                  case eSymbolTypeException:
                  case eSymbolTypeObjCClass:
                  case eSymbolTypeObjCMetaClass:
                  case eSymbolTypeObjCIVar:
                  case eSymbolTypeReExported:
                    symbol_load_addr =
                        sc.symbol->GetLoadAddress(&process->GetTarget());
                    break;
                  }
                }
              }
              // This is the normal path where our symbol lookup was successful
              // and we want to send a packet with the new symbol value and see
              // if another lookup needs to be done.

              // Change "packet" to contain the requested symbol value and name
              packet.Clear();
              packet.PutCString("qSymbol:");
              if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
                packet.Printf("%" PRIx64, symbol_load_addr);
                symbol_response_provided = true;
              } else {
                symbol_response_provided = false;
              }
              packet.PutCString(":");
              packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
              continue; // go back to the while loop and send "packet" and wait
                        // for another response
            }
          }
        }
      }
      // If we make it here, the symbol request packet response wasn't valid or
      // our symbol lookup failed so we must abort
      return;

    } else if (Log *log = GetLog(GDBRLog::Process | GDBRLog::Packets)) {
      LLDB_LOGF(log,
                "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
                __FUNCTION__);
    }
  }
}

StructuredData::Array *
GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
  if (!m_supported_async_json_packets_is_valid) {
    // Query the server for the array of supported asynchronous JSON packets.
    m_supported_async_json_packets_is_valid = true;

    Log *log = GetLog(GDBRLog::Process);

    // Poll it now.
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) ==
        PacketResult::Success) {
      m_supported_async_json_packets_sp =
          StructuredData::ParseJSON(response.GetStringRef());
      if (m_supported_async_json_packets_sp &&
          !m_supported_async_json_packets_sp->GetAsArray()) {
        // We were returned something other than a JSON array.  This is
        // invalid.  Clear it out.
        LLDB_LOGF(log,
                  "GDBRemoteCommunicationClient::%s(): "
                  "QSupportedAsyncJSONPackets returned invalid "
                  "result: %s",
                  __FUNCTION__, response.GetStringRef().data());
        m_supported_async_json_packets_sp.reset();
      }
    } else {
      LLDB_LOGF(log,
                "GDBRemoteCommunicationClient::%s(): "
                "QSupportedAsyncJSONPackets unsupported",
                __FUNCTION__);
    }

    if (log && m_supported_async_json_packets_sp) {
      StreamString stream;
      m_supported_async_json_packets_sp->Dump(stream);
      LLDB_LOGF(log,
                "GDBRemoteCommunicationClient::%s(): supported async "
                "JSON packets: %s",
                __FUNCTION__, stream.GetData());
    }
  }

  return m_supported_async_json_packets_sp
             ? m_supported_async_json_packets_sp->GetAsArray()
             : nullptr;
}

Status GDBRemoteCommunicationClient::SendSignalsToIgnore(
    llvm::ArrayRef<int32_t> signals) {
  // Format packet:
  // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
  auto range = llvm::make_range(signals.begin(), signals.end());
  std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();

  StringExtractorGDBRemote response;
  auto send_status = SendPacketAndWaitForResponse(packet, response);

  if (send_status != GDBRemoteCommunication::PacketResult::Success)
    return Status("Sending QPassSignals packet failed");

  if (response.IsOKResponse()) {
    return Status();
  } else {
    return Status("Unknown error happened during sending QPassSignals packet.");
  }
}

Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
    ConstString type_name, const StructuredData::ObjectSP &config_sp) {
  Status error;

  if (type_name.GetLength() == 0) {
    error.SetErrorString("invalid type_name argument");
    return error;
  }

  // Build command: Configure{type_name}: serialized config data.
  StreamGDBRemote stream;
  stream.PutCString("QConfigure");
  stream.PutCString(type_name.GetStringRef());
  stream.PutChar(':');
  if (config_sp) {
    // Gather the plain-text version of the configuration data.
    StreamString unescaped_stream;
    config_sp->Dump(unescaped_stream);
    unescaped_stream.Flush();

    // Add it to the stream in escaped fashion.
    stream.PutEscapedBytes(unescaped_stream.GetString().data(),
                           unescaped_stream.GetSize());
  }
  stream.Flush();

  // Send the packet.
  StringExtractorGDBRemote response;
  auto result = SendPacketAndWaitForResponse(stream.GetString(), response);
  if (result == PacketResult::Success) {
    // We failed if the config result comes back other than OK.
    if (strcmp(response.GetStringRef().data(), "OK") == 0) {
      // Okay!
      error.Clear();
    } else {
      error.SetErrorStringWithFormat("configuring StructuredData feature "
                                     "%s failed with error %s",
                                     type_name.AsCString(),
                                     response.GetStringRef().data());
    }
  } else {
    // Can we get more data here on the failure?
    error.SetErrorStringWithFormat("configuring StructuredData feature %s "
                                   "failed when sending packet: "
                                   "PacketResult=%d",
                                   type_name.AsCString(), (int)result);
  }
  return error;
}

void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
  GDBRemoteClientBase::OnRunPacketSent(first);
  m_curr_tid = LLDB_INVALID_THREAD_ID;
}

bool GDBRemoteCommunicationClient::UsesNativeSignals() {
  if (m_uses_native_signals == eLazyBoolCalculate)
    GetRemoteQSupported();
  if (m_uses_native_signals == eLazyBoolYes)
    return true;

  // If the remote didn't indicate native-signal support explicitly,
  // check whether it is an old version of lldb-server.
  return GetThreadSuffixSupported();
}

llvm::Expected<int> GDBRemoteCommunicationClient::KillProcess(lldb::pid_t pid) {
  StringExtractorGDBRemote response;
  GDBRemoteCommunication::ScopedTimeout(*this, seconds(3));

  if (SendPacketAndWaitForResponse("k", response, GetPacketTimeout()) !=
      PacketResult::Success)
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "failed to send k packet");

  char packet_cmd = response.GetChar(0);
  if (packet_cmd == 'W' || packet_cmd == 'X')
    return response.GetHexU8();

  return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                 "unexpected response to k packet: %s",
                                 response.GetStringRef().str().c_str());
}
