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


#include "GDBRemoteCommunicationClient.h"

// C Includes
#include <math.h>
#include <sys/stat.h>

// C++ Includes
#include <sstream>
#include <numeric>

// Other libraries and framework includes
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamGDBRemote.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/UnixSignals.h"

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

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

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;

//----------------------------------------------------------------------
// GDBRemoteCommunicationClient constructor
//----------------------------------------------------------------------
GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
    : GDBRemoteCommunication("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_augmented_libraries_svr4_read(eLazyBoolCalculate),
      m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
      m_supports_jLoadedDynamicLibrariesInfos(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_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_async_mutex(),
      m_async_packet_predicate(false),
      m_async_packet(),
      m_async_result(PacketResult::Success),
      m_async_response(),
      m_async_signal(-1),
      m_interrupt_sent(false),
      m_thread_id_to_used_usec_map(),
      m_host_arch(),
      m_process_arch(),
      m_os_version_major(UINT32_MAX),
      m_os_version_minor(UINT32_MAX),
      m_os_version_update(UINT32_MAX),
      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)
{
}

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

bool
GDBRemoteCommunicationClient::HandshakeWithServer (Error *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;
        const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
        while (packet_result == PacketResult::Success)
            packet_result = ReadPacket (response, timeout_usec, 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::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;
}

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.

        const uint32_t minimum_timeout = 6;
        uint32_t old_timeout = GetPacketTimeoutInMicroSeconds() / lldb_private::TimeValue::MicroSecPerSec;
        GDBRemoteCommunication::ScopedTimeout timeout (*this, std::max (old_timeout, minimum_timeout));

        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;
        }
    }
    if (m_attach_or_wait_reply == eLazyBoolYes)
        return true;
    else
        return false;
}

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;
        }
    }
    if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
        return true;
    else
        return false;
}


void
GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
{
    if (did_exec == false)
    {
        // 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_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_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_major = UINT32_MAX;
        m_os_version_minor = UINT32_MAX;
        m_os_version_update = UINT32_MAX;
        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 = 0;
        m_max_packet_size = 0;
    }

    // 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_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"};
    StreamString packet;
    packet.PutCString( "qSupported" );
    for ( uint32_t i = 0; i < features.size( ); ++i )
    {
        packet.PutCString( i==0 ? ":" : ";");
        packet.PutCString( features[i].c_str( ) );
    }

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet.GetData(),
                                     response,
                                     /*send_async=*/false) == PacketResult::Success)
    {
        const char *response_cstr = response.GetStringRef().c_str();
        if (::strstr (response_cstr, "qXfer:auxv:read+"))
            m_supports_qXfer_auxv_read = eLazyBoolYes;
        if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
            m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
        if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
        {
            m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;  // implied
            m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
        }
        if (::strstr (response_cstr, "qXfer:libraries:read+"))
            m_supports_qXfer_libraries_read = eLazyBoolYes;
        if (::strstr (response_cstr, "qXfer:features:read+"))
            m_supports_qXfer_features_read = eLazyBoolYes;


        // Look for a list of compressions in the features list e.g.
        // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-deflate,lzma
        const char *features_list = ::strstr (response_cstr, "qXfer:features:");
        if (features_list)
        {
            const char *compressions = ::strstr (features_list, "SupportedCompressions=");
            if (compressions)
            {
                std::vector<std::string> supported_compressions;
                compressions += sizeof ("SupportedCompressions=") - 1;
                const char *end_of_compressions = strchr (compressions, ';');
                if (end_of_compressions == NULL)
                {
                    end_of_compressions = strchr (compressions, '\0');
                }
                const char *current_compression = compressions;
                while (current_compression < end_of_compressions)
                {
                    const char *next_compression_name = strchr (current_compression, ',');
                    const char *end_of_this_word = next_compression_name;
                    if (next_compression_name == NULL || end_of_compressions < next_compression_name)
                    {
                        end_of_this_word = end_of_compressions;
                    }

                    if (end_of_this_word)
                    {
                        if (end_of_this_word == current_compression)
                        {
                            current_compression++;
                        }
                        else
                        {
                            std::string this_compression (current_compression, end_of_this_word - current_compression);
                            supported_compressions.push_back (this_compression);
                            current_compression = end_of_this_word + 1;
                        }
                    }
                    else
                    {
                        supported_compressions.push_back (current_compression);
                        current_compression = end_of_compressions;
                    }
                }

                if (supported_compressions.size() > 0)
                {
                    MaybeEnableCompression (supported_compressions);
                }
            }
        }

        if (::strstr (response_cstr, "qEcho"))
            m_supports_qEcho = eLazyBoolYes;
        else
            m_supports_qEcho = eLazyBoolNo;

        const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
        if (packet_size_str)
        {
            StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
            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));
                if (log)
                    log->Printf ("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().c_str();
            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;
}

// 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)
    {
        StringExtractorGDBRemote response;
        m_supports_p = eLazyBoolNo;
        char packet[256];
        if (GetThreadSuffixSupported())
            snprintf(packet, sizeof(packet), "p0;thread:%" PRIx64 ";", tid);
        else
            snprintf(packet, sizeof(packet), "p0");
        
        if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
        {
            if (response.IsNormalResponse())
                m_supports_p = eLazyBoolYes;
        }
    }
    return m_supports_p;
}

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

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::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
)
{
    Mutex::Locker locker;
    if (!GetSequenceMutex(locker,
                          "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))
    {
        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
        if (log)
            log->Printf("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 = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),
                                                           this_response,
                                                           /*send_async=*/false);
        if (result != PacketResult::Success)
            return result;

        const std::string &this_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;
    }
}

GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
(
    const char *payload,
    StringExtractorGDBRemote &response,
    bool send_async
)
{
    return SendPacketAndWaitForResponse (payload, 
                                         ::strlen (payload),
                                         response,
                                         send_async);
}

GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
                                                                  size_t payload_length,
                                                                  StringExtractorGDBRemote &response)
{
    PacketResult packet_result = SendPacketNoLock(payload, payload_length);
    if (packet_result == PacketResult::Success)
    {
        const size_t max_response_retries = 3;
        for (size_t i=0; i<max_response_retries; ++i)
        {
            packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds (), true);
            // Make sure we received a response
            if (packet_result != PacketResult::Success)
                return packet_result;
            // Make sure our response is valid for the payload that was sent
            if (response.ValidateResponse())
                return packet_result;
            // Response says it wasn't valid
            Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
            if (log)
                log->Printf("error: packet with payload \"%*s\" got invalid response \"%s\": %s",
                            (int)payload_length,
                            payload,
                            response.GetStringRef().c_str(),
                            (i == (max_response_retries - 1)) ? "using invalid response and giving up" : "ignoring response and waiting for another");
        }
    }
    return packet_result;
}

GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
(
    const char *payload,
    size_t payload_length,
    StringExtractorGDBRemote &response,
    bool send_async
)
{
    PacketResult packet_result = PacketResult::ErrorSendFailed;
    Mutex::Locker locker;
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));

    // In order to stop async notifications from being processed in the middle of the
    // send/receive sequence Hijack the broadcast. Then rebroadcast any events when we are done.
    static ListenerSP hijack_listener_sp(Listener::MakeListener("lldb.NotifyHijacker"));
    HijackBroadcaster(hijack_listener_sp, eBroadcastBitGdbReadThreadGotNotify);

    if (GetSequenceMutex (locker))
    {
        packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
    }
    else
    {
        if (send_async)
        {
            if (IsRunning())
            {
                std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
                m_async_packet.assign(payload, payload_length);
                m_async_response.CopyResponseValidator(response);
                m_async_packet_predicate.SetValue (true, eBroadcastNever);
                
                if (log) 
                    log->Printf ("async: async packet = %s", m_async_packet.c_str());

                bool timed_out = false;
                if (SendInterrupt(locker, 2, timed_out))
                {
                    if (m_interrupt_sent)
                    {
                        m_interrupt_sent = false;
                        TimeValue timeout_time;
                        timeout_time = TimeValue::Now();
                        timeout_time.OffsetWithSeconds (m_packet_timeout);

                        if (log) 
                            log->Printf ("async: sent interrupt");

                        if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
                        {
                            if (log) 
                                log->Printf ("async: got response");

                            // Swap the response buffer to avoid malloc and string copy
                            response.GetStringRef().swap (m_async_response.GetStringRef());
                            packet_result = m_async_result;
                        }
                        else
                        {
                            if (log) 
                                log->Printf ("async: timed out waiting for response");
                        }
                        
                        // Make sure we wait until the continue packet has been sent again...
                        if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
                        {
                            if (log)
                            {
                                if (timed_out) 
                                    log->Printf ("async: timed out waiting for process to resume, but process was resumed");
                                else
                                    log->Printf ("async: async packet sent");
                            }
                        }
                        else
                        {
                            if (log) 
                                log->Printf ("async: timed out waiting for process to resume");
                        }
                    }
                    else
                    {
                        // We had a racy condition where we went to send the interrupt
                        // yet we were able to get the lock, so the process must have
                        // just stopped?
                        if (log) 
                            log->Printf ("async: got lock without sending interrupt");
                        // Send the packet normally since we got the lock
                        packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
                    }
                }
                else
                {
                    if (log) 
                        log->Printf ("async: failed to interrupt");
                }

                m_async_response.SetResponseValidator(nullptr, nullptr);

            }
            else
            {
                if (log) 
                    log->Printf ("async: not running, async is ignored");
            }
        }
        else
        {
            if (log) 
                log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
        }
    }

    // Remove our Hijacking listener from the broadcast.
    RestoreBroadcaster();

    // If a notification event occurred, rebroadcast since it can now be processed safely.
    EventSP event_sp;
    if (hijack_listener_sp->GetNextEvent(event_sp))
        BroadcastEvent(event_sp);

    return packet_result;
}

static const char *end_delimiter = "--end--;";
static const int end_delimiter_len = 8;

std::string
GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
(   ProcessGDBRemote *process,
    StringExtractorGDBRemote& profileDataExtractor
)
{
    std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
    std::stringstream final_output;
    std::string name, value;

    // Going to assuming thread_used_usec comes first, else bail out.
    while (profileDataExtractor.GetNameColonValue(name, value))
    {
        if (name.compare("thread_used_id") == 0)
        {
            StringExtractor threadIDHexExtractor(value.c_str());
            uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
            
            bool has_used_usec = false;
            uint32_t curr_used_usec = 0;
            std::string usec_name, usec_value;
            uint32_t input_file_pos = profileDataExtractor.GetFilePos();
            if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
            {
                if (usec_name.compare("thread_used_usec") == 0)
                {
                    has_used_usec = true;
                    curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
                }
                else
                {
                    // We didn't find what we want, it is probably
                    // an older version. Bail out.
                    profileDataExtractor.SetFilePos(input_file_pos);
                }
            }

            if (has_used_usec)
            {
                uint32_t prev_used_usec = 0;
                std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
                if (iterator != m_thread_id_to_used_usec_map.end())
                {
                    prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
                }
                
                uint32_t real_used_usec = curr_used_usec - prev_used_usec;
                // A good first time record is one that runs for at least 0.25 sec
                bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
                bool good_subsequent_time = (prev_used_usec > 0) &&
                    ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
                
                if (good_first_time || good_subsequent_time)
                {
                    // We try to avoid doing too many index id reservation,
                    // resulting in fast increase of index ids.
                    
                    final_output << name << ":";
                    int32_t index_id = process->AssignIndexIDToThread(thread_id);
                    final_output << index_id << ";";
                    
                    final_output << usec_name << ":" << usec_value << ";";
                }
                else
                {
                    // Skip past 'thread_used_name'.
                    std::string local_name, local_value;
                    profileDataExtractor.GetNameColonValue(local_name, local_value);
                }
                
                // Store current time as previous time so that they can be compared later.
                new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
            }
            else
            {
                // Bail out and use old string.
                final_output << name << ":" << value << ";";
            }
        }
        else
        {
            final_output << name << ":" << value << ";";
        }
    }
    final_output << end_delimiter;
    m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
    
    return final_output.str();
}

bool
GDBRemoteCommunicationClient::SendvContPacket
(
    ProcessGDBRemote *process,
    const char *payload,
    size_t packet_length,
    StringExtractorGDBRemote &response
)
{

    m_curr_tid = LLDB_INVALID_THREAD_ID;
    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
    if (log)
        log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);

    // we want to lock down packet sending while we continue
    Mutex::Locker locker(m_sequence_mutex);

    // here we broadcast this before we even send the packet!!
    // this signals doContinue() to exit
    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);

    // set the public state to running
    m_public_is_running.SetValue(true, eBroadcastNever);

    // Set the starting continue packet into "continue_packet". This packet
    // may change if we are interrupted and we continue after an async packet...
    std::string continue_packet(payload, packet_length);

    if (log)
        log->Printf("GDBRemoteCommunicationClient::%s () sending vCont packet: %s", __FUNCTION__, continue_packet.c_str());

    if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
         return false;

    // set the private state to running and broadcast this
    m_private_is_running.SetValue(true, eBroadcastAlways);

    if (log)
        log->Printf("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());

    // wait for the response to the vCont
    if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
    {
        if (response.IsOKResponse())
            return true;
    }

    return false;
}

