//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CommunicationKDP.h"

// C Includes
#include <errno.h>
#include <limits.h>
#include <string.h>

// C++ Includes

// Other libraries and framework includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Core/UUID.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"

// Project includes
#include "ProcessKDPLog.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// CommunicationKDP constructor
//----------------------------------------------------------------------
CommunicationKDP::CommunicationKDP(const char *comm_name)
    : Communication(comm_name), m_addr_byte_size(4),
      m_byte_order(eByteOrderLittle), m_packet_timeout(5), m_sequence_mutex(),
      m_is_running(false), m_session_key(0u), m_request_sequence_id(0u),
      m_exception_sequence_id(0u), m_kdp_version_version(0u),
      m_kdp_version_feature(0u), m_kdp_hostinfo_cpu_mask(0u),
      m_kdp_hostinfo_cpu_type(0u), m_kdp_hostinfo_cpu_subtype(0u) {}

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

bool CommunicationKDP::SendRequestPacket(
    const PacketStreamType &request_packet) {
  std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
  return SendRequestPacketNoLock(request_packet);
}

#if 0
typedef struct {
	uint8_t     request;	// Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply
	uint8_t     sequence;
	uint16_t    length;		// Length of entire packet including this header
	uint32_t	key;		// Session key
} kdp_hdr_t;
#endif

void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type,
                                               PacketStreamType &request_packet,
                                               uint16_t request_length) {
  request_packet.Clear();
  request_packet.PutHex8(request_type |
                         ePacketTypeRequest);      // Set the request type
  request_packet.PutHex8(m_request_sequence_id++); // Sequence number
  request_packet.PutHex16(
      request_length); // Length of the packet including this header
  request_packet.PutHex32(m_session_key); // Session key
}

bool CommunicationKDP::SendRequestAndGetReply(
    const CommandType command, const PacketStreamType &request_packet,
    DataExtractor &reply_packet) {
  if (IsRunning()) {
    Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
    if (log) {
      PacketStreamType log_strm;
      DumpPacket(log_strm, request_packet.GetData(), request_packet.GetSize());
      log->Printf("error: kdp running, not sending packet: %.*s",
                  (uint32_t)log_strm.GetSize(), log_strm.GetData());
    }
    return false;
  }

  std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
#ifdef LLDB_CONFIGURATION_DEBUG
  // NOTE: this only works for packets that are in native endian byte order
  assert(request_packet.GetSize() ==
         *((uint16_t *)(request_packet.GetData() + 2)));
#endif
  lldb::offset_t offset = 1;
  const uint32_t num_retries = 3;
  for (uint32_t i = 0; i < num_retries; ++i) {
    if (SendRequestPacketNoLock(request_packet)) {
      const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
      while (1) {
        if (WaitForPacketWithTimeoutMicroSecondsNoLock(
                reply_packet, GetPacketTimeoutInMicroSeconds())) {
          offset = 0;
          const uint8_t reply_command = reply_packet.GetU8(&offset);
          const uint8_t reply_sequence_id = reply_packet.GetU8(&offset);
          if (request_sequence_id == reply_sequence_id) {
            // The sequent ID was correct, now verify we got the response we
            // were looking for
            if ((reply_command & eCommandTypeMask) == command) {
              // Success
              if (command == KDP_RESUMECPUS)
                m_is_running.SetValue(true, eBroadcastAlways);
              return true;
            } else {
              // Failed to get the correct response, bail
              reply_packet.Clear();
              return false;
            }
          } else if (reply_sequence_id > request_sequence_id) {
            // Sequence ID was greater than the sequence ID of the packet we
            // sent, something
            // is really wrong...
            reply_packet.Clear();
            return false;
          } else {
            // The reply sequence ID was less than our current packet's sequence
            // ID
            // so we should keep trying to get a response because this was a
            // response
            // for a previous packet that we must have retried.
          }
        } else {
          // Break and retry sending the packet as we didn't get a response due
          // to timeout
          break;
        }
      }
    }
  }
  reply_packet.Clear();
  return false;
}

bool CommunicationKDP::SendRequestPacketNoLock(
    const PacketStreamType &request_packet) {
  if (IsConnected()) {
    const char *packet_data = request_packet.GetData();
    const size_t packet_size = request_packet.GetSize();

    Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
    if (log) {
      PacketStreamType log_strm;
      DumpPacket(log_strm, packet_data, packet_size);
      log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
    }
    ConnectionStatus status = eConnectionStatusSuccess;

    size_t bytes_written = Write(packet_data, packet_size, status, NULL);

    if (bytes_written == packet_size)
      return true;

    if (log)
      log->Printf("error: failed to send packet entire packet %" PRIu64
                  " of %" PRIu64 " bytes sent",
                  (uint64_t)bytes_written, (uint64_t)packet_size);
  }
  return false;
}

bool CommunicationKDP::GetSequenceMutex(
    std::unique_lock<std::recursive_mutex> &lock) {
  return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex,
                                                        std::try_to_lock))
      .owns_lock();
}

bool CommunicationKDP::WaitForNotRunningPrivate(
    const std::chrono::microseconds &timeout) {
  return m_is_running.WaitForValueEqualTo(false, timeout, NULL);
}

