//===-- 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 <math.h>
#include <sys/stat.h>

#include <numeric>
#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/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", "gdb-remote.client.rx_packet"),
      m_supports_not_sending_acks(eLazyBoolCalculate),
      m_supports_thread_suffix(eLazyBoolCalculate),
      m_supports_threads_in_stop_reply(eLazyBoolCalculate),
      m_supports_vCont_all(eLazyBoolCalculate),
      m_supports_vCont_any(eLazyBoolCalculate),
      m_supports_vCont_c(eLazyBoolCalculate),
      m_supports_vCont_C(eLazyBoolCalculate),
      m_supports_vCont_s(eLazyBoolCalculate),
      m_supports_vCont_S(eLazyBoolCalculate),
      m_qHostInfo_is_valid(eLazyBoolCalculate),
      m_curr_pid_is_valid(eLazyBoolCalculate),
      m_qProcessInfo_is_valid(eLazyBoolCalculate),
      m_qGDBServerVersion_is_valid(eLazyBoolCalculate),
      m_supports_alloc_dealloc_memory(eLazyBoolCalculate),
      m_supports_memory_region_info(eLazyBoolCalculate),
      m_supports_watchpoint_support_info(eLazyBoolCalculate),
      m_supports_detach_stay_stopped(eLazyBoolCalculate),
      m_watchpoints_trigger_after_instruction(eLazyBoolCalculate),
      m_attach_or_wait_reply(eLazyBoolCalculate),
      m_prepare_for_reg_writing_reply(eLazyBoolCalculate),
      m_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
      m_avoid_g_packets(eLazyBoolCalculate),
      m_supports_QSaveRegisterState(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_augmented_libraries_svr4_read(eLazyBoolCalculate),
      m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
      m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
      m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
      m_supports_QPassSignals(eLazyBoolCalculate),
      m_supports_error_string_reply(eLazyBoolCalculate),
      m_supports_multiprocess(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_supports_jThreadsInfo(true), m_supports_jModulesInfo(true),
      m_curr_pid(LLDB_INVALID_PROCESS_ID), m_curr_tid(LLDB_INVALID_THREAD_ID),
      m_curr_tid_run(LLDB_INVALID_THREAD_ID),
      m_num_supported_hardware_watchpoints(0), m_host_arch(), m_process_arch(),
      m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(),
      m_gdb_server_version(UINT32_MAX), m_default_packet_timeout(0),
      m_max_packet_size(0), m_qSupported_response(),
      m_supported_async_json_packets_is_valid(false),
      m_supported_async_json_packets_sp(), m_qXfer_memory_map(),
      m_qXfer_memory_map_loaded(false) {}

// 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...
  if (SendAck()) {
    // Wait for any responses that might have been queued up in the remote
    // GDB server and flush them all
    StringExtractorGDBRemote response;
    PacketResult packet_result = PacketResult::Success;
    while (packet_result == PacketResult::Success)
      packet_result = ReadPacket(response, milliseconds(10), false);

    // 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 {
      if (error_ptr)
        error_ptr->SetErrorString("failed to get reply to handshake packet");
    }
  } 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;
}

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, false) ==
        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,
                                     false) == 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,
                                     false) == 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,
                                     false) == 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_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_augmented_libraries_svr4_read = 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_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_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_multiprocess = eLazyBoolNo;
  m_supports_qEcho = eLazyBoolNo;
  m_supports_QPassSignals = 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+"};
  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,
                                   /*send_async=*/false) ==
      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();

    llvm::SmallVector<llvm::StringRef, 16> server_features;
    response.GetStringRef().split(server_features, ';');

    for (llvm::StringRef x : server_features) {
      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 == "qEcho")
        m_supports_qEcho = eLazyBoolYes;
      else if (x == "QPassSignals+")
        m_supports_QPassSignals = eLazyBoolYes;
      else if (x == "multiprocess+")
        m_supports_multiprocess = 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(
              ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_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,
                                     false) == 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, false) ==
        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,
    bool send_async) {
  Lock lock(*this, send_async);
  if (!lock) {
    if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
            GDBR_LOG_PROCESS | GDBR_LOG_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, false) == PacketResult::Success &&
      response.IsNormalResponse()) {
    return eLazyBoolYes;
  }
  return eLazyBoolNo;
}

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, false) ==
        PacketResult::Success) {
      if (response.IsUnsupportedResponse()) {
        m_supports_jThreadsInfo = false;
      } else if (!response.Empty()) {
        object_sp =
            StructuredData::ParseJSON(std::string(response.GetStringRef()));
      }
    }
  }
  return object_sp;
}

bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
  if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate) {
    StringExtractorGDBRemote response;
    m_supports_jThreadExtendedInfo = eLazyBoolNo;
    if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) ==
        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, false) ==
        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,
                                     false) == 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, false) ==
        PacketResult::Success) {
      if (response.IsOKResponse()) {
        m_supports_jGetSharedCacheInfo = eLazyBoolYes;
      }
    }
  }
  return m_supports_jGetSharedCacheInfo;
}

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, false) ==
        PacketResult::Success) {
      if (response.IsOKResponse())
        m_supports_x = eLazyBoolYes;
    }
  }
  return m_supports_x;
}

GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses(
    const char *payload_prefix, std::string &response_string) {
  Lock lock(*this, false);
  if (!lock) {
    Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
                                                           GDBR_LOG_PACKETS));
    LLDB_LOGF(log,
              "error: failed to get packet sequence mutex, not sending "
              "packets with prefix '%s'",
              payload_prefix);
    return PacketResult::ErrorNoSequenceLock;
  }

  response_string = "";
  std::string payload_prefix_str(payload_prefix);
  unsigned int response_size = 0x1000;
  if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
    response_size = GetRemoteMaxPacketSize();
  }

  for (unsigned int offset = 0; true; offset += response_size) {
    StringExtractorGDBRemote this_response;
    // Construct payload
    char sizeDescriptor[128];
    snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset,
             response_size);
    PacketResult result = SendPacketAndWaitForResponseNoLock(
        payload_prefix_str + sizeDescriptor, this_response);
    if (result != PacketResult::Success)
      return result;

    const std::string &this_string = std::string(this_response.GetStringRef());

    // Check for m or l as first character; l seems to mean this is the last
    // chunk
    char first_char = *this_string.c_str();
    if (first_char != 'm' && first_char != 'l') {
      return PacketResult::ErrorReplyInvalid;
    }
    // Concatenate the result so far (skipping 'm' or 'l')
    response_string.append(this_string, 1, std::string::npos);
    if (first_char == 'l')
      // We're done
      return PacketResult::Success;
  }
}

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, false) ==
        PacketResult::Success) {
      if (response.GetChar() == 'Q') {
        if (response.GetChar() == 'C') {
          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 = ids.front().first;
        // Otherwise, use the TID of the first thread (Linux hack).
        if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
          m_curr_pid = ids.front().second;
        m_curr_pid_is_valid = eLazyBoolYes;
        return m_curr_pid;
      }
    }
  }

  return LLDB_INVALID_PROCESS_ID;
}

bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) {
  error_str.clear();
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse("qLaunchSuccess", response, false) ==
      PacketResult::Success) {
    if (response.IsOKResponse())
      return true;
    if (response.GetChar() == 'E') {
      // A string the describes what failed when launching...
      error_str = std::string(response.GetStringRef().substr(1));
    } else {
      error_str.assign("unknown error occurred launching process");
    }
  } else {
    error_str.assign("timed out waiting for app to launch");
  }
  return false;
}