StateType
GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
(
    ProcessGDBRemote *process,
    const char *payload,
    size_t packet_length,
    StringExtractorGDBRemote &response
)
{
    m_curr_tid = LLDB_INVALID_THREAD_ID;
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
    if (log)
        log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);

    Mutex::Locker locker(m_sequence_mutex);
    StateType state = eStateRunning;

    m_public_is_running.SetValue (true, eBroadcastNever);
    // Set the starting continue packet into "continue_packet". This packet
    // may change if we are interrupted and we continue after an async packet...
    std::string continue_packet(payload, packet_length);

    const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
    const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT");

    bool got_async_packet = false;
    bool broadcast_sent = false;
    
    while (state == eStateRunning)
    {
        if (!got_async_packet)
        {
            if (log)
                log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
            if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
                state = eStateInvalid;
            else
                m_interrupt_sent = false;
        
            if (! broadcast_sent)
            {
                BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
                broadcast_sent = true;
            }

            m_private_is_running.SetValue (true, eBroadcastAlways);
        }
        
        got_async_packet = false;

        if (log)
            log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(%s)", __FUNCTION__, continue_packet.c_str());

        if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
        {
            if (response.Empty())
                state = eStateInvalid;
            else
            {
                const char stop_type = response.GetChar();
                if (log)
                    log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
                switch (stop_type)
                {
                case 'T':
                case 'S':
                    {
                        if (process->GetStopID() == 0)
                        {
                            if (process->GetID() == LLDB_INVALID_PROCESS_ID)
                            {
                                lldb::pid_t pid = GetCurrentProcessID ();
                                if (pid != LLDB_INVALID_PROCESS_ID)
                                    process->SetID (pid);
                            }
                            process->BuildDynamicRegisterInfo (true);
                        }

                        // Privately notify any internal threads that we have stopped
                        // in case we wanted to interrupt our process, yet we might
                        // send a packet and continue without returning control to the
                        // user.
                        m_private_is_running.SetValue (false, eBroadcastAlways);

                        const uint8_t signo = response.GetHexU8 (UINT8_MAX);

                        bool continue_after_async = m_async_signal != -1 || m_async_packet_predicate.GetValue();
                        if (continue_after_async || m_interrupt_sent)
                        {
                            // We sent an interrupt packet to stop the inferior process
                            // for an async signal or to send an async packet while running
                            // but we might have been single stepping and received the
                            // stop packet for the step instead of for the interrupt packet.
                            // Typically when an interrupt is sent a SIGINT or SIGSTOP
                            // is used, so if we get anything else, we need to try and
                            // get another stop reply packet that may have been sent
                            // due to sending the interrupt when the target is stopped
                            // which will just re-send a copy of the last stop reply
                            // packet. If we don't do this, then the reply for our
                            // async packet will be the repeat stop reply packet and cause
                            // a lot of trouble for us! We also have some debugserver
                            // binaries that would send two stop replies anytime the process
                            // was interrupted, so we need to also check for an extra
                            // stop reply packet if we interrupted the process
                            const bool received_nonstop_signal = signo != sigint_signo && signo != sigstop_signo;
                            if (m_interrupt_sent || received_nonstop_signal)
                            {
                                if (received_nonstop_signal)
                                    continue_after_async = false;

                                // Try for a very brief time (0.1s) to get another stop reply
                                // packet to make sure it doesn't get in the way
                                StringExtractorGDBRemote extra_stop_reply_packet;
                                uint32_t timeout_usec = 100000;
                                if (ReadPacket (extra_stop_reply_packet, timeout_usec, false) == PacketResult::Success)
                                {
                                    switch (extra_stop_reply_packet.GetChar())
                                    {
                                    case 'T':
                                    case 'S':
                                        // We did get an extra stop reply, which means
                                        // our interrupt didn't stop the target so we
                                        // shouldn't continue after the async signal
                                        // or packet is sent...
                                        continue_after_async = false;
                                        break;
                                    }
                                }
                            }
                        }

                        if (m_async_signal != -1)
                        {
                            if (log)
                                log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));

                            // Save off the async signal we are supposed to send
                            const int async_signal = m_async_signal;
                            // Clear the async signal member so we don't end up
                            // sending the signal multiple times...
                            m_async_signal = -1;
                            // Check which signal we stopped with
                            if (signo == async_signal)
                            {
                                if (log) 
                                    log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));

                                // We already stopped with a signal that we wanted
                                // to stop with, so we are done
                            }
                            else
                            {
                                // We stopped with a different signal that the one
                                // we wanted to stop with, so now we must resume
                                // with the signal we want
                                char signal_packet[32];
                                int signal_packet_len = 0;
                                signal_packet_len = ::snprintf (signal_packet,
                                                                sizeof (signal_packet),
                                                                "C%2.2x",
                                                                async_signal);

                                if (log) 
                                    log->Printf ("async: stopped with signal %s, resume with %s", 
                                                       Host::GetSignalAsCString (signo),
                                                       Host::GetSignalAsCString (async_signal));

                                // Set the continue packet to resume even if the
                                // interrupt didn't cause our stop (ignore continue_after_async)
                                continue_packet.assign(signal_packet, signal_packet_len);
                                continue;
                            }
                        }
                        else if (m_async_packet_predicate.GetValue())
                        {
                            Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));

                            // We are supposed to send an asynchronous packet while
                            // we are running.
                            m_async_response.Clear();
                            if (m_async_packet.empty())
                            {
                                m_async_result = PacketResult::ErrorSendFailed;
                                if (packet_log)
                                    packet_log->Printf ("async: error: empty async packet");                            

                            }
                            else
                            {
                                if (packet_log) 
                                    packet_log->Printf ("async: sending packet");
                                
                                m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0],
                                                                               m_async_packet.size(),
                                                                               m_async_response,
                                                                               false);
                            }
                            // Let the other thread that was trying to send the async
                            // packet know that the packet has been sent and response is
                            // ready...
                            m_async_packet_predicate.SetValue(false, eBroadcastAlways);

                            if (packet_log) 
                                packet_log->Printf ("async: sent packet, continue_after_async = %i", continue_after_async);

                            // Set the continue packet to resume if our interrupt
                            // for the async packet did cause the stop
                            if (continue_after_async)
                            {
                                // Reverting this for now as it is causing deadlocks
                                // in programs (<rdar://problem/11529853>). In the future
                                // we should check our thread list and "do the right thing"
                                // for new threads that show up while we stop and run async
                                // packets. Setting the packet to 'c' to continue all threads
                                // is the right thing to do 99.99% of the time because if a
                                // thread was single stepping, and we sent an interrupt, we
                                // will notice above that we didn't stop due to an interrupt
                                // but stopped due to stepping and we would _not_ continue.
                                continue_packet.assign (1, 'c');
                                continue;
                            }
                        }
                        // Stop with signal and thread info
                        state = eStateStopped;
                    }
                    break;

                case 'W':
                case 'X':
                    // process exited
                    state = eStateExited;
                    break;

                case 'O':
                    // STDOUT
                    {
                        got_async_packet = true;
                        std::string inferior_stdout;
                        inferior_stdout.reserve(response.GetBytesLeft () / 2);

                        uint8_t ch;
                        while (response.GetHexU8Ex(ch))
                        {
                            if (ch != 0)
                                inferior_stdout.append(1, (char)ch);
                        }
                        process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
                    }
                    break;

                case 'A':
                    // Async miscellaneous reply. Right now, only profile data is coming through this channel.
                    {
                        got_async_packet = true;
                        std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
                        if (m_partial_profile_data.length() > 0)
                        {
                            m_partial_profile_data.append(input);
                            input = m_partial_profile_data;
                            m_partial_profile_data.clear();
                        }
                        
                        size_t found, pos = 0, len = input.length();
                        while ((found = input.find(end_delimiter, pos)) != std::string::npos)
                        {
                            StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
                            std::string profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
                            process->BroadcastAsyncProfileData (profile_data);
                            
                            pos = found + end_delimiter_len;
                        }
                        
                        if (pos < len)
                        {
                            // Last incomplete chunk.
                            m_partial_profile_data = input.substr(pos);
                        }
                    }
                    break;

                case 'E':
                    // ERROR
                    state = eStateInvalid;
                    break;

                default:
                    if (log)
                        log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
                    state = eStateInvalid;
                    break;
                }
            }
        }
        else
        {
            if (log)
                log->Printf ("GDBRemoteCommunicationClient::%s () ReadPacket(...) => false", __FUNCTION__);
            state = eStateInvalid;
        }
    }
    if (log)
        log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
    response.SetFilePos(0);
    m_private_is_running.SetValue (false, eBroadcastAlways);
    m_public_is_running.SetValue (false, eBroadcastAlways);
    return state;
}