size_t
CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds(DataExtractor &packet,
                                                       uint32_t timeout_usec) {
  std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
  return WaitForPacketWithTimeoutMicroSecondsNoLock(packet, timeout_usec);
}

size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock(
    DataExtractor &packet, uint32_t timeout_usec) {
  uint8_t buffer[8192];
  Error error;

  Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS |
                                                   KDP_LOG_VERBOSE));

  // Check for a packet from our cache first without trying any reading...
  if (CheckForPacket(NULL, 0, packet))
    return packet.GetByteSize();

  bool timed_out = false;
  while (IsConnected() && !timed_out) {
    lldb::ConnectionStatus status = eConnectionStatusNoConnection;
    size_t bytes_read =
        Read(buffer, sizeof(buffer), timeout_usec, status, &error);

    if (log)
      log->Printf("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, "
                  "status = %s, error = %s) => bytes_read = %" PRIu64,
                  LLVM_PRETTY_FUNCTION, timeout_usec,
                  Communication::ConnectionStatusAsCString(status),
                  error.AsCString(), (uint64_t)bytes_read);

    if (bytes_read > 0) {
      if (CheckForPacket(buffer, bytes_read, packet))
        return packet.GetByteSize();
    } else {
      switch (status) {
      case eConnectionStatusInterrupted:
      case eConnectionStatusTimedOut:
        timed_out = true;
        break;
      case eConnectionStatusSuccess:
        // printf ("status = success but error = %s\n",
        // error.AsCString("<invalid>"));
        break;

      case eConnectionStatusEndOfFile:
      case eConnectionStatusNoConnection:
      case eConnectionStatusLostConnection:
      case eConnectionStatusError:
        Disconnect();
        break;
      }
    }
  }
  packet.Clear();
  return 0;
}

bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
                                      DataExtractor &packet) {
  // Put the packet data into the buffer in a thread safe fashion
  std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);

  Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));

  if (src && src_len > 0) {
    if (log && log->GetVerbose()) {
      PacketStreamType log_strm;
      DataExtractor::DumpHexBytes(&log_strm, src, src_len, UINT32_MAX,
                                  LLDB_INVALID_ADDRESS);
      log->Printf("CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__,
                  (uint32_t)src_len, log_strm.GetData());
    }
    m_bytes.append((const char *)src, src_len);
  }

  // Make sure we at least have enough bytes for a packet header
  const size_t bytes_available = m_bytes.size();
  if (bytes_available >= 8) {
    packet.SetData(&m_bytes[0], bytes_available, m_byte_order);
    lldb::offset_t offset = 0;
    uint8_t reply_command = packet.GetU8(&offset);
    switch (reply_command) {
    case ePacketTypeRequest | KDP_EXCEPTION:
    case ePacketTypeRequest | KDP_TERMINATION:
      // We got an exception request, so be sure to send an ACK
      {
        PacketStreamType request_ack_packet(Stream::eBinary, m_addr_byte_size,
                                            m_byte_order);
        // Set the reply but and make the ACK packet
        request_ack_packet.PutHex8(reply_command | ePacketTypeReply);
        request_ack_packet.PutHex8(packet.GetU8(&offset));
        request_ack_packet.PutHex16(packet.GetU16(&offset));
        request_ack_packet.PutHex32(packet.GetU32(&offset));
        m_is_running.SetValue(false, eBroadcastAlways);
        // Ack to the exception or termination
        SendRequestPacketNoLock(request_ack_packet);
      }
      // Fall through to case below to get packet contents
      LLVM_FALLTHROUGH;
    case ePacketTypeReply | KDP_CONNECT:
    case ePacketTypeReply | KDP_DISCONNECT:
    case ePacketTypeReply | KDP_HOSTINFO:
    case ePacketTypeReply | KDP_VERSION:
    case ePacketTypeReply | KDP_MAXBYTES:
    case ePacketTypeReply | KDP_READMEM:
    case ePacketTypeReply | KDP_WRITEMEM:
    case ePacketTypeReply | KDP_READREGS:
    case ePacketTypeReply | KDP_WRITEREGS:
    case ePacketTypeReply | KDP_LOAD:
    case ePacketTypeReply | KDP_IMAGEPATH:
    case ePacketTypeReply | KDP_SUSPEND:
    case ePacketTypeReply | KDP_RESUMECPUS:
    case ePacketTypeReply | KDP_BREAKPOINT_SET:
    case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
    case ePacketTypeReply | KDP_REGIONS:
    case ePacketTypeReply | KDP_REATTACH:
    case ePacketTypeReply | KDP_HOSTREBOOT:
    case ePacketTypeReply | KDP_READMEM64:
    case ePacketTypeReply | KDP_WRITEMEM64:
    case ePacketTypeReply | KDP_BREAKPOINT_SET64:
    case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
    case ePacketTypeReply | KDP_KERNELVERSION:
    case ePacketTypeReply | KDP_READPHYSMEM64:
    case ePacketTypeReply | KDP_WRITEPHYSMEM64:
    case ePacketTypeReply | KDP_READIOPORT:
    case ePacketTypeReply | KDP_WRITEIOPORT:
    case ePacketTypeReply | KDP_READMSR64:
    case ePacketTypeReply | KDP_WRITEMSR64:
    case ePacketTypeReply | KDP_DUMPINFO: {
      offset = 2;
      const uint16_t length = packet.GetU16(&offset);
      if (length <= bytes_available) {
        // We have an entire packet ready, we need to copy the data
        // bytes into a buffer that will be owned by the packet and
        // erase the bytes from our communcation buffer "m_bytes"
        packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length)));
        m_bytes.erase(0, length);

        if (log) {
          PacketStreamType log_strm;
          DumpPacket(log_strm, packet);

          log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
        }
        return true;
      }
    } break;

    default:
      // Unrecognized reply command byte, erase this byte and try to get back on
      // track
      if (log)
        log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
                    __FUNCTION__, (uint8_t)m_bytes[0]);
      m_bytes.erase(0, 1);
      break;
    }
  }
  packet.Clear();
  return false;
}