int GDBRemoteCommunicationClient::SendArgumentsPacket(
    const ProcessLaunchInfo &launch_info) {
  // Since we don't get the send argv0 separate from the executable path, we
  // need to make sure to use the actual executable path found in the
  // launch_info...
  std::vector<const char *> argv;
  FileSpec exe_file = launch_info.GetExecutableFile();
  std::string exe_path;
  const char *arg = nullptr;
  const Args &launch_args = launch_info.GetArguments();
  if (exe_file)
    exe_path = exe_file.GetPath(false);
  else {
    arg = launch_args.GetArgumentAtIndex(0);
    if (arg)
      exe_path = arg;
  }
  if (!exe_path.empty()) {
    argv.push_back(exe_path.c_str());
    for (uint32_t i = 1; (arg = launch_args.GetArgumentAtIndex(i)) != nullptr;
         ++i) {
      if (arg)
        argv.push_back(arg);
    }
  }
  if (!argv.empty()) {
    StreamString packet;
    packet.PutChar('A');
    for (size_t i = 0, n = argv.size(); i < n; ++i) {
      arg = argv[i];
      const int arg_len = strlen(arg);
      if (i > 0)
        packet.PutChar(',');
      packet.Printf("%i,%i,", arg_len * 2, (int)i);
      packet.PutBytesAsRawHex8(arg, arg_len);
    }

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

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]) {
    StreamString packet;
    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;
    if (send_hex_encoding) {
      if (m_supports_QEnvironmentHexEncoded) {
        packet.PutCString("QEnvironmentHexEncoded:");
        packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value));
        if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
            PacketResult::Success) {
          if (response.IsOKResponse())
            return 0;
          uint8_t error = response.GetError();
          if (error)
            return error;
          if (response.IsUnsupportedResponse())
            m_supports_QEnvironmentHexEncoded = false;
        }
      }

    } else if (m_supports_QEnvironment) {
      packet.Printf("QEnvironment:%s", name_equal_value);
      if (SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
          PacketResult::Success) {
        if (response.IsOKResponse())
          return 0;
        uint8_t error = response.GetError();
        if (error)
          return error;
        if (response.IsUnsupportedResponse())
          m_supports_QEnvironment = false;
      }
    }
  }
  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, false) ==
        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, false) ==
        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;
}

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

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

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::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, false) ==
        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;
    llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";";
    if (SendPacketAndWaitForResponse(packet.str(), response, false) !=
        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, false) !=
      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 = 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(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_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, false) ==
        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 distribution_id;
        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(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("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;
            }
          }
        }

        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());
        }
        if (!distribution_id.empty())
          m_host_arch.SetDistributionId(distribution_id.c_str());
      }
    }
  }
  return m_qHostInfo_is_valid == eLazyBoolYes;
}

int GDBRemoteCommunicationClient::SendAttach(
    lldb::pid_t pid, StringExtractorGDBRemote &response) {
  if (pid != LLDB_INVALID_PROCESS_ID) {
    char packet[64];
    const int packet_len =
        ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid);
    UNUSED_IF_ASSERT_DISABLED(packet_len);
    assert(packet_len < (int)sizeof(packet));
    if (SendPacketAndWaitForResponse(packet, response, false) ==
        PacketResult::Success) {
      if (response.IsErrorResponse())
        return response.GetError();
      return 0;
    }
  }
  return -1;
}

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, false) ==
      PacketResult::Success) {
    return 0;
  }
  return response.GetError();
}

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

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, false) ==
        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, false) ==
        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) {
  Status error;

  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, false) ==
              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 {
      StringExtractorGDBRemote response;
      PacketResult packet_result =
          SendPacketAndWaitForResponse("D1", response, false);
      if (packet_result != PacketResult::Success)
        error.SetErrorString("Sending extended disconnect packet failed.");
    }
  } else {
    StringExtractorGDBRemote response;
    PacketResult packet_result =
        SendPacketAndWaitForResponse("D", response, false);
    if (packet_result != PacketResult::Success)
      error.SetErrorString("Sending disconnect 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, false) ==
            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);
        } else if (name.equals("permissions") &&
                   region_info.GetRange().IsValid()) {
          saw_permissions = true;
          if (region_info.GetRange().Contains(addr)) {
            if (value.find('r') != llvm::StringRef::npos)
              region_info.SetReadable(MemoryRegionInfo::eYes);
            else
              region_info.SetReadable(MemoryRegionInfo::eNo);

            if (value.find('w') != llvm::StringRef::npos)
              region_info.SetWritable(MemoryRegionInfo::eYes);
            else
              region_info.SetWritable(MemoryRegionInfo::eNo);

            if (value.find('x') != llvm::StringRef::npos)
              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("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());
        }
      }

      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;
  }

  std::string xml;
  lldb_private::Status lldberr;
  if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml,
                      lldberr)) {
    error.SetErrorString("Failed to read memory map");
    return error;
  }

  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;
}

Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
  Status error;

  if (m_supports_watchpoint_support_info == eLazyBoolYes) {
    num = m_num_supported_hardware_watchpoints;
    return error;
  }

  // Set num to 0 first.
  num = 0;
  if (m_supports_watchpoint_support_info != eLazyBoolNo) {
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response,
                                     false) == PacketResult::Success) {
      m_supports_watchpoint_support_info = eLazyBoolYes;
      llvm::StringRef name;
      llvm::StringRef value;
      bool found_num_field = false;
      while (response.GetNameColonValue(name, value)) {
        if (name.equals("num")) {
          value.getAsInteger(0, m_num_supported_hardware_watchpoints);
          num = m_num_supported_hardware_watchpoints;
          found_num_field = true;
        }
      }
      if (!found_num_field) {
        m_supports_watchpoint_support_info = eLazyBoolNo;
      }
    } else {
      m_supports_watchpoint_support_info = eLazyBoolNo;
    }
  }

  if (m_supports_watchpoint_support_info == eLazyBoolNo) {
    error.SetErrorString("qWatchpointSupportInfo is not supported");
  }
  return error;
}

lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(
    uint32_t &num, bool &after, const ArchSpec &arch) {
  Status error(GetWatchpointSupportInfo(num));
  if (error.Success())
    error = GetWatchpointsTriggerAfterInstruction(after, arch);
  return error;
}

lldb_private::Status
GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
    bool &after, const ArchSpec &arch) {
  Status error;
  llvm::Triple triple = arch.GetTriple();

  // we assume watchpoints will happen after running the relevant opcode and we
  // only want to override this behavior if we have explicitly received a
  // qHostInfo telling us otherwise
  if (m_qHostInfo_is_valid != eLazyBoolYes) {
    // On targets like MIPS and ppc64, watchpoint exceptions are always
    // generated before the instruction is executed. The connected target may
    // not support qHostInfo or qWatchpointSupportInfo packets.
    after = !(triple.isMIPS() || triple.isPPC64());
  } else {
    // For MIPS and ppc64, set m_watchpoints_trigger_after_instruction to
    // eLazyBoolNo if it is not calculated before.
    if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
        (triple.isMIPS() || triple.isPPC64()))
      m_watchpoints_trigger_after_instruction = eLazyBoolNo;

    after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
  }
  return error;
}

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, false) ==
        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, false) ==
        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, false) ==
        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, false) ==
      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, false) ==
        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, false) ==
      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, false) ==
      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, false) ==
        PacketResult::Success) {
      return DecodeProcessInfoResponse(response, process_info);
    } else {
      m_supports_qProcessInfoPID = false;
      return false;
    }
  }
  return false;
}

bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
                                                         GDBR_LOG_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, false) ==
      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;
        }
      }
      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 = 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::Wasm:
        case llvm::Triple::XCOFF:
          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));
        m_host_arch.GetTriple().setVendorName(llvm::StringRef(vendor_name));
        m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
        m_host_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, false) ==
        PacketResult::Success) {
      do {
        ProcessInstanceInfo process_info;
        if (!DecodeProcessInfoResponse(response, process_info))
          break;
        process_infos.push_back(process_info);
        response = StringExtractorGDBRemote();
      } while (SendPacketAndWaitForResponse("qsProcessInfo", response, false) ==
               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, false) ==
        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, false) ==
        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;
}

bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) {
  // Form non-stop packet request
  char packet[32];
  const int packet_len =
      ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
  assert(packet_len < (int)sizeof(packet));
  UNUSED_IF_ASSERT_DISABLED(packet_len);

  StringExtractorGDBRemote response;
  // Send to target
  if (SendPacketAndWaitForResponse(packet, response, false) ==
      PacketResult::Success)
    if (response.IsOKResponse())
      return true;

  // Failed or not supported
  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) {
  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) {
  uint32_t i;
  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 (i = 0; i < num_packets; ++i) {
          const auto packet_start_time = steady_clock::now();
          StringExtractorGDBRemote response;
          SendPacketAndWaitForResponse(packet.GetString(), response, false);
          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 = total_time / num_packets;
        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, false);
          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 = total_time / packet_count;

        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, false) ==
         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, false) ==
      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, false) !=
      PacketResult::Success)
    return 0;

  StructuredData::ObjectSP data =
      StructuredData::ParseJSON(std::string(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->GetIntegerValue(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, false) ==
      PacketResult::Success) {
    if (response.IsOKResponse())
      return true;
  }
  return false;
}

bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
  if (m_curr_tid == tid)
    return true;

  char packet[32];
  int packet_len;
  if (tid == UINT64_MAX)
    packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
  else
    packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
  assert(packet_len + 1 < (int)sizeof(packet));
  UNUSED_IF_ASSERT_DISABLED(packet_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet, response, false) ==
      PacketResult::Success) {
    if (response.IsOKResponse()) {
      m_curr_tid = tid;
      return true;
    }

    /*
     * 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()) {
      m_curr_tid = 1;
      return true;
    }
  }
  return false;
}

bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
  if (m_curr_tid_run == tid)
    return true;

  char packet[32];
  int packet_len;
  if (tid == UINT64_MAX)
    packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
  else
    packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);

  assert(packet_len + 1 < (int)sizeof(packet));
  UNUSED_IF_ASSERT_DISABLED(packet_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(packet, response, false) ==
      PacketResult::Success) {
    if (response.IsOKResponse()) {
      m_curr_tid_run = tid;
      return true;
    }

    /*
     * Connected bare-iron target (like YAMON gdb-stub) may not have support for
     * Hc 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()) {
      m_curr_tid_run = 1;
      return true;
    }
  }
  return false;
}

bool GDBRemoteCommunicationClient::GetStopReply(
    StringExtractorGDBRemote &response) {
  if (SendPacketAndWaitForResponse("?", response, false) ==
      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, false) ==
        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) {
  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_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, true) ==
      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, false);
  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 (!pid_tid)
            return {};

          ids.push_back(pid_tid.getValue());
          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(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
                                                           GDBR_LOG_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, false) !=
          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, false) ==
      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, false) !=
      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.GetU32(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, false) !=
      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.GetU32(UINT32_MAX), eErrorTypePOSIX);
}

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);
  if (result == -2)
    return fail_result;
  if (response.GetChar() == ',') {
    int result_errno = response.GetS32(-2);
    if (result_errno != -2)
      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, false) ==
      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:%i", (int)fd);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
      PacketResult::Success) {
    return ParseHostIOPacketResponse(response, -1, error) == 0;
  }
  return false;
}

// Extension of host I/O packets to get the file size.
lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize(
    const lldb_private::FileSpec &file_spec) {
  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, false) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return UINT64_MAX;
    uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
    return retcode;
  }
  return 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, false) ==
      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) {
  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, false) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F') {
      error.SetErrorStringWithFormat("invalid response to '%s' packet",
                                     stream.GetData());
    } else {
      const uint32_t mode = response.GetS32(-1);
      if (static_cast<int32_t>(mode) == -1) {
        if (response.GetChar() == ',') {
          int response_errno = response.GetS32(-1);
          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);
      }
    }
  } else {
    error.SetErrorStringWithFormat("failed to send '%s' packet",
                                   stream.GetData());
  }
  return error;
}

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:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len,
                offset);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return 0;
    uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX);
    if (retcode == UINT32_MAX)
      return retcode;
    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:%i,%" PRId64 ",", (int)fd, offset);
  stream.PutEscapedBytes(src, src_len);
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F') {
      error.SetErrorStringWithFormat("write file failed");
      return 0;
    }
    uint64_t bytes_written = response.GetU64(UINT64_MAX);
    if (bytes_written == UINT64_MAX) {
      error.SetErrorToGenericError();
      if (response.GetChar() == ',') {
        int response_errno = response.GetS32(-1);
        if (response_errno > 0)
          error.SetError(response_errno, lldb::eErrorTypePOSIX);
      }
      return 0;
    }
    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, false) ==
      PacketResult::Success) {
    if (response.GetChar() == 'F') {
      uint32_t result = response.GetU32(UINT32_MAX);
      if (result != 0) {
        error.SetErrorToGenericError();
        if (response.GetChar() == ',') {
          int response_errno = response.GetS32(-1);
          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, false) ==
      PacketResult::Success) {
    if (response.GetChar() == 'F') {
      uint32_t result = response.GetU32(UINT32_MAX);
      if (result != 0) {
        error.SetErrorToGenericError();
        if (response.GetChar() == ',') {
          int response_errno = response.GetS32(-1);
          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) {
  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, false) ==
      PacketResult::Success) {
    if (response.GetChar() != 'F')
      return false;
    if (response.GetChar() != ',')
      return false;
    bool retcode = (response.GetChar() != '0');
    return retcode;
  }
  return false;
}

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, false) ==
      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, false) != PacketResult::Success ||
      !response.IsNormalResponse())
    return nullptr;

  DataBufferSP 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, false) != PacketResult::Success ||
      !response.IsNormalResponse())
    return nullptr;

  DataBufferSP 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, false) ==
             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, false) ==
             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, false) != 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, false) != 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, false) ==
             GDBRemoteCommunication::PacketResult::Success &&
         response.IsOKResponse();
}

llvm::Expected<TraceSupportedResponse>
GDBRemoteCommunicationClient::SendTraceSupported() {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));

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

  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
                                   true) ==
      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) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_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,
                                   true) ==
      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) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_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,
                                   true) ==
      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) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_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,
                                   true) ==
      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) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_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,
                                   true) ==
      GDBRemoteCommunication::PacketResult::Success) {
    if (response.IsErrorResponse())
      return response.GetStatus().ToError();
    if (response.IsUnsupportedResponse())
      return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                     "jLLDBTraceGetBinaryData is unsupported");
    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());
}

llvm::Optional<QOffsets> GDBRemoteCommunicationClient::GetQOffsets() {
  StringExtractorGDBRemote response;
  if (SendPacketAndWaitForResponse(
          "qOffsets", response, /*send_async=*/false) != PacketResult::Success)
    return llvm::None;
  if (!response.IsNormalResponse())
    return llvm::None;

  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 llvm::None;
    if (!ref.consume_front(";Data=") || !GetOffset())
      return llvm::None;
    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 llvm::None;
    if (ref.empty())
      return result;
    if (ref.consume_front(";DataSeg=") && GetOffset() && ref.empty())
      return result;
  }
  return llvm::None;
}

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, false) !=
      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 llvm::Optional<ModuleSpec>