bool
GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
{
    std::lock_guard<std::recursive_mutex> guard(m_async_mutex);
    m_async_signal = signo;
    bool timed_out = false;
    Mutex::Locker locker;
    if (SendInterrupt (locker, 1, timed_out))
        return true;
    m_async_signal = -1;
    return false;
}

// This function takes a mutex locker as a parameter in case the GetSequenceMutex
// actually succeeds. If it doesn't succeed in acquiring the sequence mutex 
// (the expected result), then it will send the halt packet. If it does succeed
// then the caller that requested the interrupt will want to keep the sequence
// locked down so that no one else can send packets while the caller has control.
// This function usually gets called when we are running and need to stop the 
// target. It can also be used when we are running and we need to do something
// else (like read/write memory), so we need to interrupt the running process
// (gdb remote protocol requires this), and do what we need to do, then resume.

bool
GDBRemoteCommunicationClient::SendInterrupt
(
    Mutex::Locker& locker, 
    uint32_t seconds_to_wait_for_stop,             
    bool &timed_out
)
{
    timed_out = false;
    Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));

    if (IsRunning())
    {
        // Only send an interrupt if our debugserver is running...
        if (GetSequenceMutex (locker))
        {
            if (log)
                log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt");
        }
        else
        {
            // Someone has the mutex locked waiting for a response or for the
            // inferior to stop, so send the interrupt on the down low...
            char ctrl_c = '\x03';
            ConnectionStatus status = eConnectionStatusSuccess;
            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
            if (log)
                log->PutCString("send packet: \\x03");
            if (bytes_written > 0)
            {
                m_interrupt_sent = true;
                if (seconds_to_wait_for_stop)
                {
                    TimeValue timeout;
                    if (seconds_to_wait_for_stop)
                    {
                        timeout = TimeValue::Now();
                        timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
                    }
                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
                    {
                        if (log)
                            log->PutCString ("SendInterrupt () - sent interrupt, private state stopped");
                        return true;
                    }
                    else
                    {
                        if (log)
                            log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume");
                    }
                }
                else
                {
                    if (log)
                        log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop...");
                    return true;
                }
            }
            else
            {
                if (log)
                    log->Printf ("SendInterrupt () - failed to write interrupt");
            }
            return false;
        }
    }
    else
    {
        if (log)
            log->Printf ("SendInterrupt () - not running");
    }
    return true;
}

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", strlen("qC"), response, false) == PacketResult::Success)
        {
            if (response.GetChar() == 'Q')
            {
                if (response.GetChar() == 'C')
                {
                    m_curr_pid = response.GetHexMaxU32 (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)
        {
            std::vector<lldb::tid_t> thread_ids;
            bool sequence_mutex_unavailable;
            size_t size;
            size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
            if (size && sequence_mutex_unavailable == false)
            {
                m_curr_pid = thread_ids.front();
                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", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
    {
        if (response.IsOKResponse())
            return true;
        if (response.GetChar() == 'E')
        {
            // A string the describes what failed when launching...
            error_str = 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 = NULL;
    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)) != NULL; ++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.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
        {
            if (response.IsOKResponse())
                return 0;
            uint8_t error = response.GetError();
            if (error)
                return error;
        }
    }
    return -1;
}

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 == false; ++p)
        {
            if (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.GetData(), packet.GetSize(), 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.GetData(), packet.GetSize(), 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.GetData(), packet.GetSize(), 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.GetData(), packet.GetSize(), 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;
}

bool
GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, 
                                            uint32_t &minor, 
                                            uint32_t &update)
{
    if (GetHostInfo ())
    {
        if (m_os_version_major != UINT32_MAX)
        {
            major = m_os_version_major;
            minor = m_os_version_minor;
            update = m_os_version_update;
            return true;
        }
    }
    return false;
}

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())
            {
                std::string name;
                std::string value;
                bool success = false;
                while (response.GetNameColonValue(name, value))
                {
                    if (name.compare("name") == 0)
                    {
                        success = true;
                        m_gdb_server_name.swap(value);
                    }
                    else if (name.compare("version") == 0)
                    {
                        size_t dot_pos = value.find('.');
                        if (dot_pos != std::string::npos)
                            value[dot_pos] = '\0';
                        const uint32_t version = StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0);
                        if (version != UINT32_MAX)
                        {
                            success = true;
                            m_gdb_server_version = version;
                        }
                    }
                }
                if (success)
                    m_qGDBServerVersion_is_valid = eLazyBoolYes;
            }
        }
    }
    return m_qGDBServerVersion_is_valid == eLazyBoolYes;
}

void
GDBRemoteCommunicationClient::MaybeEnableCompression (std::vector<std::string> supported_compressions)
{
    CompressionType avail_type = CompressionType::None;
    std::string avail_name;

#if defined (HAVE_LIBCOMPRESSION)
    // libcompression is weak linked so test if compression_decode_buffer() is available
    if (compression_decode_buffer != NULL && 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)
    // libcompression is weak linked so test if compression_decode_buffer() is available
    if (compression_decode_buffer != NULL && 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_LIBZ)
    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)
    // libcompression is weak linked so test if compression_decode_buffer() is available
    if (compression_decode_buffer != NULL && 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)
    // libcompression is weak linked so test if compression_decode_buffer() is available
    if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
    {
        for (auto compression : supported_compressions)
        {
            if (compression == "lzma")
            {
                avail_type = CompressionType::LZMA;
                avail_name = compression;
                break;
            }
        }
    }