bool CommunicationKDP::SendRequestConnect(uint16_t reply_port,
                                          uint16_t exc_port,
                                          const char *greeting) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  if (greeting == NULL)
    greeting = "";

  const CommandType command = KDP_CONNECT;
  // Length is 82 uint16_t and the length of the greeting C string with the
  // terminating NULL
  const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
  MakeRequestPacketHeader(command, request_packet, command_length);
  // Always send connect ports as little endian
  request_packet.SetByteOrder(eByteOrderLittle);
  request_packet.PutHex16(htons(reply_port));
  request_packet.PutHex16(htons(exc_port));
  request_packet.SetByteOrder(m_byte_order);
  request_packet.PutCString(greeting);
  DataExtractor reply_packet;
  return SendRequestAndGetReply(command, request_packet, reply_packet);
}

void CommunicationKDP::ClearKDPSettings() {
  m_request_sequence_id = 0;
  m_kdp_version_version = 0;
  m_kdp_version_feature = 0;
  m_kdp_hostinfo_cpu_mask = 0;
  m_kdp_hostinfo_cpu_type = 0;
  m_kdp_hostinfo_cpu_subtype = 0;
}

bool CommunicationKDP::SendRequestReattach(uint16_t reply_port) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_REATTACH;
  // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
  const uint32_t command_length = 8 + 2;
  MakeRequestPacketHeader(command, request_packet, command_length);
  // Always send connect ports as little endian
  request_packet.SetByteOrder(eByteOrderLittle);
  request_packet.PutHex16(htons(reply_port));
  request_packet.SetByteOrder(m_byte_order);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    // Reset the sequence ID to zero for reattach
    ClearKDPSettings();
    lldb::offset_t offset = 4;
    m_session_key = reply_packet.GetU32(&offset);
    return true;
  }
  return false;
}

uint32_t CommunicationKDP::GetVersion() {
  if (!VersionIsValid())
    SendRequestVersion();
  return m_kdp_version_version;
}

uint32_t CommunicationKDP::GetFeatureFlags() {
  if (!VersionIsValid())
    SendRequestVersion();
  return m_kdp_version_feature;
}

bool CommunicationKDP::SendRequestVersion() {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_VERSION;
  const uint32_t command_length = 8;
  MakeRequestPacketHeader(command, request_packet, command_length);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    m_kdp_version_version = reply_packet.GetU32(&offset);
    m_kdp_version_feature = reply_packet.GetU32(&offset);
    return true;
  }
  return false;
}

#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
const char *
CommunicationKDP::GetImagePath ()
{
    if (m_image_path.empty())
        SendRequestImagePath();
    return m_image_path.c_str();
}

bool
CommunicationKDP::SendRequestImagePath ()
{
    PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
    const CommandType command = KDP_IMAGEPATH;
    const uint32_t command_length = 8;
    MakeRequestPacketHeader (command, request_packet, command_length);
    DataExtractor reply_packet;
    if (SendRequestAndGetReply (command, request_packet, reply_packet))
    {
        const char *path = reply_packet.PeekCStr(8);
        if (path && path[0])
            m_kernel_version.assign (path);
        return true;
    }
    return false;
}
#endif

uint32_t CommunicationKDP::GetCPUMask() {
  if (!HostInfoIsValid())
    SendRequestHostInfo();
  return m_kdp_hostinfo_cpu_mask;
}

uint32_t CommunicationKDP::GetCPUType() {
  if (!HostInfoIsValid())
    SendRequestHostInfo();
  return m_kdp_hostinfo_cpu_type;
}

uint32_t CommunicationKDP::GetCPUSubtype() {
  if (!HostInfoIsValid())
    SendRequestHostInfo();
  return m_kdp_hostinfo_cpu_subtype;
}