ParseModuleSpec(StructuredData::Dictionary *dict) {
  ModuleSpec result;
  if (!dict)
    return llvm::None;

  llvm::StringRef string;
  uint64_t integer;

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

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

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

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

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

  return result;
}

llvm::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 llvm::None;

  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, false) !=
          PacketResult::Success ||
      response.IsErrorResponse())
    return llvm::None;

  if (response.IsUnsupportedResponse()) {
    m_supports_jModulesInfo = false;
    return llvm::None;
  }

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

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

  std::vector<ModuleSpec> result;
  for (size_t i = 0; i < response_array->GetSize(); ++i) {
    if (llvm::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', out=<xml output> return:
// 'true'  on success
//          'false' on failure (err set)
bool GDBRemoteCommunicationClient::ReadExtFeature(
    const lldb_private::ConstString object,
    const lldb_private::ConstString annex, std::string &out,
    lldb_private::Status &err) {

  std::stringstream 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::stringstream packet;
    packet << "qXfer:" << object.AsCString("")
           << ":read:" << annex.AsCString("") << ":" << std::hex << offset
           << "," << std::hex << size;

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

    if (res != GDBRemoteCommunication::PacketResult::Success) {
      err.SetErrorString("Error sending $qXfer packet");
      return false;
    }

    const std::string &str = std::string(chunk.GetStringRef());
    if (str.length() == 0) {
      // should have some data in chunk
      err.SetErrorString("Empty response from $qXfer packet");
      return false;
    }

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

    // more chunks
    case ('m'):
      if (str.length() > 1)
        output << &str[1];
      offset += str.length() - 1;
      break;

    // unknown chunk
    default:
      err.SetErrorString("Invalid continuation code from $qXfer packet");
      return false;
    }
  }

  out = output.str();
  err.Success();
  return true;
}

// 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, false);
    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);
              if (!sc_list.IsEmpty()) {
                const size_t num_scs = sc_list.GetSize();
                for (size_t sc_idx = 0;
                     sc_idx < num_scs &&
                     symbol_load_addr == LLDB_INVALID_ADDRESS;
                     ++sc_idx) {
                  SymbolContext sc;
                  if (sc_list.GetContextAtIndex(sc_idx, sc)) {
                    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 = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
                   GDBR_LOG_PROCESS | GDBR_LOG_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(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));

    // Poll it now.
    StringExtractorGDBRemote response;
    const bool send_async = false;
    if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
                                     send_async) == PacketResult::Success) {
      m_supported_async_json_packets_sp =
          StructuredData::ParseJSON(std::string(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, false);

  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.
  const bool send_async = false;
  StringExtractorGDBRemote response;
  auto result =
      SendPacketAndWaitForResponse(stream.GetString(), response, send_async);
  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;
}