#endif

    if (avail_type != CompressionType::None)
    {
        StringExtractorGDBRemote response;
        std::string packet = "QEnableCompression:type:" + avail_name + ";";
        if (SendPacketAndWaitForResponse (packet.c_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 NULL;
}

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')
        tid = response.GetHexMaxU32(true, -1);

    return true;
}

bool
GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
    Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));

    if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
    {
        m_qHostInfo_is_valid = eLazyBoolNo;
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
        {
            if (response.IsNormalResponse())
            {
                std::string name;
                std::string value;
                uint32_t cpu = LLDB_INVALID_CPUTYPE;
                uint32_t sub = 0;
                std::string arch_name;
                std::string os_name;
                std::string vendor_name;
                std::string triple;
                std::string distribution_id;
                uint32_t pointer_byte_size = 0;
                StringExtractor extractor;
                ByteOrder byte_order = eByteOrderInvalid;
                uint32_t num_keys_decoded = 0;
                while (response.GetNameColonValue(name, value))
                {
                    if (name.compare("cputype") == 0)
                    {
                        // exception type in big endian hex
                        cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
                        if (cpu != LLDB_INVALID_CPUTYPE)
                            ++num_keys_decoded;
                    }
                    else if (name.compare("cpusubtype") == 0)
                    {
                        // exception count in big endian hex
                        sub = StringConvert::ToUInt32 (value.c_str(), 0, 0);
                        if (sub != 0)
                            ++num_keys_decoded;
                    }
                    else if (name.compare("arch") == 0)
                    {
                        arch_name.swap (value);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("triple") == 0)
                    {
                        extractor.GetStringRef ().swap (value);
                        extractor.SetFilePos(0);
                        extractor.GetHexByteString (triple);
                        ++num_keys_decoded;
                    }
                    else if (name.compare ("distribution_id") == 0)
                    {
                        extractor.GetStringRef ().swap (value);
                        extractor.SetFilePos (0);
                        extractor.GetHexByteString (distribution_id);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("os_build") == 0)
                    {
                        extractor.GetStringRef().swap(value);
                        extractor.SetFilePos(0);
                        extractor.GetHexByteString (m_os_build);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("hostname") == 0)
                    {
                        extractor.GetStringRef().swap(value);
                        extractor.SetFilePos(0);
                        extractor.GetHexByteString (m_hostname);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("os_kernel") == 0)
                    {
                        extractor.GetStringRef().swap(value);
                        extractor.SetFilePos(0);
                        extractor.GetHexByteString (m_os_kernel);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("ostype") == 0)
                    {
                        os_name.swap (value);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("vendor") == 0)
                    {
                        vendor_name.swap(value);
                        ++num_keys_decoded;
                    }
                    else if (name.compare("endian") == 0)
                    {
                        ++num_keys_decoded;
                        if (value.compare("little") == 0)
                            byte_order = eByteOrderLittle;
                        else if (value.compare("big") == 0)
                            byte_order = eByteOrderBig;
                        else if (value.compare("pdp") == 0)
                            byte_order = eByteOrderPDP;
                        else
                            --num_keys_decoded;
                    }
                    else if (name.compare("ptrsize") == 0)
                    {
                        pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 0);
                        if (pointer_byte_size != 0)
                            ++num_keys_decoded;
                    }
                    else if ((name.compare("os_version") == 0) ||
                             (name.compare("version") == 0)) // Older debugserver binaries used the "version" key instead of "os_version"...
                    {
                        Args::StringToVersion (value.c_str(), 
                                               m_os_version_major,
                                               m_os_version_minor,
                                               m_os_version_update);
                        if (m_os_version_major != UINT32_MAX)
                            ++num_keys_decoded;
                    }
                    else if (name.compare("watchpoint_exceptions_received") == 0)
                    {
                        ++num_keys_decoded;
                        if (strcmp(value.c_str(),"before") == 0)
                            m_watchpoints_trigger_after_instruction = eLazyBoolNo;
                        else if (strcmp(value.c_str(),"after") == 0)
                            m_watchpoints_trigger_after_instruction = eLazyBoolYes;
                        else
                            --num_keys_decoded;
                    }
                    else if (name.compare("default_packet_timeout") == 0)
                    {
                        m_default_packet_timeout = StringConvert::ToUInt32(value.c_str(), 0);
                        if (m_default_packet_timeout > 0)
                        {
                            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));
                                
                        }
                    }
                    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::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());
                    }

                    if (log)
                        log->Printf ("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);
        assert (packet_len < (int)sizeof(packet));
        if (SendPacketAndWaitForResponse (packet, packet_len, 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.GetData(), packet.GetSize(), 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;
}

uint32_t
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));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, 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));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, 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;
}

Error
GDBRemoteCommunicationClient::Detach (bool keep_stopped)
{
    Error 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));
            StringExtractorGDBRemote response;
            if (SendPacketAndWaitForResponse (packet, packet_len, 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", 2, response, false);
            if (packet_result != PacketResult::Success)
                error.SetErrorString ("Sending extended disconnect packet failed.");
        }
    }
    else
    {
        StringExtractorGDBRemote response;
        PacketResult packet_result = SendPacketAndWaitForResponse ("D", 1, response, false);
        if (packet_result != PacketResult::Success)
            error.SetErrorString ("Sending disconnect packet failed.");
    }
    return error;
}

Error
GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, 
                                                  lldb_private::MemoryRegionInfo &region_info)
{
    Error 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));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
        {
            std::string name;
            std::string value;
            addr_t addr_value;
            bool success = true;
            bool saw_permissions = false;
            while (success && response.GetNameColonValue(name, value))
            {
                if (name.compare ("start") == 0)
                {
                    addr_value = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success);
                    if (success)
                        region_info.GetRange().SetRangeBase(addr_value);
                }
                else if (name.compare ("size") == 0)
                {
                    addr_value = StringConvert::ToUInt64(value.c_str(), 0, 16, &success);
                    if (success)
                        region_info.GetRange().SetByteSize (addr_value);
                }
                else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid())
                {
                    saw_permissions = true;
                    if (region_info.GetRange().Contains (addr))
                    {
                        if (value.find('r') != std::string::npos)
                            region_info.SetReadable (MemoryRegionInfo::eYes);
                        else
                            region_info.SetReadable (MemoryRegionInfo::eNo);

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

                        if (value.find('x') != std::string::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.compare ("error") == 0)
                {
                    StringExtractorGDBRemote name_extractor;
                    // Swap "value" over into "name_extractor"
                    name_extractor.GetStringRef().swap(value);
                    // Now convert the HEX bytes into a string value
                    name_extractor.GetHexByteString (value);
                    error.SetErrorString(value.c_str());
                }
            }

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

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

}

Error
GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
{
    Error 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)
    {
        char packet[64];
        const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
        assert (packet_len < (int)sizeof(packet));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
        {
            m_supports_watchpoint_support_info = eLazyBoolYes;        
            std::string name;
            std::string value;
            while (response.GetNameColonValue(name, value))
            {
                if (name.compare ("num") == 0)
                {
                    num = StringConvert::ToUInt32(value.c_str(), 0, 0);
                    m_num_supported_hardware_watchpoints = num;
                }
            }
        }
        else
        {
            m_supports_watchpoint_support_info = eLazyBoolNo;
        }
    }

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

}

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