lldb_private::UUID CommunicationKDP::GetUUID() {
  UUID uuid;
  if (GetKernelVersion() == NULL)
    return uuid;

  if (m_kernel_version.find("UUID=") == std::string::npos)
    return uuid;

  size_t p = m_kernel_version.find("UUID=") + strlen("UUID=");
  std::string uuid_str = m_kernel_version.substr(p, 36);
  if (uuid_str.size() < 32)
    return uuid;

  if (uuid.SetFromCString(uuid_str.c_str()) == 0) {
    UUID invalid_uuid;
    return invalid_uuid;
  }

  return uuid;
}

bool CommunicationKDP::RemoteIsEFI() {
  if (GetKernelVersion() == NULL)
    return false;
  if (strncmp(m_kernel_version.c_str(), "EFI", 3) == 0)
    return true;
  else
    return false;
}

bool CommunicationKDP::RemoteIsDarwinKernel() {
  if (GetKernelVersion() == NULL)
    return false;
  if (m_kernel_version.find("Darwin Kernel") != std::string::npos)
    return true;
  else
    return false;
}

lldb::addr_t CommunicationKDP::GetLoadAddress() {
  if (GetKernelVersion() == NULL)
    return LLDB_INVALID_ADDRESS;

  if (m_kernel_version.find("stext=") == std::string::npos)
    return LLDB_INVALID_ADDRESS;
  size_t p = m_kernel_version.find("stext=") + strlen("stext=");
  if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
    return LLDB_INVALID_ADDRESS;

  addr_t kernel_load_address;
  errno = 0;
  kernel_load_address = ::strtoul(m_kernel_version.c_str() + p, NULL, 16);
  if (errno != 0 || kernel_load_address == 0)
    return LLDB_INVALID_ADDRESS;

  return kernel_load_address;
}

bool CommunicationKDP::SendRequestHostInfo() {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_HOSTINFO;
  const uint32_t command_length = 8;
  MakeRequestPacketHeader(command, request_packet, command_length);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    m_kdp_hostinfo_cpu_mask = reply_packet.GetU32(&offset);
    m_kdp_hostinfo_cpu_type = reply_packet.GetU32(&offset);
    m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32(&offset);

    ArchSpec kernel_arch;
    kernel_arch.SetArchitecture(eArchTypeMachO, m_kdp_hostinfo_cpu_type,
                                m_kdp_hostinfo_cpu_subtype);

    m_addr_byte_size = kernel_arch.GetAddressByteSize();
    m_byte_order = kernel_arch.GetByteOrder();
    return true;
  }
  return false;
}

const char *CommunicationKDP::GetKernelVersion() {
  if (m_kernel_version.empty())
    SendRequestKernelVersion();
  return m_kernel_version.c_str();
}

bool CommunicationKDP::SendRequestKernelVersion() {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_KERNELVERSION;
  const uint32_t command_length = 8;
  MakeRequestPacketHeader(command, request_packet, command_length);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    const char *kernel_version_cstr = reply_packet.PeekCStr(8);
    if (kernel_version_cstr && kernel_version_cstr[0])
      m_kernel_version.assign(kernel_version_cstr);
    return true;
  }
  return false;
}

bool CommunicationKDP::SendRequestDisconnect() {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_DISCONNECT;
  const uint32_t command_length = 8;
  MakeRequestPacketHeader(command, request_packet, command_length);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    // Are we supposed to get a reply for disconnect?
  }
  ClearKDPSettings();
  return true;
}

uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst,
                                                 uint32_t dst_len,
                                                 Error &error) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  bool use_64 = (GetVersion() >= 11);
  uint32_t command_addr_byte_size = use_64 ? 8 : 4;
  const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
  // Size is header + address size + uint32_t length
  const uint32_t command_length = 8 + command_addr_byte_size + 4;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutMaxHex64(addr, command_addr_byte_size);
  request_packet.PutHex32(dst_len);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    uint32_t kdp_error = reply_packet.GetU32(&offset);
    uint32_t src_len = reply_packet.GetByteSize() - 12;

    if (src_len > 0) {
      const void *src = reply_packet.GetData(&offset, src_len);
      if (src) {
        ::memcpy(dst, src, src_len);
        error.Clear();
        return src_len;
      }
    }
    if (kdp_error)
      error.SetErrorStringWithFormat("kdp read memory failed (error %u)",
                                     kdp_error);
    else
      error.SetErrorString("kdp read memory failed");
  } else {
    error.SetErrorString("failed to send packet");
  }
  return 0;
}

uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr,
                                                  const void *src,
                                                  uint32_t src_len,
                                                  Error &error) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  bool use_64 = (GetVersion() >= 11);
  uint32_t command_addr_byte_size = use_64 ? 8 : 4;
  const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
  // Size is header + address size + uint32_t length
  const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutMaxHex64(addr, command_addr_byte_size);
  request_packet.PutHex32(src_len);
  request_packet.PutRawBytes(src, src_len);

  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    uint32_t kdp_error = reply_packet.GetU32(&offset);
    if (kdp_error)
      error.SetErrorStringWithFormat("kdp write memory failed (error %u)",
                                     kdp_error);
    else {
      error.Clear();
      return src_len;
    }
  } else {
    error.SetErrorString("failed to send packet");
  }
  return 0;
}

bool CommunicationKDP::SendRawRequest(
    uint8_t command_byte,
    const void *src,  // Raw packet payload bytes
    uint32_t src_len, // Raw packet payload length
    DataExtractor &reply_packet, Error &error) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  // Size is header + address size + uint32_t length
  const uint32_t command_length = 8 + src_len;
  const CommandType command = (CommandType)command_byte;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutRawBytes(src, src_len);

  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    uint32_t kdp_error = reply_packet.GetU32(&offset);
    if (kdp_error && (command_byte != KDP_DUMPINFO))
      error.SetErrorStringWithFormat("request packet 0x%8.8x failed (error %u)",
                                     command_byte, kdp_error);
    else {
      error.Clear();
      return true;
    }
  } else {
    error.SetErrorString("failed to send packet");
  }
  return false;
}

const char *CommunicationKDP::GetCommandAsCString(uint8_t command) {
  switch (command) {
  case KDP_CONNECT:
    return "KDP_CONNECT";
  case KDP_DISCONNECT:
    return "KDP_DISCONNECT";
  case KDP_HOSTINFO:
    return "KDP_HOSTINFO";
  case KDP_VERSION:
    return "KDP_VERSION";
  case KDP_MAXBYTES:
    return "KDP_MAXBYTES";
  case KDP_READMEM:
    return "KDP_READMEM";
  case KDP_WRITEMEM:
    return "KDP_WRITEMEM";
  case KDP_READREGS:
    return "KDP_READREGS";
  case KDP_WRITEREGS:
    return "KDP_WRITEREGS";
  case KDP_LOAD:
    return "KDP_LOAD";
  case KDP_IMAGEPATH:
    return "KDP_IMAGEPATH";
  case KDP_SUSPEND:
    return "KDP_SUSPEND";
  case KDP_RESUMECPUS:
    return "KDP_RESUMECPUS";
  case KDP_EXCEPTION:
    return "KDP_EXCEPTION";
  case KDP_TERMINATION:
    return "KDP_TERMINATION";
  case KDP_BREAKPOINT_SET:
    return "KDP_BREAKPOINT_SET";
  case KDP_BREAKPOINT_REMOVE:
    return "KDP_BREAKPOINT_REMOVE";
  case KDP_REGIONS:
    return "KDP_REGIONS";
  case KDP_REATTACH:
    return "KDP_REATTACH";
  case KDP_HOSTREBOOT:
    return "KDP_HOSTREBOOT";
  case KDP_READMEM64:
    return "KDP_READMEM64";
  case KDP_WRITEMEM64:
    return "KDP_WRITEMEM64";
  case KDP_BREAKPOINT_SET64:
    return "KDP_BREAKPOINT64_SET";
  case KDP_BREAKPOINT_REMOVE64:
    return "KDP_BREAKPOINT64_REMOVE";
  case KDP_KERNELVERSION:
    return "KDP_KERNELVERSION";
  case KDP_READPHYSMEM64:
    return "KDP_READPHYSMEM64";
  case KDP_WRITEPHYSMEM64:
    return "KDP_WRITEPHYSMEM64";
  case KDP_READIOPORT:
    return "KDP_READIOPORT";
  case KDP_WRITEIOPORT:
    return "KDP_WRITEIOPORT";
  case KDP_READMSR64:
    return "KDP_READMSR64";
  case KDP_WRITEMSR64:
    return "KDP_WRITEMSR64";
  case KDP_DUMPINFO:
    return "KDP_DUMPINFO";
  }
  return NULL;
}

void CommunicationKDP::DumpPacket(Stream &s, const void *data,
                                  uint32_t data_len) {
  DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size);
  DumpPacket(s, extractor);
}