lldb_private::Error
GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch)
{
    Error error;
    llvm::Triple::ArchType atype = arch.GetMachine();
    
    // 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, watchpoint exceptions are always generated 
        // before the instruction is executed. The connected target may not 
        // support qHostInfo or qWatchpointSupportInfo packets.
        if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
            || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el)
            after = false;
        else
            after = true;
    }
    else
    {
        // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo 
        // if it is not calculated before.
        if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
            (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel
            || atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
            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.PutCStringAsRawHex8(path.c_str());

        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), 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.PutCStringAsRawHex8(path.c_str());

        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), 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.PutCStringAsRawHex8(path.c_str());

        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), 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, false, GetHostArchitecture());
        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.PutCStringAsRawHex8(path.c_str());

        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), 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));
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse (packet, packet_len, 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));
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse (packet, packet_len, 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())
    {
        std::string name;
        std::string 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.compare("pid") == 0)
            {
                process_info.SetProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
            }
            else if (name.compare("ppid") == 0)
            {
                process_info.SetParentProcessID (StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0));
            }
            else if (name.compare("uid") == 0)
            {
                process_info.SetUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
            }
            else if (name.compare("euid") == 0)
            {
                process_info.SetEffectiveUserID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
            }
            else if (name.compare("gid") == 0)
            {
                process_info.SetGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
            }
            else if (name.compare("egid") == 0)
            {
                process_info.SetEffectiveGroupID (StringConvert::ToUInt32 (value.c_str(), UINT32_MAX, 0));
            }
            else if (name.compare("triple") == 0)
            {
                StringExtractor extractor;
                extractor.GetStringRef().swap(value);
                extractor.SetFilePos(0);
                extractor.GetHexByteString (value);
                process_info.GetArchitecture ().SetTriple (value.c_str());
            }
            else if (name.compare("name") == 0)
            {
                StringExtractor extractor;
                // The process name from ASCII hex bytes since we can't 
                // control the characters in a process name
                extractor.GetStringRef().swap(value);
                extractor.SetFilePos(0);
                extractor.GetHexByteString (value);
                process_info.GetExecutableFile().SetFile (value.c_str(), false);
            }
            else if (name.compare("cputype") == 0)
            {
                cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
            }
            else if (name.compare("cpusubtype") == 0)
            {
                sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
            }
            else if (name.compare("vendor") == 0)
            {
                vendor = value;
            }
            else if (name.compare("ostype") == 0)
            {
                os_type = 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));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, 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())
        {
            std::string name;
            std::string value;
            uint32_t cpu = LLDB_INVALID_CPUTYPE;
            uint32_t sub = 0;
            std::string arch_name;
            std::string os_name;
            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.compare("cputype") == 0)
                {
                    cpu = StringConvert::ToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
                    if (cpu != LLDB_INVALID_CPUTYPE)
                        ++num_keys_decoded;
                }
                else if (name.compare("cpusubtype") == 0)
                {
                    sub = StringConvert::ToUInt32 (value.c_str(), 0, 16);
                    if (sub != 0)
                        ++num_keys_decoded;
                }
                else if (name.compare("triple") == 0)
                {
                    StringExtractor extractor;
                    extractor.GetStringRef().swap(value);
                    extractor.SetFilePos(0);
                    extractor.GetHexByteString (triple);
                    ++num_keys_decoded;
                }
                else if (name.compare("ostype") == 0)
                {
                    os_name.swap (value);
                    ++num_keys_decoded;
                }
                else if (name.compare("vendor") == 0)
                {
                    vendor_name.swap(value);
                    ++num_keys_decoded;
                }
                else if (name.compare("endian") == 0)
                {
                    ++num_keys_decoded;
                    if (value.compare("little") == 0)
                        byte_order = eByteOrderLittle;
                    else if (value.compare("big") == 0)
                        byte_order = eByteOrderBig;
                    else if (value.compare("pdp") == 0)
                        byte_order = eByteOrderPDP;
                    else
                        --num_keys_decoded;
                }
                else if (name.compare("ptrsize") == 0)
                {
                    pointer_byte_size = StringConvert::ToUInt32 (value.c_str(), 0, 16);
                    if (pointer_byte_size != 0)
                        ++num_keys_decoded;
                }
                else if (name.compare("pid") == 0)
                {
                    pid = StringConvert::ToUInt64(value.c_str(), 0, 16);
                    if (pid != LLDB_INVALID_PROCESS_ID)
                        ++num_keys_decoded;
                }
                else if (name.compare("elf_abi") == 0)
                {
                    elf_abi = 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);

                assert(triple.getObjectFormat() != llvm::Triple::UnknownObjectFormat);
                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::UnknownObjectFormat:
                        if (log)
                            log->Printf("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_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
                m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
            }
            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;
                NameMatchType name_match_type = match_info.GetNameMatchType();
                switch (name_match_type)
                {
                case eNameMatchIgnore:  
                    has_name_match = false;
                    break;

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

                case eNameMatchContains:
                    packet.PutCString ("name_match:contains;"); 
                    break;
                
                case eNameMatchStartsWith:
                    packet.PutCString ("name_match:starts_with;"); 
                    break;
                
                case eNameMatchEndsWith:
                    packet.PutCString ("name_match:ends_with;"); 
                    break;

                case eNameMatchRegularExpression:
                    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());
            if (match_info.GetProcessInfo().EffectiveGroupIDIsValid())
                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().c_str());
                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.
        GDBRemoteCommunication::ScopedTimeout timeout (*this, 60);
        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
        {
            do
            {
                ProcessInstanceInfo process_info;
                if (!DecodeProcessInfoResponse (response, process_info))
                    break;
                process_infos.Append(process_info);
                response.GetStringRef().clear();
                response.SetFilePos(0);
            } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
        }
        else
        {
            m_supports_qfProcessInfo = false;
            return 0;
        }
    }
    return process_infos.GetSize();
    
}

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));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, 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));
        StringExtractorGDBRemote response;
        if (SendPacketAndWaitForResponse (packet, packet_len, 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));

    StringExtractorGDBRemote response;
    // Send to target
    if (SendPacketAndWaitForResponse(packet, packet_len, 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;
        }
    }
}

template<typename T>
T calculate_standard_deviation(const std::vector<T> &v)
{
    T sum = std::accumulate(std::begin(v), std::end(v), T(0));
    T mean =  sum / (T)v.size();
    T accum = T(0);
    std::for_each (std::begin(v), std::end(v), [&](const T d) {
        T delta = d - mean;
        accum += delta * delta;
    });

    T stdev = sqrt(accum / (v.size()-1));
    return stdev;
}