void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) {
  const char *error_desc = NULL;
  if (packet.GetByteSize() < 8) {
    error_desc = "error: invalid packet (too short): ";
  } else {
    lldb::offset_t offset = 0;
    const uint8_t first_packet_byte = packet.GetU8(&offset);
    const uint8_t sequence_id = packet.GetU8(&offset);
    const uint16_t length = packet.GetU16(&offset);
    const uint32_t key = packet.GetU32(&offset);
    const CommandType command = ExtractCommand(first_packet_byte);
    const char *command_name = GetCommandAsCString(command);
    if (command_name) {
      const bool is_reply = ExtractIsReply(first_packet_byte);
      s.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
               IsRunning(), is_reply ? "<--" : "-->", command_name,
               first_packet_byte, sequence_id, length, key);

      if (is_reply) {
        // Dump request reply packets
        switch (command) {
        // Commands that return a single 32 bit error
        case KDP_CONNECT:
        case KDP_WRITEMEM:
        case KDP_WRITEMEM64:
        case KDP_BREAKPOINT_SET:
        case KDP_BREAKPOINT_REMOVE:
        case KDP_BREAKPOINT_SET64:
        case KDP_BREAKPOINT_REMOVE64:
        case KDP_WRITEREGS:
        case KDP_LOAD:
        case KDP_WRITEIOPORT:
        case KDP_WRITEMSR64: {
          const uint32_t error = packet.GetU32(&offset);
          s.Printf(" (error=0x%8.8x)", error);
        } break;

        case KDP_DISCONNECT:
        case KDP_REATTACH:
        case KDP_HOSTREBOOT:
        case KDP_SUSPEND:
        case KDP_RESUMECPUS:
        case KDP_EXCEPTION:
        case KDP_TERMINATION:
          // No return value for the reply, just the header to ack
          s.PutCString(" ()");
          break;

        case KDP_HOSTINFO: {
          const uint32_t cpu_mask = packet.GetU32(&offset);
          const uint32_t cpu_type = packet.GetU32(&offset);
          const uint32_t cpu_subtype = packet.GetU32(&offset);
          s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)",
                   cpu_mask, cpu_type, cpu_subtype);
        } break;

        case KDP_VERSION: {
          const uint32_t version = packet.GetU32(&offset);
          const uint32_t feature = packet.GetU32(&offset);
          s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
        } break;

        case KDP_REGIONS: {
          const uint32_t region_count = packet.GetU32(&offset);
          s.Printf(" (count = %u", region_count);
          for (uint32_t i = 0; i < region_count; ++i) {
            const addr_t region_addr = packet.GetPointer(&offset);
            const uint32_t region_size = packet.GetU32(&offset);
            const uint32_t region_prot = packet.GetU32(&offset);
            s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64
                     " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }",
                     region_addr, region_addr, region_addr + region_size,
                     region_size, GetPermissionsAsCString(region_prot));
          }
        } break;

        case KDP_READMEM:
        case KDP_READMEM64:
        case KDP_READPHYSMEM64: {
          const uint32_t error = packet.GetU32(&offset);
          const uint32_t count = packet.GetByteSize() - offset;
          s.Printf(" (error = 0x%8.8x:\n", error);
          if (count > 0)
            packet.Dump(&s,                      // Stream to dump to
                        offset,                  // Offset within "packet"
                        eFormatBytesWithASCII,   // Format to use
                        1,                       // Size of each item in bytes
                        count,                   // Number of items
                        16,                      // Number per line
                        m_last_read_memory_addr, // Don't show addresses before
                                                 // each line
                        0, 0);                   // No bitfields
        } break;

        case KDP_READREGS: {
          const uint32_t error = packet.GetU32(&offset);
          const uint32_t count = packet.GetByteSize() - offset;
          s.Printf(" (error = 0x%8.8x regs:\n", error);
          if (count > 0)
            packet.Dump(
                &s,                       // Stream to dump to
                offset,                   // Offset within "packet"
                eFormatHex,               // Format to use
                m_addr_byte_size,         // Size of each item in bytes
                count / m_addr_byte_size, // Number of items
                16 / m_addr_byte_size,    // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields
        } break;

        case KDP_KERNELVERSION: {
          const char *kernel_version = packet.PeekCStr(8);
          s.Printf(" (version = \"%s\")", kernel_version);
        } break;

        case KDP_MAXBYTES: {
          const uint32_t max_bytes = packet.GetU32(&offset);
          s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
        } break;
        case KDP_IMAGEPATH: {
          const char *path = packet.GetCStr(&offset);
          s.Printf(" (path = \"%s\")", path);
        } break;

        case KDP_READIOPORT:
        case KDP_READMSR64: {
          const uint32_t error = packet.GetU32(&offset);
          const uint32_t count = packet.GetByteSize() - offset;
          s.Printf(" (error = 0x%8.8x io:\n", error);
          if (count > 0)
            packet.Dump(
                &s,                   // Stream to dump to
                offset,               // Offset within "packet"
                eFormatHex,           // Format to use
                1,                    // Size of each item in bytes
                count,                // Number of items
                16,                   // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields
        } break;
        case KDP_DUMPINFO: {
          const uint32_t count = packet.GetByteSize() - offset;
          s.Printf(" (count = %u, bytes = \n", count);
          if (count > 0)
            packet.Dump(
                &s,                   // Stream to dump to
                offset,               // Offset within "packet"
                eFormatHex,           // Format to use
                1,                    // Size of each item in bytes
                count,                // Number of items
                16,                   // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields

        } break;

        default:
          s.Printf(" (add support for dumping this packet reply!!!");
          break;
        }
      } else {
        // Dump request packets
        switch (command) {
        case KDP_CONNECT: {
          const uint16_t reply_port = ntohs(packet.GetU16(&offset));
          const uint16_t exc_port = ntohs(packet.GetU16(&offset));
          s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")",
                   reply_port, exc_port, packet.GetCStr(&offset));
        } break;

        case KDP_DISCONNECT:
        case KDP_HOSTREBOOT:
        case KDP_HOSTINFO:
        case KDP_VERSION:
        case KDP_REGIONS:
        case KDP_KERNELVERSION:
        case KDP_MAXBYTES:
        case KDP_IMAGEPATH:
        case KDP_SUSPEND:
          // No args, just the header in the request...
          s.PutCString(" ()");
          break;

        case KDP_RESUMECPUS: {
          const uint32_t cpu_mask = packet.GetU32(&offset);
          s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
        } break;

        case KDP_READMEM: {
          const uint32_t addr = packet.GetU32(&offset);
          const uint32_t size = packet.GetU32(&offset);
          s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
          m_last_read_memory_addr = addr;
        } break;

        case KDP_WRITEMEM: {
          const uint32_t addr = packet.GetU32(&offset);
          const uint32_t size = packet.GetU32(&offset);
          s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
          if (size > 0)
            DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
                                        32, addr);
        } break;

        case KDP_READMEM64: {
          const uint64_t addr = packet.GetU64(&offset);
          const uint32_t size = packet.GetU32(&offset);
          s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
          m_last_read_memory_addr = addr;
        } break;

        case KDP_READPHYSMEM64: {
          const uint64_t addr = packet.GetU64(&offset);
          const uint32_t size = packet.GetU32(&offset);
          const uint32_t lcpu = packet.GetU16(&offset);
          s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size,
                   lcpu);
          m_last_read_memory_addr = addr;
        } break;

        case KDP_WRITEMEM64: {
          const uint64_t addr = packet.GetU64(&offset);
          const uint32_t size = packet.GetU32(&offset);
          s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr,
                   size);
          if (size > 0)
            DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
                                        32, addr);
        } break;

        case KDP_WRITEPHYSMEM64: {
          const uint64_t addr = packet.GetU64(&offset);
          const uint32_t size = packet.GetU32(&offset);
          const uint32_t lcpu = packet.GetU16(&offset);
          s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n",
                   addr, size, lcpu);
          if (size > 0)
            DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size,
                                        32, addr);
        } break;

        case KDP_READREGS: {
          const uint32_t cpu = packet.GetU32(&offset);
          const uint32_t flavor = packet.GetU32(&offset);
          s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
        } break;

        case KDP_WRITEREGS: {
          const uint32_t cpu = packet.GetU32(&offset);
          const uint32_t flavor = packet.GetU32(&offset);
          const uint32_t nbytes = packet.GetByteSize() - offset;
          s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
          if (nbytes > 0)
            packet.Dump(
                &s,                        // Stream to dump to
                offset,                    // Offset within "packet"
                eFormatHex,                // Format to use
                m_addr_byte_size,          // Size of each item in bytes
                nbytes / m_addr_byte_size, // Number of items
                16 / m_addr_byte_size,     // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields
        } break;

        case KDP_BREAKPOINT_SET:
        case KDP_BREAKPOINT_REMOVE: {
          const uint32_t addr = packet.GetU32(&offset);
          s.Printf(" (addr = 0x%8.8x)", addr);
        } break;

        case KDP_BREAKPOINT_SET64:
        case KDP_BREAKPOINT_REMOVE64: {
          const uint64_t addr = packet.GetU64(&offset);
          s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
        } break;

        case KDP_LOAD: {
          const char *path = packet.GetCStr(&offset);
          s.Printf(" (path = \"%s\")", path);
        } break;

        case KDP_EXCEPTION: {
          const uint32_t count = packet.GetU32(&offset);

          for (uint32_t i = 0; i < count; ++i) {
            const uint32_t cpu = packet.GetU32(&offset);
            const uint32_t exc = packet.GetU32(&offset);
            const uint32_t code = packet.GetU32(&offset);
            const uint32_t subcode = packet.GetU32(&offset);
            const char *exc_cstr = NULL;
            switch (exc) {
            case 1:
              exc_cstr = "EXC_BAD_ACCESS";
              break;
            case 2:
              exc_cstr = "EXC_BAD_INSTRUCTION";
              break;
            case 3:
              exc_cstr = "EXC_ARITHMETIC";
              break;
            case 4:
              exc_cstr = "EXC_EMULATION";
              break;
            case 5:
              exc_cstr = "EXC_SOFTWARE";
              break;
            case 6:
              exc_cstr = "EXC_BREAKPOINT";
              break;
            case 7:
              exc_cstr = "EXC_SYSCALL";
              break;
            case 8:
              exc_cstr = "EXC_MACH_SYSCALL";
              break;
            case 9:
              exc_cstr = "EXC_RPC_ALERT";
              break;
            case 10:
              exc_cstr = "EXC_CRASH";
              break;
            default:
              break;
            }

            s.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), "
                     "subcode = %u (0x%8.8x)} ",
                     cpu, exc_cstr, exc, code, code, subcode, subcode);
          }
        } break;

        case KDP_TERMINATION: {
          const uint32_t term_code = packet.GetU32(&offset);
          const uint32_t exit_code = packet.GetU32(&offset);
          s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))",
                   term_code, term_code, exit_code, exit_code);
        } break;

        case KDP_REATTACH: {
          const uint16_t reply_port = ntohs(packet.GetU16(&offset));
          s.Printf(" (reply_port = %u)", reply_port);
        } break;

        case KDP_READMSR64: {
          const uint32_t address = packet.GetU32(&offset);
          const uint16_t lcpu = packet.GetU16(&offset);
          s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
        } break;

        case KDP_WRITEMSR64: {
          const uint32_t address = packet.GetU32(&offset);
          const uint16_t lcpu = packet.GetU16(&offset);
          const uint32_t nbytes = packet.GetByteSize() - offset;
          s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu,
                   address, nbytes);
          if (nbytes > 0)
            packet.Dump(
                &s,                   // Stream to dump to
                offset,               // Offset within "packet"
                eFormatHex,           // Format to use
                1,                    // Size of each item in bytes
                nbytes,               // Number of items
                16,                   // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields
        } break;

        case KDP_READIOPORT: {
          const uint16_t lcpu = packet.GetU16(&offset);
          const uint16_t address = packet.GetU16(&offset);
          const uint16_t nbytes = packet.GetU16(&offset);
          s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address,
                   nbytes);
        } break;

        case KDP_WRITEIOPORT: {
          const uint16_t lcpu = packet.GetU16(&offset);
          const uint16_t address = packet.GetU16(&offset);
          const uint16_t nbytes = packet.GetU16(&offset);
          s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu,
                   address, nbytes);
          if (nbytes > 0)
            packet.Dump(
                &s,                   // Stream to dump to
                offset,               // Offset within "packet"
                eFormatHex,           // Format to use
                1,                    // Size of each item in bytes
                nbytes,               // Number of items
                16,                   // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields
        } break;

        case KDP_DUMPINFO: {
          const uint32_t count = packet.GetByteSize() - offset;
          s.Printf(" (count = %u, bytes = \n", count);
          if (count > 0)
            packet.Dump(
                &s,                   // Stream to dump to
                offset,               // Offset within "packet"
                eFormatHex,           // Format to use
                1,                    // Size of each item in bytes
                count,                // Number of items
                16,                   // Number per line
                LLDB_INVALID_ADDRESS, // Don't show addresses before each line
                0, 0);                // No bitfields

        } break;
        }
      }
    } else {
      error_desc = "error: invalid packet command: ";
    }
  }

  if (error_desc) {
    s.PutCString(error_desc);

    packet.Dump(&s,                   // Stream to dump to
                0,                    // Offset into "packet"
                eFormatBytes,         // Dump as hex bytes
                1,                    // Size of each item is 1 for single bytes
                packet.GetByteSize(), // Number of bytes
                UINT32_MAX,           // Num bytes per line
                LLDB_INVALID_ADDRESS, // Base address
                0, 0); // Bitfield info set to not do anything bitfield related
  }
}

uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu,
                                                    uint32_t flavor, void *dst,
                                                    uint32_t dst_len,
                                                    Error &error) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_READREGS;
  // Size is header + 4 byte cpu and 4 byte flavor
  const uint32_t command_length = 8 + 4 + 4;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutHex32(cpu);
  request_packet.PutHex32(flavor);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    uint32_t kdp_error = reply_packet.GetU32(&offset);
    uint32_t src_len = reply_packet.GetByteSize() - 12;

    if (src_len > 0) {
      const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
      const void *src = reply_packet.GetData(&offset, bytes_to_copy);
      if (src) {
        ::memcpy(dst, src, bytes_to_copy);
        error.Clear();
        // Return the number of bytes we could have returned regardless if
        // we copied them or not, just so we know when things don't match up
        return src_len;
      }
    }
    if (kdp_error)
      error.SetErrorStringWithFormat(
          "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
          flavor, kdp_error);
    else
      error.SetErrorStringWithFormat(
          "failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
  } else {
    error.SetErrorString("failed to send packet");
  }
  return 0;
}

uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu,
                                                     uint32_t flavor,
                                                     const void *src,
                                                     uint32_t src_len,
                                                     Error &error) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_WRITEREGS;
  // Size is header + 4 byte cpu and 4 byte flavor
  const uint32_t command_length = 8 + 4 + 4 + src_len;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutHex32(cpu);
  request_packet.PutHex32(flavor);
  request_packet.Write(src, src_len);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    uint32_t kdp_error = reply_packet.GetU32(&offset);
    if (kdp_error == 0)
      return src_len;
    error.SetErrorStringWithFormat(
        "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
        flavor, kdp_error);
  } else {
    error.SetErrorString("failed to send packet");
  }
  return 0;
}

bool CommunicationKDP::SendRequestResume() {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_RESUMECPUS;
  const uint32_t command_length = 12;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutHex32(GetCPUMask());

  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet))
    return true;
  return false;
}

bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  bool use_64 = (GetVersion() >= 11);
  uint32_t command_addr_byte_size = use_64 ? 8 : 4;
  const CommandType command =
      set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET)
          : (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);

  const uint32_t command_length = 8 + command_addr_byte_size;
  MakeRequestPacketHeader(command, request_packet, command_length);
  request_packet.PutMaxHex64(addr, command_addr_byte_size);

  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
    lldb::offset_t offset = 8;
    uint32_t kdp_error = reply_packet.GetU32(&offset);
    if (kdp_error == 0)
      return true;
  }
  return false;
}

bool CommunicationKDP::SendRequestSuspend() {
  PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
                                  m_byte_order);
  const CommandType command = KDP_SUSPEND;
  const uint32_t command_length = 8;
  MakeRequestPacketHeader(command, request_packet, command_length);
  DataExtractor reply_packet;
  if (SendRequestAndGetReply(command, request_packet, reply_packet))
    return true;
  return false;
}