void
GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm)
{
    uint32_t i;
    TimeValue start_time, end_time;
    uint64_t total_time_nsec;
    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<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
                start_time = TimeValue::Now();
                for (i=0; i<num_packets; ++i)
                {
                    TimeValue packet_start_time = TimeValue::Now();
                    StringExtractorGDBRemote response;
                    SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
                    TimeValue packet_end_time = TimeValue::Now();
                    uint64_t packet_time_nsec = packet_end_time.GetAsNanoSecondsSinceJan1_1970() - packet_start_time.GetAsNanoSecondsSinceJan1_1970();
                    packet_times.push_back((float)packet_time_nsec);
                }
                end_time = TimeValue::Now();
                total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();

                float packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
                float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
                float average_ms_per_packet = total_ms / num_packets;
                const float standard_deviation = calculate_standard_deviation<float>(packet_times);
                if (json)
                {
                    strm.Printf ("%s\n     {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 ", \"standard_deviation_nsec\" : %9" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec, (uint64_t)standard_deviation);
                    ++result_idx;
                }
                else
                {
                    strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) in %" PRIu64 ".%9.9" PRIu64 " sec for %9.2f packets/sec (%10.6f ms per packet) with standard deviation of %10.6f ms\n",
                                 send_size,
                                 recv_size,
                                 total_time_nsec / TimeValue::NanoSecPerSec,
                                 total_time_nsec % TimeValue::NanoSecPerSec,
                                 packets_per_second,
                                 average_ms_per_packet,
                                 standard_deviation/(float)TimeValue::NanoSecPerMilliSec);
                }
                strm.Flush();
            }
        }

        const uint64_t k_recv_amount = 4*1024*1024; // Receive amount in bytes

        const float k_recv_amount_mb = (float)k_recv_amount/(1024.0f*1024.0f);
        if (json)
            strm.Printf("\n    ]\n  },\n  \"download_speed\" : {\n    \"byte_size\" : %" PRIu64 ",\n    \"results\" : [", k_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)
            {
                start_time = TimeValue::Now();
                uint32_t bytes_read = 0;
                uint32_t packet_count = 0;
                while (bytes_read < k_recv_amount)
                {
                    StringExtractorGDBRemote response;
                    SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false);
                    bytes_read += recv_size;
                    ++packet_count;
                }
                end_time = TimeValue::Now();
                total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
                float mb_second = ((((float)k_recv_amount)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec) / (1024.0*1024.0);
                float packets_per_second = (((float)packet_count)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
                float total_ms = (float)total_time_nsec/(float)TimeValue::NanoSecPerMilliSec;
                float average_ms_per_packet = total_ms / packet_count;

                if (json)
                {
                    strm.Printf ("%s\n     {\"send_size\" : %6" PRIu32 ", \"recv_size\" : %6" PRIu32 ", \"total_time_nsec\" : %12" PRIu64 " }", result_idx > 0 ? "," : "", send_size, recv_size, total_time_nsec);
                    ++result_idx;
                }
                else
                {
                    strm.Printf ("qSpeedTest(send=%-7u, recv=%-7u) %6u packets needed to receive %2.1fMB in %" PRIu64 ".%9.9" PRIu64 " sec for %f MB/sec for %9.2f packets/sec (%10.6f ms per packet)\n",
                                 send_size,
                                 recv_size,
                                 packet_count,
                                 k_recv_amount_mb,
                                 total_time_nsec / TimeValue::NanoSecPerSec,
                                 total_time_nsec % TimeValue::NanoSecPerSec,
                                 mb_second,
                                 packets_per_second,
                                 average_ms_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.GetData(), packet.GetSize(), 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:*;");
        }
    }
    const char *packet = stream.GetData();
    int packet_len = stream.GetSize();

    // give the process a few seconds to startup
    GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);

    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
    {
        std::string name;
        std::string value;
        StringExtractor extractor;
        while (response.GetNameColonValue(name, value))
        {
            if (name.compare("port") == 0)
                port = StringConvert::ToUInt32(value.c_str(), 0, 0);
            else if (name.compare("pid") == 0)
                pid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_PROCESS_ID, 0);
            else if (name.compare("socket_name") == 0)
            {
                extractor.GetStringRef().swap(value);
                extractor.SetFilePos(0);
                extractor.GetHexByteString(value);

                socket_name = value;
            }
        }
        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(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 = 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);
    const char *packet = stream.GetData();
    int packet_len = stream.GetSize();

    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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));
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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));
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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("?", 1, 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));
        if (SendPacketAndWaitForResponse(packet, packet_len, 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));
    if (log)
        log->Printf ("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));
    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, packet_len, response, true) == PacketResult::Success)
    {
        // Receive and OK packet when the breakpoint successfully placed
        if (response.IsOKResponse())
            return 0;

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

size_t
GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids, 
                                                   bool &sequence_mutex_unavailable)
{
    Mutex::Locker locker;
    thread_ids.clear();
    
    if (GetSequenceMutex (locker, "ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"))
    {
        sequence_mutex_unavailable = false;
        StringExtractorGDBRemote response;
        
        PacketResult packet_result;
        for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
             packet_result == PacketResult::Success && response.IsNormalResponse();
             packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
        {
            char ch = response.GetChar();
            if (ch == 'l')
                break;
            if (ch == 'm')
            {
                do
                {
                    tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
                    
                    if (tid != LLDB_INVALID_THREAD_ID)
                    {
                        thread_ids.push_back (tid);
                    }
                    ch = response.GetChar();    // Skip the command separator
                } while (ch == ',');            // Make sure we got a comma separator
            }
        }

        /*
         * Connected bare-iron target (like YAMON gdb-stub) may not have support for
         * qProcessInfo, qC and qfThreadInfo packets. The reply from '?' packet could
         * be as simple as 'S05'. There is no packet which can give us pid and/or tid.
         * Assume pid=tid=1 in such cases.
        */
        if (response.IsUnsupportedResponse() && thread_ids.size() == 0 && IsConnected())
        {
            thread_ids.push_back (1);
        }
    }
    else
    {
#if defined (LLDB_CONFIGURATION_DEBUG)
        // assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
#else
        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
        if (log)
            log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
#endif
        sequence_mutex_unavailable = true;
    }
    return thread_ids.size();
}

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

lldb_private::Error
GDBRemoteCommunicationClient::RunShellCommand(const char *command,           // Shouldn't be NULL
                                              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
                                              uint32_t timeout_sec)          // Timeout in seconds to wait for shell program to finish
{
    lldb_private::StreamString stream;
    stream.PutCString("qPlatform_shell:");
    stream.PutBytesAsRawHex8(command, strlen(command));
    stream.PutChar(',');
    stream.PutHex32(timeout_sec);
    if (working_dir)
    {
        std::string path{working_dir.GetPath(false)};
        stream.PutChar(',');
        stream.PutCStringAsRawHex8(path.c_str());
    }
    const char *packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
    {
        if (response.GetChar() != 'F')
            return Error("malformed reply");
        if (response.GetChar() != ',')
            return Error("malformed reply");
        uint32_t exitcode = response.GetHexMaxU32(false, UINT32_MAX);
        if (exitcode == UINT32_MAX)
            return Error("unable to run remote process");
        else if (status_ptr)
            *status_ptr = exitcode;
        if (response.GetChar() != ',')
            return Error("malformed reply");
        uint32_t signo = response.GetHexMaxU32(false, UINT32_MAX);
        if (signo_ptr)
            *signo_ptr = signo;
        if (response.GetChar() != ',')
            return Error("malformed reply");
        std::string output;
        response.GetEscapedBinaryData(output);
        if (command_output)
            command_output->assign(output);
        return Error();
    }
    return Error("unable to send packet");
}

Error
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.PutCStringAsRawHex8(path.c_str());
    const char *packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;

    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
        return Error("failed to send '%s' packet", packet);

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

    return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
}

Error
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.PutCStringAsRawHex8(path.c_str());
    const char *packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;

    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) != PacketResult::Success)
        return Error("failed to send '%s' packet", packet);

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

    return Error(response.GetU32(UINT32_MAX), eErrorTypePOSIX);
}

static uint64_t
ParseHostIOPacketResponse (StringExtractorGDBRemote &response,
                           uint64_t fail_result,
                           Error &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,
                                        uint32_t flags,
                                        mode_t mode,
                                        Error &error)
{
    std::string path(file_spec.GetPath(false));
    lldb_private::StreamString stream;
    stream.PutCString("vFile:open:");
    if (path.empty())
        return UINT64_MAX;
    stream.PutCStringAsRawHex8(path.c_str());
    stream.PutChar(',');
    stream.PutHex32(flags);
    stream.PutChar(',');
    stream.PutHex32(mode);
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
    {
        return ParseHostIOPacketResponse (response, UINT64_MAX, error);
    }
    return UINT64_MAX;
}

bool
GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
                                         Error &error)
{
    lldb_private::StreamString stream;
    stream.Printf("vFile:close:%i", (int)fd);
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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.PutCStringAsRawHex8(path.c_str());
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
    {
        if (response.GetChar() != 'F')
            return UINT64_MAX;
        uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
        return retcode;
    }
    return UINT64_MAX;
}

Error
GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
                                                 uint32_t &file_permissions)
{
    std::string path{file_spec.GetPath(false)};
    Error error;
    lldb_private::StreamString stream;
    stream.PutCString("vFile:mode:");
    stream.PutCStringAsRawHex8(path.c_str());
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
    {
        if (response.GetChar() != 'F')
        {
            error.SetErrorStringWithFormat ("invalid response to '%s' packet", packet);
        }
        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", packet);
    }
    return error;
}

uint64_t
GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
                                        uint64_t offset,
                                        void *dst,
                                        uint64_t dst_len,
                                        Error &error)
{
    lldb_private::StreamString stream;
    stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, offset);
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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,
                                         Error &error)
{
    lldb_private::StreamGDBRemote stream;
    stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset);
    stream.PutEscapedBytes(src, src_len);
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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;
}

Error
GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, const FileSpec &dst)
{
    std::string src_path{src.GetPath(false)},
                dst_path{dst.GetPath(false)};
    Error 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.PutCStringAsRawHex8(dst_path.c_str());
    stream.PutChar(',');
    stream.PutCStringAsRawHex8(src_path.c_str());
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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;
}

Error
GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec)
{
    std::string path{file_spec.GetPath(false)};
    Error 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.PutCStringAsRawHex8(path.c_str());
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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.PutCStringAsRawHex8(path.c_str());
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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.PutCStringAsRawHex8(path.c_str());
    const char* packet = stream.GetData();
    int packet_len = stream.GetSize();
    StringExtractorGDBRemote response;
    if (SendPacketAndWaitForResponse(packet, packet_len, 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)
            {
                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;
}

bool
GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, StringExtractorGDBRemote &response)
{
    Mutex::Locker locker;
    if (GetSequenceMutex (locker, "Didn't get sequence mutex for p packet."))
    {
        const bool thread_suffix_supported = GetThreadSuffixSupported();
        
        if (thread_suffix_supported || SetCurrentThread(tid))
        {
            char packet[64];
            int packet_len = 0;
            if (thread_suffix_supported)
                packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, tid);
            else
                packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
            assert (packet_len < ((int)sizeof(packet) - 1));
            return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
        }
    }
    return false;

}


bool
GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractorGDBRemote &response)
{
    Mutex::Locker locker;
    if (GetSequenceMutex (locker, "Didn't get sequence mutex for g packet."))
    {
        const bool thread_suffix_supported = GetThreadSuffixSupported();

        if (thread_suffix_supported || SetCurrentThread(tid))
        {
            char packet[64];
            int packet_len = 0;
            // Get all registers in one packet
            if (thread_suffix_supported)
                packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", tid);
            else
                packet_len = ::snprintf (packet, sizeof(packet), "g");
            assert (packet_len < ((int)sizeof(packet) - 1));
            return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
        }
    }
    return false;
}
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;
    Mutex::Locker locker;
    if (GetSequenceMutex (locker, "Didn't get sequence mutex for QSaveRegisterState."))
    {
        const bool thread_suffix_supported = GetThreadSuffixSupported();
        if (thread_suffix_supported || SetCurrentThread(tid))
        {
            char packet[256];
            if (thread_suffix_supported)
                ::snprintf (packet, sizeof(packet), "QSaveRegisterState;thread:%4.4" PRIx64 ";", tid);
            else
                ::snprintf(packet, sizeof(packet), "QSaveRegisterState");
            
            StringExtractorGDBRemote response;

            if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
            {
                if (response.IsUnsupportedResponse())
                {
                    // This packet isn't supported, don't try calling it again
                    m_supports_QSaveRegisterState = eLazyBoolNo;
                }
                    
                const uint32_t response_save_id = response.GetU32(0);
                if (response_save_id != 0)
                {
                    save_id = response_save_id;
                    return true;
                }
            }
        }
    }
    return false;
}

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;
    
    Mutex::Locker locker;
    if (GetSequenceMutex (locker, "Didn't get sequence mutex for QRestoreRegisterState."))
    {
        const bool thread_suffix_supported = GetThreadSuffixSupported();
        if (thread_suffix_supported || SetCurrentThread(tid))
        {
            char packet[256];
            if (thread_suffix_supported)
                ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u;thread:%4.4" PRIx64 ";", save_id, tid);
            else
                ::snprintf (packet, sizeof(packet), "QRestoreRegisterState:%u" PRIx64 ";", save_id);
            
            StringExtractorGDBRemote response;
            
            if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
            {
                if (response.IsOKResponse())
                {
                    return true;
                }
                else if (response.IsUnsupportedResponse())
                {
                    // This packet isn't supported, don't try calling this packet or
                    // QSaveRegisterState again...
                    m_supports_QSaveRegisterState = eLazyBoolNo;
                }
            }
        }
    }
    return false;
}

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.PutCStringAsRawHex8(module_path.c_str());
    packet.PutCString(";");
    const auto& triple = arch_spec.GetTriple().getTriple();
    packet.PutCStringAsRawHex8(triple.c_str());

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

    if (response.IsErrorResponse ())
        return false;

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

    std::string name;
    std::string value;
    bool success;
    StringExtractor extractor;

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

    while (response.GetNameColonValue (name, value))
    {
        if (name == "uuid" || name == "md5")
        {
            extractor.GetStringRef ().swap (value);
            extractor.SetFilePos (0);
            extractor.GetHexByteString (value);
            module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2);
        }
        else if (name == "triple")
        {
            extractor.GetStringRef ().swap (value);
            extractor.SetFilePos (0);
            extractor.GetHexByteString (value);
            module_spec.GetArchitecture().SetTriple (value.c_str ());
        }
        else if (name == "file_offset")
        {
            const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
            if (success)
                module_spec.SetObjectOffset (ival);
        }
        else if (name == "file_size")
        {
            const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
            if (success)
                module_spec.SetObjectSize (ival);
        }
        else if (name == "file_path")
        {
            extractor.GetStringRef ().swap (value);
            extractor.SetFilePos (0);
            extractor.GetHexByteString (value);
            module_spec.GetFileSpec() = FileSpec(value.c_str(), false, arch_spec);
        }
    }

    return true;
}

// 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::Error & 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().c_str(),
                                          chunk,
                                          false );

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

        const std::string & str = 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 += size;
            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 inital qSymbol:: packet?
    bool first_qsymbol_query = true;

    if (m_supports_qSymbol && m_qSymbol_requests_done == false)
    {
        Mutex::Locker locker;
        if (GetSequenceMutex(locker, "GDBRemoteCommunicationClient::ServeSymbolLookups() failed due to not getting the sequence mutex"))
        {
            StreamString packet;
            packet.PutCString ("qSymbol::");
            StringExtractorGDBRemote response;
            while (SendPacketAndWaitForResponseNoLock(packet.GetData(), packet.GetSize(), 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;
                            if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list))
                            {
                                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;

        }
    }
}

