[Lldb-commits] [lldb] r280751 - *** This commit represents a complete reformatting of the LLDB source code

Kate Stone via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 6 13:58:36 PDT 2016


Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue Sep  6 15:57:50 2016
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "GDBRemoteCommunicationClient.h"
 
 // C Includes
@@ -15,35 +14,35 @@
 #include <sys/stat.h>
 
 // C++ Includes
-#include <sstream>
 #include <numeric>
+#include <sstream>
 
 // Other libraries and framework includes
+#include "lldb/Core/DataBufferHeap.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/Core/DataBufferHeap.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Target/UnixSignals.h"
 #include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Target/Target.h"
 
 // Project includes
-#include "Utility/StringExtractorGDBRemote.h"
 #include "ProcessGDBRemote.h"
 #include "ProcessGDBRemoteLog.h"
+#include "Utility/StringExtractorGDBRemote.h"
 #include "lldb/Host/Config.h"
 
 #include "llvm/ADT/StringSwitch.h"
 
-#if defined (HAVE_LIBCOMPRESSION)
+#if defined(HAVE_LIBCOMPRESSION)
 #include <compression.h>
 #endif
 
@@ -76,8 +75,7 @@ GDBRemoteCommunicationClient::GDBRemoteC
       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_supports_p(eLazyBoolCalculate), m_supports_x(eLazyBoolCalculate),
       m_avoid_g_packets(eLazyBoolCalculate),
       m_supports_QSaveRegisterState(eLazyBoolCalculate),
       m_supports_qXfer_auxv_read(eLazyBoolCalculate),
@@ -88,532 +86,452 @@ GDBRemoteCommunicationClient::GDBRemoteC
       m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
       m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
       m_supports_jGetSharedCacheInfo(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_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_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),
-      m_qSupported_response(),
-      m_supported_async_json_packets_is_valid(false),
-      m_supported_async_json_packets_sp()
-{
-}
+      m_num_supported_hardware_watchpoints(0), 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),
+      m_qSupported_response(), m_supported_async_json_packets_is_valid(false),
+      m_supported_async_json_packets_sp() {}
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
-{
-    if (IsConnected())
-        Disconnect();
+GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() {
+  if (IsConnected())
+    Disconnect();
 }
 
-bool
-GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
-{
-    ResetDiscoverableSettings(false);
+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;
-}
+  // 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);
 
-bool
-GDBRemoteCommunicationClient::GetEchoSupported ()
-{
-    if (m_supports_qEcho == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
+    // 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");
     }
-    return m_supports_qEcho == eLazyBoolYes;
+  } else {
+    if (error_ptr)
+      error_ptr->SetErrorString("failed to send the handshake ack");
+  }
+  return false;
 }
 
-
-bool
-GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
-{
-    if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetEchoSupported() {
+  if (m_supports_qEcho == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qEcho == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
-{
-    if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
+  if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
-{
-    if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_libraries_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
+  if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
-{
-    if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_auxv_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
+  if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_libraries_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported ()
-{
-    if (m_supports_qXfer_features_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_features_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
+  if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_auxv_read == eLazyBoolYes;
 }
 
-uint64_t
-GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
-{
-    if (m_max_packet_size == 0)
-    {
-        GetRemoteQSupported();
-    }
-    return m_max_packet_size;
+bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
+  if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_features_read == eLazyBoolYes;
 }
 
-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;
+uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
+  if (m_max_packet_size == 0) {
+    GetRemoteQSupported();
+  }
+  return m_max_packet_size;
 }
 
-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::QueryNoAckModeSupported() {
+  if (m_supports_not_sending_acks == eLazyBoolCalculate) {
+    m_send_acks = true;
+    m_supports_not_sending_acks = eLazyBoolNo;
 
-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;
-}
+    // 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.
 
-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;
-        }
+    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;
     }
-    if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
-        return true;
-    else
-        return false;
+  }
+  return false;
 }
 
+void GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported() {
+  if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) {
+    m_supports_threads_in_stop_reply = eLazyBoolNo;
 
-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;
-        m_qSupported_response.clear();
-        m_supported_async_json_packets_is_valid = false;
-        m_supported_async_json_packets_sp.reset();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        m_supports_threads_in_stop_reply = eLazyBoolYes;
     }
-
-    // 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
+bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
+  if (m_attach_or_wait_reply == eLazyBoolCalculate) {
+    m_attach_or_wait_reply = eLazyBoolNo;
 
-    // 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("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;
+}
 
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet.GetData(),
-                                     response,
-                                     /*send_async=*/false) == PacketResult::Success)
-    {
-        const char *response_cstr = response.GetStringRef().c_str();
-
-        // Hang on to the qSupported packet, so that platforms can do custom
-        // configuration of the transport before attaching/launching the
-        // process.
-        m_qSupported_response = response_cstr;
-
-        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;
-                    }
+bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
+  if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
+    m_prepare_for_reg_writing_reply = eLazyBoolNo;
 
-                    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;
-                    }
-                }
+    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;
+}
 
-                if (supported_compressions.size() > 0)
-                {
-                    MaybeEnableCompression (supported_compressions);
-                }
-            }
+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;
+    m_qSupported_response.clear();
+    m_supported_async_json_packets_is_valid = false;
+    m_supported_async_json_packets_sp.reset();
+  }
+
+  // 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();
+
+    // Hang on to the qSupported packet, so that platforms can do custom
+    // configuration of the transport before attaching/launching the
+    // process.
+    m_qSupported_response = response_cstr;
+
+    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 (::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");
-            }
+        if (supported_compressions.size() > 0) {
+          MaybeEnableCompression(supported_compressions);
         }
+      }
     }
-}
 
-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;
-        }
+    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");
+      }
     }
-    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;
+
+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;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload,
-                                                                         StringExtractorGDBRemote &response,
-                                                                         bool send_async)
-{
-    Lock lock(*this, send_async);
-    if (!lock)
-    {
-        if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
-            log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex for %s packet.", __FUNCTION__,
-                        payload.GetString().c_str());
-        return PacketResult::ErrorNoSequenceLock;
-    }
-
-    if (GetThreadSuffixSupported())
-        payload.Printf(";thread:%4.4" PRIx64 ";", tid);
-    else
-    {
-        if (!SetCurrentThread(tid))
-            return PacketResult::ErrorSendFailed;
-    }
+GDBRemoteCommunicationClient::SendThreadSpecificPacketAndWaitForResponse(
+    lldb::tid_t tid, StreamString &&payload, StringExtractorGDBRemote &response,
+    bool send_async) {
+  Lock lock(*this, send_async);
+  if (!lock) {
+    if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
+            GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
+      log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex "
+                  "for %s packet.",
+                  __FUNCTION__, payload.GetString().c_str());
+    return PacketResult::ErrorNoSequenceLock;
+  }
+
+  if (GetThreadSuffixSupported())
+    payload.Printf(";thread:%4.4" PRIx64 ";", tid);
+  else {
+    if (!SetCurrentThread(tid))
+      return PacketResult::ErrorSendFailed;
+  }
 
-    return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
+  return SendPacketAndWaitForResponseNoLock(payload.GetString(), response);
 }
 
 // Check if the target supports 'p' packet. It sends out a 'p'
@@ -621,3045 +539,2697 @@ GDBRemoteCommunicationClient::SendThread
 // that support is available.
 //
 // Takes a valid thread ID because p needs to apply to a thread.
-bool
-GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
-{
-    if (m_supports_p == eLazyBoolCalculate)
-    {
-        m_supports_p = eLazyBoolNo;
-        StreamString payload;
-        payload.PutCString("p0");
-        StringExtractorGDBRemote response;
-        if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) ==
-                PacketResult::Success &&
-            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());
-            }
-        }
+bool GDBRemoteCommunicationClient::GetpPacketSupported(lldb::tid_t tid) {
+  if (m_supports_p == eLazyBoolCalculate) {
+    m_supports_p = eLazyBoolNo;
+    StreamString payload;
+    payload.PutCString("p0");
+    StringExtractorGDBRemote response;
+    if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+                                                   response, false) ==
+            PacketResult::Success &&
+        response.IsNormalResponse()) {
+      m_supports_p = eLazyBoolYes;
     }
-    return object_sp;
+  }
+  return m_supports_p;
 }
 
+StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() {
+  // Get information on all threads at one using the "jThreadsInfo" packet
+  StructuredData::ObjectSP 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;
-            }
-        }
+  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 m_supports_jLoadedDynamicLibrariesInfos;
+  }
+  return object_sp;
 }
 
-bool
-GDBRemoteCommunicationClient::GetSharedCacheInfoSupported ()
-{
-    if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate)
-    {
-        StringExtractorGDBRemote response;
-        m_supports_jGetSharedCacheInfo = eLazyBoolNo;
-        if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-            {
-                m_supports_jGetSharedCacheInfo = eLazyBoolYes;
-            }
-        }
+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_jGetSharedCacheInfo;
+  }
+  return m_supports_jThreadExtendedInfo;
 }
 
-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;
-        }
+bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
+  if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
+    StringExtractorGDBRemote response;
+    m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo;
+    if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:",
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse()) {
+        m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes;
+      }
+    }
+  }
+  return m_supports_jLoadedDynamicLibrariesInfos;
+}
+
+bool GDBRemoteCommunicationClient::GetSharedCacheInfoSupported() {
+  if (m_supports_jGetSharedCacheInfo == eLazyBoolCalculate) {
+    StringExtractorGDBRemote response;
+    m_supports_jGetSharedCacheInfo = eLazyBoolNo;
+    if (SendPacketAndWaitForResponse("jGetSharedCacheInfo:", response, false) ==
+        PacketResult::Success) {
+      if (response.IsOKResponse()) {
+        m_supports_jGetSharedCacheInfo = eLazyBoolYes;
+      }
+    }
+  }
+  return m_supports_jGetSharedCacheInfo;
+}
+
+bool GDBRemoteCommunicationClient::GetxPacketSupported() {
+  if (m_supports_x == eLazyBoolCalculate) {
+    StringExtractorGDBRemote response;
+    m_supports_x = eLazyBoolNo;
+    char packet[256];
+    snprintf(packet, sizeof(packet), "x0,0");
+    if (SendPacketAndWaitForResponse(packet, response, false) ==
+        PacketResult::Success) {
+      if (response.IsOKResponse())
+        m_supports_x = eLazyBoolYes;
     }
-    return m_supports_x;
+  }
+  return m_supports_x;
 }
 
 GDBRemoteCommunicationClient::PacketResult
-GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
-(
-    const char *payload_prefix,
-    std::string &response_string
-)
-{
-    Lock lock(*this, false);
-    if (!lock)
-    {
-        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
-        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 = SendPacketAndWaitForResponseNoLock(payload_prefix_str + sizeDescriptor, this_response);
-        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::SendPacketsAndConcatenateResponses(
+    const char *payload_prefix, std::string &response_string) {
+  Lock lock(*this, false);
+  if (!lock) {
+    Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS |
+                                                           GDBR_LOG_PACKETS));
+    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 = SendPacketAndWaitForResponseNoLock(
+        payload_prefix_str + sizeDescriptor, this_response);
+    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;
+  }
+}
+
+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;
 }
 
-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;
+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);
     }
-    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;
-            }
-        }
+  }
+  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);
     }
-    
-    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");
+    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 false;
+  }
+  return -1;
 }
 
-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;
+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;
+      }
     }
-    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;
-            }
+    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;
+  }
+  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;
-        }
+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;
+  }
+  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;
-            }
-        }
+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;
+  }
+  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;
-        }
+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;
+  }
+  return false;
 }
 
-bool
-GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
-{
-    if (GetHostInfo ())
-    {
-        if (!m_os_build.empty())
-        {
-            s = m_os_build;
-            return true;
-        }
+bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
+  if (GetHostInfo()) {
+    if (!m_os_build.empty()) {
+      s = m_os_build;
+      return true;
     }
-    s.clear();
-    return false;
+  }
+  s.clear();
+  return false;
 }
 
-
-bool
-GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
-{
-    if (GetHostInfo ())
-    {
-        if (!m_os_kernel.empty())
-        {
-            s = m_os_kernel;
-            return true;
-        }
+bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
+  if (GetHostInfo()) {
+    if (!m_os_kernel.empty()) {
+      s = m_os_kernel;
+      return true;
     }
-    s.clear();
-    return false;
+  }
+  s.clear();
+  return false;
 }
 
-bool
-GDBRemoteCommunicationClient::GetHostname (std::string &s)
-{
-    if (GetHostInfo ())
-    {
-        if (!m_hostname.empty())
-        {
-            s = m_hostname;
-            return true;
-        }
+bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
+  if (GetHostInfo()) {
+    if (!m_hostname.empty()) {
+      s = m_hostname;
+      return true;
     }
-    s.clear();
-    return false;
+  }
+  s.clear();
+  return false;
 }
 
-ArchSpec
-GDBRemoteCommunicationClient::GetSystemArchitecture ()
-{
-    if (GetHostInfo ())
-        return m_host_arch;
-    return ArchSpec();
+ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
+  if (GetHostInfo())
+    return m_host_arch;
+  return ArchSpec();
 }
 
 const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetProcessArchitecture ()
-{
-    if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
-        GetCurrentProcessInfo ();
-    return m_process_arch;
-}
-
-bool
-GDBRemoteCommunicationClient::GetGDBServerVersion()
-{
-    if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
-    {
-        m_gdb_server_name.clear();
-        m_gdb_server_version = 0;
-        m_qGDBServerVersion_is_valid = eLazyBoolNo;
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
-        {
-            if (response.IsNormalResponse())
-            {
-                llvm::StringRef name, value;
-                bool success = false;
-                while (response.GetNameColonValue(name, value))
-                {
-                    if (name.equals("name"))
-                    {
-                        success = true;
-                        m_gdb_server_name = value;
-                    }
-                    else if (name.equals("version"))
-                    {
-                        llvm::StringRef major, minor;
-                        std::tie(major, minor) = value.split('.');
-                        if (!major.getAsInteger(0, m_gdb_server_version))
-                            success = true;
-                    }
-                }
-                if (success)
-                    m_qGDBServerVersion_is_valid = eLazyBoolYes;
-            }
-        }
-    }
-    return m_qGDBServerVersion_is_valid == eLazyBoolYes;
-}
-
-void
-GDBRemoteCommunicationClient::MaybeEnableCompression (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;
-            }
-        }
+GDBRemoteCommunicationClient::GetProcessArchitecture() {
+  if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+    GetCurrentProcessInfo();
+  return m_process_arch;
+}
+
+bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
+  if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
+    m_gdb_server_name.clear();
+    m_gdb_server_version = 0;
+    m_qGDBServerVersion_is_valid = eLazyBoolNo;
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
+        PacketResult::Success) {
+      if (response.IsNormalResponse()) {
+        llvm::StringRef name, value;
+        bool success = false;
+        while (response.GetNameColonValue(name, value)) {
+          if (name.equals("name")) {
+            success = true;
+            m_gdb_server_name = value;
+          } else if (name.equals("version")) {
+            llvm::StringRef major, minor;
+            std::tie(major, minor) = value.split('.');
+            if (!major.getAsInteger(0, m_gdb_server_version))
+              success = true;
+          }
+        }
+        if (success)
+          m_qGDBServerVersion_is_valid = eLazyBoolYes;
+      }
+    }
+  }
+  return m_qGDBServerVersion_is_valid == eLazyBoolYes;
+}
+
+void GDBRemoteCommunicationClient::MaybeEnableCompression(
+    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;
-            }
-        }
+#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;
-            }
-        }
+#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;
-            }
-        }
+#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;
-            }
-        }
+#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;
-        }
+  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;
+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())
-            {
-                llvm::StringRef name;
-                llvm::StringRef value;
-                uint32_t cpu = LLDB_INVALID_CPUTYPE;
-                uint32_t sub = 0;
-                std::string arch_name;
-                std::string os_name;
-                std::string vendor_name;
-                std::string triple;
-                std::string distribution_id;
-                uint32_t pointer_byte_size = 0;
-                ByteOrder byte_order = eByteOrderInvalid;
-                uint32_t num_keys_decoded = 0;
-                while (response.GetNameColonValue(name, value))
-                {
-                    if (name.equals("cputype"))
-                    {
-                        // exception type in big endian hex
-                        if (!value.getAsInteger(0, cpu))
-                            ++num_keys_decoded;
-                    }
-                    else if (name.equals("cpusubtype"))
-                    {
-                        // exception count in big endian hex
-                        if (!value.getAsInteger(0, sub))
-                            ++num_keys_decoded;
-                    }
-                    else if (name.equals("arch"))
-                    {
-                        arch_name = value;
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("triple"))
-                    {
-                        StringExtractor extractor(value);
-                        extractor.GetHexByteString (triple);
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("distribution_id"))
-                    {
-                        StringExtractor extractor(value);
-                        extractor.GetHexByteString (distribution_id);
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("os_build"))
-                    {
-                        StringExtractor extractor(value);
-                        extractor.GetHexByteString (m_os_build);
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("hostname"))
-                    {
-                        StringExtractor extractor(value);
-                        extractor.GetHexByteString (m_hostname);
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("os_kernel"))
-                    {
-                        StringExtractor extractor(value);
-                        extractor.GetHexByteString (m_os_kernel);
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("ostype"))
-                    {
-                        os_name = value;
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("vendor"))
-                    {
-                        vendor_name = value;
-                        ++num_keys_decoded;
-                    }
-                    else if (name.equals("endian"))
-                    {
-                        byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
-                                         .Case("little", eByteOrderLittle)
-                                         .Case("big", eByteOrderBig)
-                                         .Case("pdp", eByteOrderPDP)
-                                         .Default(eByteOrderInvalid);
-                        if (byte_order != eByteOrderInvalid)
-                            ++num_keys_decoded;
-                    }
-                    else if (name.equals("ptrsize"))
-                    {
-                        if (!value.getAsInteger(0, pointer_byte_size))
-                            ++num_keys_decoded;
-                    }
-                    else if (name.equals("os_version") || name.equals("version")) // Older debugserver binaries used the
-                                                                                  // "version" key instead of
-                                                                                  // "os_version"...
-                    {
-                        Args::StringToVersion(value.str().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.equals("watchpoint_exceptions_received"))
-                    {
-                        m_watchpoints_trigger_after_instruction = llvm::StringSwitch<LazyBool>(value)
-                                                                      .Case("before", eLazyBoolNo)
-                                                                      .Case("after", eLazyBoolYes)
-                                                                      .Default(eLazyBoolCalculate);
-                        if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
-                            ++num_keys_decoded;
-                    }
-                    else if (name.equals("default_packet_timeout"))
-                    {
-                        if (!value.getAsInteger(0, m_default_packet_timeout))
-                        {
-                            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;
+uint32_t GDBRemoteCommunicationClient::GetGDBServerProgramVersion() {
+  if (GetGDBServerVersion())
+    return m_gdb_server_version;
+  return 0;
 }
 
-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;
-        }
-    }
+bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse("qC", response, false) !=
+      PacketResult::Success)
     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)
-        {
-            llvm::StringRef name;
-            llvm::StringRef value;
-            addr_t addr_value = LLDB_INVALID_ADDRESS;
-            bool success = true;
-            bool saw_permissions = false;
-            while (success && response.GetNameColonValue(name, value))
-            {
-                if (name.equals("start"))
-                {
-                    if (!value.getAsInteger(16, addr_value))
-                        region_info.GetRange().SetRangeBase(addr_value);
-                }
-                else if (name.equals("size"))
-                {
-                    if (!value.getAsInteger(16, addr_value))
-                        region_info.GetRange().SetByteSize(addr_value);
-                }
-                else if (name.equals("permissions") && region_info.GetRange().IsValid())
-                {
-                    saw_permissions = true;
-                    if (region_info.GetRange().Contains (addr))
-                    {
-                        if (value.find('r') != llvm::StringRef::npos)
-                            region_info.SetReadable (MemoryRegionInfo::eYes);
-                        else
-                            region_info.SetReadable (MemoryRegionInfo::eNo);
-
-                        if (value.find('w') != llvm::StringRef::npos)
-                            region_info.SetWritable (MemoryRegionInfo::eYes);
-                        else
-                            region_info.SetWritable (MemoryRegionInfo::eNo);
-
-                        if (value.find('x') != llvm::StringRef::npos)
-                            region_info.SetExecutable (MemoryRegionInfo::eYes);
-                        else
-                            region_info.SetExecutable (MemoryRegionInfo::eNo);
-
-                        region_info.SetMapped(MemoryRegionInfo::eYes);
-                    }
-                    else
-                    {
-                        // The reported region does not contain this address -- we're looking at an unmapped page
-                        region_info.SetReadable (MemoryRegionInfo::eNo);
-                        region_info.SetWritable (MemoryRegionInfo::eNo);
-                        region_info.SetExecutable (MemoryRegionInfo::eNo);
-                        region_info.SetMapped(MemoryRegionInfo::eNo);
-                    }
-                }
-                else if (name.equals("name"))
-                {
-                    StringExtractorGDBRemote name_extractor(value);
-                    std::string name;
-                    name_extractor.GetHexByteString(name);
-                    region_info.SetName(name.c_str());
-                }
-                else if (name.equals("error"))
-                {
-                    StringExtractorGDBRemote error_extractor(value);
-                    std::string error_string;
-                    // Now convert the HEX bytes into a string value
-                    error_extractor.GetHexByteString(error_string);
-                    error.SetErrorString(error_string.c_str());
-                }
-            }
-
-            // 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;
-            llvm::StringRef name;
-            llvm::StringRef value;
-            while (response.GetNameColonValue(name, value))
-            {
-                if (name.equals("num"))
-                {
-                    value.getAsInteger(0, m_num_supported_hardware_watchpoints);
-                    num = m_num_supported_hardware_watchpoints;
-                }
-            }
-        }
-        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();
-    }
+  if (!response.IsNormalResponse())
     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;
-}
+  if (response.GetChar() == 'Q' && response.GetChar() == 'C')
+    tid = response.GetHexMaxU32(true, -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;
+  return true;
 }
 
+bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));
 
-bool
-GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
-{
-    if (response.IsNormalResponse())
-    {
+  if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) {
+    m_qHostInfo_is_valid = eLazyBoolNo;
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qHostInfo", response, false) ==
+        PacketResult::Success) {
+      if (response.IsNormalResponse()) {
         llvm::StringRef name;
         llvm::StringRef value;
-        StringExtractor extractor;
-
         uint32_t cpu = LLDB_INVALID_CPUTYPE;
         uint32_t sub = 0;
-        std::string vendor;
-        std::string os_type;
-
-        while (response.GetNameColonValue(name, value))
-        {
-            if (name.equals("pid"))
-            {
-                lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-                value.getAsInteger(0, pid);
-                process_info.SetProcessID(pid);
-            }
-            else if (name.equals("ppid"))
-            {
-                lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-                value.getAsInteger(0, pid);
-                process_info.SetParentProcessID(pid);
-            }
-            else if (name.equals("uid"))
-            {
-                uint32_t uid = UINT32_MAX;
-                value.getAsInteger(0, uid);
-                process_info.SetUserID(uid);
-            }
-            else if (name.equals("euid"))
-            {
-                uint32_t uid = UINT32_MAX;
-                value.getAsInteger(0, uid);
-                process_info.SetEffectiveGroupID(uid);
-            }
-            else if (name.equals("gid"))
-            {
-                uint32_t gid = UINT32_MAX;
-                value.getAsInteger(0, gid);
-                process_info.SetGroupID(gid);
-            }
-            else if (name.equals("egid"))
-            {
-                uint32_t gid = UINT32_MAX;
-                value.getAsInteger(0, gid);
-                process_info.SetEffectiveGroupID(gid);
-            }
-            else if (name.equals("triple"))
-            {
-                StringExtractor extractor(value);
-                std::string triple;
-                extractor.GetHexByteString(triple);
-                process_info.GetArchitecture().SetTriple(triple.c_str());
-            }
-            else if (name.equals("name"))
-            {
-                StringExtractor extractor(value);
-                // The process name from ASCII hex bytes since we can't 
-                // control the characters in a process name
-                std::string name;
-                extractor.GetHexByteString(name);
-                process_info.GetExecutableFile().SetFile(name.c_str(), false);
-            }
-            else if (name.equals("cputype"))
-            {
-                value.getAsInteger(0, cpu);
-            }
-            else if (name.equals("cpusubtype"))
-            {
-                value.getAsInteger(0, sub);
-            }
-            else if (name.equals("vendor"))
-            {
-                vendor = value;
-            }
-            else if (name.equals("ostype"))
-            {
-                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));
+        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;
+        ByteOrder byte_order = eByteOrderInvalid;
+        uint32_t num_keys_decoded = 0;
+        while (response.GetNameColonValue(name, value)) {
+          if (name.equals("cputype")) {
+            // exception type in big endian hex
+            if (!value.getAsInteger(0, cpu))
+              ++num_keys_decoded;
+          } else if (name.equals("cpusubtype")) {
+            // exception count in big endian hex
+            if (!value.getAsInteger(0, sub))
+              ++num_keys_decoded;
+          } else if (name.equals("arch")) {
+            arch_name = value;
+            ++num_keys_decoded;
+          } else if (name.equals("triple")) {
+            StringExtractor extractor(value);
+            extractor.GetHexByteString(triple);
+            ++num_keys_decoded;
+          } else if (name.equals("distribution_id")) {
+            StringExtractor extractor(value);
+            extractor.GetHexByteString(distribution_id);
+            ++num_keys_decoded;
+          } else if (name.equals("os_build")) {
+            StringExtractor extractor(value);
+            extractor.GetHexByteString(m_os_build);
+            ++num_keys_decoded;
+          } else if (name.equals("hostname")) {
+            StringExtractor extractor(value);
+            extractor.GetHexByteString(m_hostname);
+            ++num_keys_decoded;
+          } else if (name.equals("os_kernel")) {
+            StringExtractor extractor(value);
+            extractor.GetHexByteString(m_os_kernel);
+            ++num_keys_decoded;
+          } else if (name.equals("ostype")) {
+            os_name = value;
+            ++num_keys_decoded;
+          } else if (name.equals("vendor")) {
+            vendor_name = value;
+            ++num_keys_decoded;
+          } else if (name.equals("endian")) {
+            byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
+                             .Case("little", eByteOrderLittle)
+                             .Case("big", eByteOrderBig)
+                             .Case("pdp", eByteOrderPDP)
+                             .Default(eByteOrderInvalid);
+            if (byte_order != eByteOrderInvalid)
+              ++num_keys_decoded;
+          } else if (name.equals("ptrsize")) {
+            if (!value.getAsInteger(0, pointer_byte_size))
+              ++num_keys_decoded;
+          } else if (name.equals("os_version") ||
+                     name.equals(
+                         "version")) // Older debugserver binaries used the
+                                     // "version" key instead of
+                                     // "os_version"...
+          {
+            Args::StringToVersion(value.str().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.equals("watchpoint_exceptions_received")) {
+            m_watchpoints_trigger_after_instruction =
+                llvm::StringSwitch<LazyBool>(value)
+                    .Case("before", eLazyBoolNo)
+                    .Case("after", eLazyBoolYes)
+                    .Default(eLazyBoolCalculate);
+            if (m_watchpoints_trigger_after_instruction != eLazyBoolCalculate)
+              ++num_keys_decoded;
+          } else if (name.equals("default_packet_timeout")) {
+            if (!value.getAsInteger(0, m_default_packet_timeout)) {
+              SetPacketTimeout(m_default_packet_timeout);
+              ++num_keys_decoded;
+            }
+          }
+        }
+
+        if (num_keys_decoded > 0)
+          m_qHostInfo_is_valid = eLazyBoolYes;
+
+        if (triple.empty()) {
+          if (arch_name.empty()) {
+            if (cpu != LLDB_INVALID_CPUTYPE) {
+              m_host_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+              if (pointer_byte_size) {
+                assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
+              }
+              if (byte_order != eByteOrderInvalid) {
+                assert(byte_order == m_host_arch.GetByteOrder());
+              }
+
+              if (!vendor_name.empty())
+                m_host_arch.GetTriple().setVendorName(
+                    llvm::StringRef(vendor_name));
+              if (!os_name.empty())
+                m_host_arch.GetTriple().setOSName(llvm::StringRef(os_name));
             }
-        }
-        
-        if (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())
-        {
-            llvm::StringRef name;
-            llvm::StringRef value;
-            uint32_t cpu = LLDB_INVALID_CPUTYPE;
-            uint32_t sub = 0;
-            std::string arch_name;
-            std::string os_name;
-            std::string vendor_name;
+          } else {
             std::string triple;
-            uint32_t pointer_byte_size = 0;
-            StringExtractor extractor;
-            ByteOrder byte_order = eByteOrderInvalid;
-            uint32_t num_keys_decoded = 0;
-            lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-            while (response.GetNameColonValue(name, value))
-            {
-                if (name.equals("cputype"))
-                {
-                    if (!value.getAsInteger(16, cpu))
-                        ++num_keys_decoded;
-                }
-                else if (name.equals("cpusubtype"))
-                {
-                    if (!value.getAsInteger(16, sub))
-                        ++num_keys_decoded;
-                }
-                else if (name.equals("triple"))
-                {
-                    StringExtractor extractor(value);
-                    extractor.GetHexByteString (triple);
-                    ++num_keys_decoded;
-                }
-                else if (name.equals("ostype"))
-                {
-                    os_name = value;
-                    ++num_keys_decoded;
-                }
-                else if (name.equals("vendor"))
-                {
-                    vendor_name = value;
-                    ++num_keys_decoded;
-                }
-                else if (name.equals("endian"))
-                {
-                    byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
-                                     .Case("little", eByteOrderLittle)
-                                     .Case("big", eByteOrderBig)
-                                     .Case("pdp", eByteOrderPDP)
-                                     .Default(eByteOrderInvalid);
-                    if (byte_order != eByteOrderInvalid)
-                        ++num_keys_decoded;
-                }
-                else if (name.equals("ptrsize"))
-                {
-                    if (!value.getAsInteger(16, pointer_byte_size))
-                        ++num_keys_decoded;
-                }
-                else if (name.equals("pid"))
-                {
-                    if (!value.getAsInteger(16, pid))
-                        ++num_keys_decoded;
-                }
-            }
-            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 ());
-                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 (';');
-                }
+            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 (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 (';');
+            if (pointer_byte_size) {
+              assert(pointer_byte_size == m_host_arch.GetAddressByteSize());
             }
-        }
-        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;
+            if (byte_order != eByteOrderInvalid) {
+              assert(byte_order == m_host_arch.GetByteOrder());
             }
-        }
-        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);
+          }
+        } 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));
-
-    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:*;");
-        }
-    }
-    // give the process a few seconds to startup
-    GDBRemoteCommunication::ScopedTimeout timeout (*this, 10);
-
-    if (SendPacketAndWaitForResponse(stream.GetString(), response, false) == PacketResult::Success)
-    {
-        llvm::StringRef name;
-        llvm::StringRef value;
-        while (response.GetNameColonValue(name, value))
-        {
-            if (name.equals("port"))
-                value.getAsInteger(0, port);
-            else if (name.equals("pid"))
-                value.getAsInteger(0, pid);
-            else if (name.compare("socket_name") == 0)
-            {
-                StringExtractor extractor(value);
-                extractor.GetHexByteString(socket_name);
-            }
-        }
-        return true;
-    }
-    return false;
+    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();
 }
 
-size_t
-GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls)
-{
-    connection_urls.clear();
-
+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("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();
-
+    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.IsOKResponse())
-            return true;
-    }
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
-{
-    if (m_curr_tid == tid)
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+        PacketResult::Success) {
+      if (response.IsUnsupportedResponse())
+        m_supports_alloc_dealloc_memory = eLazyBoolNo;
+      else if (response.IsOKResponse())
         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;
-        }
+    } else {
+      m_supports_alloc_dealloc_memory = eLazyBoolNo;
     }
-    return false;
+  }
+  return false;
 }
 
-bool
-GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
-{
-    if (m_curr_tid_run == tid)
-        return true;
+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();
 
-    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));
+  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)
-    {
-        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;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+        PacketResult::Success) {
+      llvm::StringRef name;
+      llvm::StringRef value;
+      addr_t addr_value = LLDB_INVALID_ADDRESS;
+      bool success = true;
+      bool saw_permissions = false;
+      while (success && response.GetNameColonValue(name, value)) {
+        if (name.equals("start")) {
+          if (!value.getAsInteger(16, addr_value))
+            region_info.GetRange().SetRangeBase(addr_value);
+        } else if (name.equals("size")) {
+          if (!value.getAsInteger(16, addr_value))
+            region_info.GetRange().SetByteSize(addr_value);
+        } else if (name.equals("permissions") &&
+                   region_info.GetRange().IsValid()) {
+          saw_permissions = true;
+          if (region_info.GetRange().Contains(addr)) {
+            if (value.find('r') != llvm::StringRef::npos)
+              region_info.SetReadable(MemoryRegionInfo::eYes);
             else
-                return false;
-        }
-        else
-        {
-            m_supports_qThreadStopInfo = false;
-        }
-    }
-    return false;
-}
+              region_info.SetReadable(MemoryRegionInfo::eNo);
 
+            if (value.find('w') != llvm::StringRef::npos)
+              region_info.SetWritable(MemoryRegionInfo::eYes);
+            else
+              region_info.SetWritable(MemoryRegionInfo::eNo);
 
-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();
+            if (value.find('x') != llvm::StringRef::npos)
+              region_info.SetExecutable(MemoryRegionInfo::eYes);
+            else
+              region_info.SetExecutable(MemoryRegionInfo::eNo);
 
-        // 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;
+            region_info.SetMapped(MemoryRegionInfo::eYes);
+          } else {
+            // The reported region does not contain this address -- we're
+            // looking at an unmapped page
+            region_info.SetReadable(MemoryRegionInfo::eNo);
+            region_info.SetWritable(MemoryRegionInfo::eNo);
+            region_info.SetExecutable(MemoryRegionInfo::eNo);
+            region_info.SetMapped(MemoryRegionInfo::eNo);
+          }
+        } else if (name.equals("name")) {
+          StringExtractorGDBRemote name_extractor(value);
+          std::string name;
+          name_extractor.GetHexByteString(name);
+          region_info.SetName(name.c_str());
+        } else if (name.equals("error")) {
+          StringExtractorGDBRemote error_extractor(value);
+          std::string error_string;
+          // Now convert the HEX bytes into a string value
+          error_extractor.GetHexByteString(error_string);
+          error.SetErrorString(error_string.c_str());
+        }
+      }
+
+      // 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;
 }
 
-size_t
-GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids, 
-                                                   bool &sequence_mutex_unavailable)
-{
-    thread_ids.clear();
+Error GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) {
+  Error error;
 
-    Lock lock(*this, false);
-    if (lock)
-    {
-        sequence_mutex_unavailable = false;
-        StringExtractorGDBRemote response;
-        
-        PacketResult packet_result;
-        for (packet_result = SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
-             packet_result == PacketResult::Success && response.IsNormalResponse();
-             packet_result = SendPacketAndWaitForResponseNoLock("qsThreadInfo", response))
-        {
-            char ch = response.GetChar();
-            if (ch == 'l')
-                break;
-            if (ch == 'm')
-            {
-                do
-                {
-                    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();
-}
+  if (m_supports_watchpoint_support_info == eLazyBoolYes) {
+    num = m_num_supported_hardware_watchpoints;
+    return error;
+  }
 
-lldb::addr_t
-GDBRemoteCommunicationClient::GetShlibInfoAddr()
-{
+  // 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("qShlibInfoAddr", response, false) != PacketResult::Success || !response.IsNormalResponse())
-        return LLDB_INVALID_ADDRESS;
-    return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+        PacketResult::Success) {
+      m_supports_watchpoint_support_info = eLazyBoolYes;
+      llvm::StringRef name;
+      llvm::StringRef value;
+      while (response.GetNameColonValue(name, value)) {
+        if (name.equals("num")) {
+          value.getAsInteger(0, m_num_supported_hardware_watchpoints);
+          num = m_num_supported_hardware_watchpoints;
+        }
+      }
+    } 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::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);
+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;
 }
 
-Error
-GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec,
-                                                 uint32_t file_permissions)
-{
+int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
+  if (file_spec) {
     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);
-}
+    StreamString packet;
+    packet.PutCString("QSetSTDIN:");
+    packet.PutCStringAsRawHex8(path.c_str());
 
-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);
+    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 UINT64_MAX;
+  }
+  return -1;
 }
 
-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;
-}
+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());
 
-// 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;
+    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 UINT64_MAX;
+  }
+  return -1;
 }
 
-Error
-GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec,
-                                                 uint32_t &file_permissions)
-{
+int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
+  if (file_spec) {
     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();
+    StreamString packet;
+    packet.PutCString("QSetSTDERR:");
+    packet.PutCStringAsRawHex8(path.c_str());
+
     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);
+    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 error;
+  }
+  return -1;
 }
 
-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;
+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;
 }
 
-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");
+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 0;
+  }
+  return -1;
 }
 
-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;
+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;
 }
 
-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();
+bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
+    StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
+  if (response.IsNormalResponse()) {
+    llvm::StringRef name;
+    llvm::StringRef value;
+    StringExtractor extractor;
+
+    uint32_t cpu = LLDB_INVALID_CPUTYPE;
+    uint32_t sub = 0;
+    std::string vendor;
+    std::string os_type;
+
+    while (response.GetNameColonValue(name, value)) {
+      if (name.equals("pid")) {
+        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+        value.getAsInteger(0, pid);
+        process_info.SetProcessID(pid);
+      } else if (name.equals("ppid")) {
+        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+        value.getAsInteger(0, pid);
+        process_info.SetParentProcessID(pid);
+      } else if (name.equals("uid")) {
+        uint32_t uid = UINT32_MAX;
+        value.getAsInteger(0, uid);
+        process_info.SetUserID(uid);
+      } else if (name.equals("euid")) {
+        uint32_t uid = UINT32_MAX;
+        value.getAsInteger(0, uid);
+        process_info.SetEffectiveGroupID(uid);
+      } else if (name.equals("gid")) {
+        uint32_t gid = UINT32_MAX;
+        value.getAsInteger(0, gid);
+        process_info.SetGroupID(gid);
+      } else if (name.equals("egid")) {
+        uint32_t gid = UINT32_MAX;
+        value.getAsInteger(0, gid);
+        process_info.SetEffectiveGroupID(gid);
+      } else if (name.equals("triple")) {
+        StringExtractor extractor(value);
+        std::string triple;
+        extractor.GetHexByteString(triple);
+        process_info.GetArchitecture().SetTriple(triple.c_str());
+      } else if (name.equals("name")) {
+        StringExtractor extractor(value);
+        // The process name from ASCII hex bytes since we can't
+        // control the characters in a process name
+        std::string name;
+        extractor.GetHexByteString(name);
+        process_info.GetExecutableFile().SetFile(name.c_str(), false);
+      } else if (name.equals("cputype")) {
+        value.getAsInteger(0, cpu);
+      } else if (name.equals("cpusubtype")) {
+        value.getAsInteger(0, sub);
+      } else if (name.equals("vendor")) {
+        vendor = value;
+      } else if (name.equals("ostype")) {
+        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)
-    {
-        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");
+    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()) {
+      llvm::StringRef name;
+      llvm::StringRef value;
+      uint32_t cpu = LLDB_INVALID_CPUTYPE;
+      uint32_t sub = 0;
+      std::string arch_name;
+      std::string os_name;
+      std::string vendor_name;
+      std::string triple;
+      uint32_t pointer_byte_size = 0;
+      StringExtractor extractor;
+      ByteOrder byte_order = eByteOrderInvalid;
+      uint32_t num_keys_decoded = 0;
+      lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+      while (response.GetNameColonValue(name, value)) {
+        if (name.equals("cputype")) {
+          if (!value.getAsInteger(16, cpu))
+            ++num_keys_decoded;
+        } else if (name.equals("cpusubtype")) {
+          if (!value.getAsInteger(16, sub))
+            ++num_keys_decoded;
+        } else if (name.equals("triple")) {
+          StringExtractor extractor(value);
+          extractor.GetHexByteString(triple);
+          ++num_keys_decoded;
+        } else if (name.equals("ostype")) {
+          os_name = value;
+          ++num_keys_decoded;
+        } else if (name.equals("vendor")) {
+          vendor_name = value;
+          ++num_keys_decoded;
+        } else if (name.equals("endian")) {
+          byte_order = llvm::StringSwitch<lldb::ByteOrder>(value)
+                           .Case("little", eByteOrderLittle)
+                           .Case("big", eByteOrderBig)
+                           .Case("pdp", eByteOrderPDP)
+                           .Default(eByteOrderInvalid);
+          if (byte_order != eByteOrderInvalid)
+            ++num_keys_decoded;
+        } else if (name.equals("ptrsize")) {
+          if (!value.getAsInteger(16, pointer_byte_size))
+            ++num_keys_decoded;
+        } else if (name.equals("pid")) {
+          if (!value.getAsInteger(16, pid))
+            ++num_keys_decoded;
+        }
+      }
+      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());
+        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
-    {
-        error.SetErrorString ("failed to send vFile:unlink packet");
+      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();
+      }
     }
-    return error;
+    if (json)
+      strm.Printf("\n    ]\n  }\n}\n");
+    else
+      strm.EOL();
+  }
 }
 
-// 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;
+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:*;");
+    }
+  }
+  // give the process a few seconds to startup
+  GDBRemoteCommunication::ScopedTimeout timeout(*this, 10);
+
+  if (SendPacketAndWaitForResponse(stream.GetString(), response, false) ==
+      PacketResult::Success) {
+    llvm::StringRef name;
+    llvm::StringRef value;
+    while (response.GetNameColonValue(name, value)) {
+      if (name.equals("port"))
+        value.getAsInteger(0, port);
+      else if (name.equals("pid"))
+        value.getAsInteger(0, pid);
+      else if (name.compare("socket_name") == 0) {
+        StringExtractor extractor(value);
+        extractor.GetHexByteString(socket_name);
+      }
     }
-    return false;
+    return true;
+  }
+  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;
+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::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;
-                    }
-                }
-            }
-        }
+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 m_avoid_g_packets == eLazyBoolYes;
+  }
+  return false;
 }
 
-DataBufferSP
-GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg)
-{
-    StreamString payload;
-    payload.Printf("p%x", reg);
-    StringExtractorGDBRemote response;
-    if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success ||
-        !response.IsNormalResponse())
-        return nullptr;
+bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
+  if (m_curr_tid_run == tid)
+    return true;
 
-    DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0));
-    response.GetHexBytes(buffer_sp->GetData(), '\xcc');
-    return buffer_sp;
+  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;
 }
 
-DataBufferSP
-GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid)
-{
-    StreamString payload;
-    payload.PutChar('g');
-    StringExtractorGDBRemote response;
-    if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success ||
-        !response.IsNormalResponse())
-        return nullptr;
+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);
 
-    DataBufferSP buffer_sp(new DataBufferHeap(response.GetStringRef().size() / 2, 0));
-    response.GetHexBytes(buffer_sp->GetData(), '\xcc');
-    return buffer_sp;
-}
+  // 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;
 
-bool
-GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid, uint32_t reg_num, llvm::ArrayRef<uint8_t> data)
-{
-    StreamString payload;
-    payload.Printf("P%x=", reg_num);
-    payload.PutBytesAsRawHex8(data.data(), data.size(), endian::InlHostByteOrder(), endian::InlHostByteOrder());
-    StringExtractorGDBRemote response;
-    return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) ==
-               PacketResult::Success &&
-           response.IsOKResponse();
+    // 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) {
+  thread_ids.clear();
+
+  Lock lock(*this, false);
+  if (lock) {
+    sequence_mutex_unavailable = false;
+    StringExtractorGDBRemote response;
+
+    PacketResult packet_result;
+    for (packet_result =
+             SendPacketAndWaitForResponseNoLock("qfThreadInfo", response);
+         packet_result == PacketResult::Success && response.IsNormalResponse();
+         packet_result =
+             SendPacketAndWaitForResponseNoLock("qsThreadInfo", response)) {
+      char ch = response.GetChar();
+      if (ch == 'l')
+        break;
+      if (ch == 'm') {
+        do {
+          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();
 }
 
-bool
-GDBRemoteCommunicationClient::WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data)
-{
-    StreamString payload;
-    payload.PutChar('G');
-    payload.PutBytesAsRawHex8(data.data(), data.size(), endian::InlHostByteOrder(), endian::InlHostByteOrder());
-    StringExtractorGDBRemote response;
-    return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) ==
-               PacketResult::Success &&
-           response.IsOKResponse();
+lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
+          PacketResult::Success ||
+      !response.IsNormalResponse())
+    return LLDB_INVALID_ADDRESS;
+  return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
 }
 
-bool
-GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save_id)
-{
-    save_id = 0; // Set to invalid save ID
-    if (m_supports_QSaveRegisterState == eLazyBoolNo)
-        return false;
-    
-    m_supports_QSaveRegisterState = eLazyBoolYes;
-    StreamString payload;
-    payload.PutCString("QSaveRegisterState");
-    StringExtractorGDBRemote response;
-    if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success)
-        return false;
-
-    if (response.IsUnsupportedResponse())
-        m_supports_QSaveRegisterState = eLazyBoolNo;
+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;
+}
 
-    const uint32_t response_save_id = response.GetU32(0);
-    if (response_save_id == 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;
+}
 
-    save_id = response_save_id;
+// 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::RestoreRegisterState (lldb::tid_t tid, uint32_t save_id)
-{
-    // We use the "m_supports_QSaveRegisterState" variable here because the
-    // QSaveRegisterState and QRestoreRegisterState packets must both be supported in
-    // order to be useful
-    if (m_supports_QSaveRegisterState == eLazyBoolNo)
-        return false;
-
-    StreamString payload;
-    payload.Printf("QRestoreRegisterState:%u", save_id);
-    StringExtractorGDBRemote response;
-    if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success)
-        return false;
+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;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid,
+                                                        uint32_t reg) {
+  StreamString payload;
+  payload.Printf("p%x", reg);
+  StringExtractorGDBRemote response;
+  if (SendThreadSpecificPacketAndWaitForResponse(
+          tid, std::move(payload), response, false) != PacketResult::Success ||
+      !response.IsNormalResponse())
+    return nullptr;
+
+  DataBufferSP buffer_sp(
+      new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+  response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+  return buffer_sp;
+}
+
+DataBufferSP GDBRemoteCommunicationClient::ReadAllRegisters(lldb::tid_t tid) {
+  StreamString payload;
+  payload.PutChar('g');
+  StringExtractorGDBRemote response;
+  if (SendThreadSpecificPacketAndWaitForResponse(
+          tid, std::move(payload), response, false) != PacketResult::Success ||
+      !response.IsNormalResponse())
+    return nullptr;
+
+  DataBufferSP buffer_sp(
+      new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+  response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+  return buffer_sp;
+}
+
+bool GDBRemoteCommunicationClient::WriteRegister(lldb::tid_t tid,
+                                                 uint32_t reg_num,
+                                                 llvm::ArrayRef<uint8_t> data) {
+  StreamString payload;
+  payload.Printf("P%x=", reg_num);
+  payload.PutBytesAsRawHex8(data.data(), data.size(),
+                            endian::InlHostByteOrder(),
+                            endian::InlHostByteOrder());
+  StringExtractorGDBRemote response;
+  return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+                                                    response, false) ==
+             PacketResult::Success &&
+         response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::WriteAllRegisters(
+    lldb::tid_t tid, llvm::ArrayRef<uint8_t> data) {
+  StreamString payload;
+  payload.PutChar('G');
+  payload.PutBytesAsRawHex8(data.data(), data.size(),
+                            endian::InlHostByteOrder(),
+                            endian::InlHostByteOrder());
+  StringExtractorGDBRemote response;
+  return SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload),
+                                                    response, false) ==
+             PacketResult::Success &&
+         response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::SaveRegisterState(lldb::tid_t tid,
+                                                     uint32_t &save_id) {
+  save_id = 0; // Set to invalid save ID
+  if (m_supports_QSaveRegisterState == eLazyBoolNo)
+    return false;
+
+  m_supports_QSaveRegisterState = eLazyBoolYes;
+  StreamString payload;
+  payload.PutCString("QSaveRegisterState");
+  StringExtractorGDBRemote response;
+  if (SendThreadSpecificPacketAndWaitForResponse(
+          tid, std::move(payload), response, false) != PacketResult::Success)
+    return false;
+
+  if (response.IsUnsupportedResponse())
+    m_supports_QSaveRegisterState = eLazyBoolNo;
+
+  const uint32_t response_save_id = response.GetU32(0);
+  if (response_save_id == 0)
+    return false;
+
+  save_id = response_save_id;
+  return true;
+}
+
+bool GDBRemoteCommunicationClient::RestoreRegisterState(lldb::tid_t tid,
+                                                        uint32_t save_id) {
+  // We use the "m_supports_QSaveRegisterState" variable here because the
+  // QSaveRegisterState and QRestoreRegisterState packets must both be supported
+  // in
+  // order to be useful
+  if (m_supports_QSaveRegisterState == eLazyBoolNo)
+    return false;
+
+  StreamString payload;
+  payload.Printf("QRestoreRegisterState:%u", save_id);
+  StringExtractorGDBRemote response;
+  if (SendThreadSpecificPacketAndWaitForResponse(
+          tid, std::move(payload), response, false) != PacketResult::Success)
+    return false;
 
-    if (response.IsOKResponse())
-        return true;
+  if (response.IsOKResponse())
+    return true;
 
-    if (response.IsUnsupportedResponse())
-        m_supports_QSaveRegisterState = eLazyBoolNo;
-    return false;
+  if (response.IsUnsupportedResponse())
+    m_supports_QSaveRegisterState = eLazyBoolNo;
+  return false;
 }
 
-bool
-GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid)
-{
-    if (!GetSyncThreadStateSupported())
-        return false;
+bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
+  if (!GetSyncThreadStateSupported())
+    return false;
 
-    StreamString packet;
-    StringExtractorGDBRemote response;
-    packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
-    return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
-               GDBRemoteCommunication::PacketResult::Success &&
-           response.IsOKResponse();
+  StreamString packet;
+  StringExtractorGDBRemote response;
+  packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
+  return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+             GDBRemoteCommunication::PacketResult::Success &&
+         response.IsOKResponse();
 }
 
-bool
-GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
-                                            ModuleSpec &module_spec)
-{
-    if (!m_supports_qModuleInfo)
-        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;
+  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());
+  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;
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response,
+                                   false) != PacketResult::Success)
+    return false;
 
-    if (response.IsErrorResponse ())
-        return false;
+  if (response.IsErrorResponse())
+    return false;
 
-    if (response.IsUnsupportedResponse ())
-    {
-        m_supports_qModuleInfo = false;
-        return false;
-    }
+  if (response.IsUnsupportedResponse()) {
+    m_supports_qModuleInfo = false;
+    return false;
+  }
 
-    llvm::StringRef name;
-    llvm::StringRef value;
+  llvm::StringRef name;
+  llvm::StringRef value;
 
-    module_spec.Clear ();
-    module_spec.GetFileSpec () = module_file_spec;
+  module_spec.Clear();
+  module_spec.GetFileSpec() = module_file_spec;
 
-    while (response.GetNameColonValue (name, value))
-    {
-        if (name == "uuid" || name == "md5")
-        {
-            StringExtractor extractor(value);
-            std::string uuid;
-            extractor.GetHexByteString(uuid);
-            module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
-        }
-        else if (name == "triple")
-        {
-            StringExtractor extractor(value);
-            std::string triple;
-            extractor.GetHexByteString(triple);
-            module_spec.GetArchitecture().SetTriple(triple.c_str());
-        }
-        else if (name == "file_offset")
-        {
-            uint64_t ival = 0;
-            if (!value.getAsInteger(16, ival))
-                module_spec.SetObjectOffset (ival);
-        }
-        else if (name == "file_size")
-        {
-            uint64_t ival = 0;
-            if (!value.getAsInteger(16, ival))
-                module_spec.SetObjectSize (ival);
-        }
-        else if (name == "file_path")
-        {
-            StringExtractor extractor(value);
-            std::string path;
-            extractor.GetHexByteString(path);
-            module_spec.GetFileSpec() = FileSpec(path.c_str(), false, arch_spec);
-        }
+  while (response.GetNameColonValue(name, value)) {
+    if (name == "uuid" || name == "md5") {
+      StringExtractor extractor(value);
+      std::string uuid;
+      extractor.GetHexByteString(uuid);
+      module_spec.GetUUID().SetFromCString(uuid.c_str(), uuid.size() / 2);
+    } else if (name == "triple") {
+      StringExtractor extractor(value);
+      std::string triple;
+      extractor.GetHexByteString(triple);
+      module_spec.GetArchitecture().SetTriple(triple.c_str());
+    } else if (name == "file_offset") {
+      uint64_t ival = 0;
+      if (!value.getAsInteger(16, ival))
+        module_spec.SetObjectOffset(ival);
+    } else if (name == "file_size") {
+      uint64_t ival = 0;
+      if (!value.getAsInteger(16, ival))
+        module_spec.SetObjectSize(ival);
+    } else if (name == "file_path") {
+      StringExtractor extractor(value);
+      std::string path;
+      extractor.GetHexByteString(path);
+      module_spec.GetFileSpec() = FileSpec(path.c_str(), false, arch_spec);
     }
+  }
 
-    return true;
+  return true;
 }
 
 // query the target remote for extended information using the qXfer packet
@@ -3667,368 +3237,342 @@ GDBRemoteCommunicationClient::GetModuleI
 // 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;
+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
+//  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
+//     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
+//     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
+//     Remote gdb stub asks for address of 'dispatch_queue_offsets'.  lldb says
+//     that it
+//     is at address 0x2bc97554.  Remote gdb stub sends 'OK' indicating that it
+//     does not
 //     need any more symbols.  lldb does not need to ask again in this session.
 
-void
-GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
-{
-    // Set to true once we've resolved a symbol to an address for the remote stub.
-    // If we get an 'OK' response after this, the remote stub doesn't need any more
-    // symbols and we can stop asking.
-    bool symbol_response_provided = false;
-
-    // Is this the initial qSymbol:: packet?
-    bool first_qsymbol_query = true;
-
-    if (m_supports_qSymbol && m_qSymbol_requests_done == false)
-    {
-        Lock lock(*this, false);
-        if (lock)
-        {
-            StreamString packet;
-            packet.PutCString ("qSymbol::");
-            StringExtractorGDBRemote response;
-            while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) == PacketResult::Success)
-            {
-                if (response.IsOKResponse())
-                {
-                    if (symbol_response_provided || first_qsymbol_query)
-                    {
-                        m_qSymbol_requests_done = true;
-                    }
+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;
 
-                    // We are done serving symbols requests
-                    return;
-                }
-                first_qsymbol_query = false;
+  // Is this the initial qSymbol:: packet?
+  bool first_qsymbol_query = true;
 
-                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 (m_supports_qSymbol && m_qSymbol_requests_done == false) {
+    Lock lock(*this, false);
+    if (lock) {
+      StreamString packet;
+      packet.PutCString("qSymbol::");
+      StringExtractorGDBRemote response;
+      while (SendPacketAndWaitForResponseNoLock(packet.GetString(), response) ==
+             PacketResult::Success) {
+        if (response.IsOKResponse()) {
+          if (symbol_response_provided || first_qsymbol_query) {
+            m_qSymbol_requests_done = true;
+          }
+
+          // We are done serving symbols requests
+          return;
+        }
+        first_qsymbol_query = false;
+
+        if (response.IsUnsupportedResponse()) {
+          // qSymbol is not supported by the current GDB server we are connected
+          // to
+          m_supports_qSymbol = false;
+          return;
+        } else {
+          llvm::StringRef response_str(response.GetStringRef());
+          if (response_str.startswith("qSymbol:")) {
+            response.SetFilePos(strlen("qSymbol:"));
+            std::string symbol_name;
+            if (response.GetHexByteString(symbol_name)) {
+              if (symbol_name.empty())
+                return;
+
+              addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
+              lldb_private::SymbolContextList sc_list;
+              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;
+                      }
                     }
+                  }
                 }
-            }
-            // If we make it here, the symbol request packet response wasn't valid or
-            // our symbol lookup failed so we must abort
-            return;
+              }
+              // This is the normal path where our symbol lookup was successful
+              // and we want
+              // to send a packet with the new symbol value and see if another
+              // lookup needs to be
+              // done.
+
+              // Change "packet" to contain the requested symbol value and name
+              packet.Clear();
+              packet.PutCString("qSymbol:");
+              if (symbol_load_addr != LLDB_INVALID_ADDRESS) {
+                packet.Printf("%" PRIx64, symbol_load_addr);
+                symbol_response_provided = true;
+              } else {
+                symbol_response_provided = false;
+              }
+              packet.PutCString(":");
+              packet.PutBytesAsRawHex8(symbol_name.data(), symbol_name.size());
+              continue; // go back to the while loop and send "packet" and wait
+                        // for another response
+            }
+          }
+        }
+      }
+      // If we make it here, the symbol request packet response wasn't valid or
+      // our symbol lookup failed so we must abort
+      return;
+
+    } else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(
+                   GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)) {
+      log->Printf(
+          "GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.",
+          __FUNCTION__);
+    }
+  }
+}
+
+StructuredData::Array *
+GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() {
+  if (!m_supported_async_json_packets_is_valid) {
+    // Query the server for the array of supported asynchronous JSON
+    // packets.
+    m_supported_async_json_packets_is_valid = true;
 
-        }
-        else if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | GDBR_LOG_PACKETS))
-        {
-            log->Printf("GDBRemoteCommunicationClient::%s: Didn't get sequence mutex.", __FUNCTION__);
-        }
-    }
-}
-
-StructuredData::Array*
-GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins()
-{
-    if (!m_supported_async_json_packets_is_valid)
-    {
-        // Query the server for the array of supported asynchronous JSON
-        // packets.
-        m_supported_async_json_packets_is_valid = true;
-
-        Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
-            GDBR_LOG_PROCESS));
-
-        // Poll it now.
-        StringExtractorGDBRemote response;
-        const bool send_async = false;
-        if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
-                                         send_async) == PacketResult::Success)
-        {
-            m_supported_async_json_packets_sp = StructuredData::ParseJSON(
-                response.GetStringRef());
-            if (m_supported_async_json_packets_sp &&
-                !m_supported_async_json_packets_sp->GetAsArray())
-            {
-                // We were returned something other than a JSON array.  This
-                // is invalid.  Clear it out.
-                if (log)
-                    log->Printf("GDBRemoteCommunicationClient::%s(): "
-                                "QSupportedAsyncJSONPackets returned invalid "
-                                "result: %s", __FUNCTION__,
-                                response.GetStringRef().c_str());
-                m_supported_async_json_packets_sp.reset();
-            }
-        }
-        else
-        {
-            if (log)
-                log->Printf("GDBRemoteCommunicationClient::%s(): "
-                            "QSupportedAsyncJSONPackets unsupported",
-                            __FUNCTION__);
-        }
-
-        if (log && m_supported_async_json_packets_sp)
-        {
-            StreamString  stream;
-            m_supported_async_json_packets_sp->Dump(stream);
-            log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
-                        "JSON packets: %s", __FUNCTION__,
-                        stream.GetString().c_str());
-        }
-    }
-
-    return m_supported_async_json_packets_sp
-        ? m_supported_async_json_packets_sp->GetAsArray()
-        : nullptr;
-}
-
-Error
-GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
-    const ConstString &type_name,
-    const StructuredData::ObjectSP &config_sp)
-{
-    Error error;
+    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
 
-    if (type_name.GetLength() == 0)
-    {
-        error.SetErrorString("invalid type_name argument");
-        return error;
-    }
-
-    // Build command: Configure{type_name}: serialized config
-    // data.
-    StreamGDBRemote stream;
-    stream.PutCString("QConfigure");
-    stream.PutCString(type_name.AsCString());
-    stream.PutChar(':');
-    if (config_sp)
-    {
-        // Gather the plain-text version of the configuration data.
-        StreamString unescaped_stream;
-        config_sp->Dump(unescaped_stream);
-        unescaped_stream.Flush();
-
-        // Add it to the stream in escaped fashion.
-        stream.PutEscapedBytes(unescaped_stream.GetData(),
-                               unescaped_stream.GetSize());
-    }
-    stream.Flush();
-
-    // Send the packet.
-    const bool send_async = false;
+    // Poll it now.
     StringExtractorGDBRemote response;
-    auto result = SendPacketAndWaitForResponse(stream.GetString().c_str(),
-                                               response, send_async);
-    if (result == PacketResult::Success)
-    {
-        // We failed if the config result comes back other than OK.
-        if (strcmp(response.GetStringRef().c_str(), "OK") == 0)
-        {
-            // Okay!
-            error.Clear();
-        }
-        else
-        {
-            error.SetErrorStringWithFormat("configuring StructuredData feature "
-                                           "%s failed with error %s",
-                                           type_name.AsCString(),
-                                           response.GetStringRef().c_str());
-        }
-    }
-    else
-    {
-        // Can we get more data here on the failure?
-        error.SetErrorStringWithFormat("configuring StructuredData feature %s "
-                                       "failed when sending packet: "
-                                       "PacketResult=%d", type_name.AsCString(),
-                                       result);
-    }
+    const bool send_async = false;
+    if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
+                                     send_async) == PacketResult::Success) {
+      m_supported_async_json_packets_sp =
+          StructuredData::ParseJSON(response.GetStringRef());
+      if (m_supported_async_json_packets_sp &&
+          !m_supported_async_json_packets_sp->GetAsArray()) {
+        // We were returned something other than a JSON array.  This
+        // is invalid.  Clear it out.
+        if (log)
+          log->Printf("GDBRemoteCommunicationClient::%s(): "
+                      "QSupportedAsyncJSONPackets returned invalid "
+                      "result: %s",
+                      __FUNCTION__, response.GetStringRef().c_str());
+        m_supported_async_json_packets_sp.reset();
+      }
+    } else {
+      if (log)
+        log->Printf("GDBRemoteCommunicationClient::%s(): "
+                    "QSupportedAsyncJSONPackets unsupported",
+                    __FUNCTION__);
+    }
+
+    if (log && m_supported_async_json_packets_sp) {
+      StreamString stream;
+      m_supported_async_json_packets_sp->Dump(stream);
+      log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
+                  "JSON packets: %s",
+                  __FUNCTION__, stream.GetString().c_str());
+    }
+  }
+
+  return m_supported_async_json_packets_sp
+             ? m_supported_async_json_packets_sp->GetAsArray()
+             : nullptr;
+}
+
+Error GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
+    const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+  Error error;
+
+  if (type_name.GetLength() == 0) {
+    error.SetErrorString("invalid type_name argument");
     return error;
-}
+  }
 
-void
-GDBRemoteCommunicationClient::OnRunPacketSent(bool first)
-{
-    GDBRemoteClientBase::OnRunPacketSent(first);
-    m_curr_tid = LLDB_INVALID_THREAD_ID;
+  // Build command: Configure{type_name}: serialized config
+  // data.
+  StreamGDBRemote stream;
+  stream.PutCString("QConfigure");
+  stream.PutCString(type_name.AsCString());
+  stream.PutChar(':');
+  if (config_sp) {
+    // Gather the plain-text version of the configuration data.
+    StreamString unescaped_stream;
+    config_sp->Dump(unescaped_stream);
+    unescaped_stream.Flush();
+
+    // Add it to the stream in escaped fashion.
+    stream.PutEscapedBytes(unescaped_stream.GetData(),
+                           unescaped_stream.GetSize());
+  }
+  stream.Flush();
+
+  // Send the packet.
+  const bool send_async = false;
+  StringExtractorGDBRemote response;
+  auto result = SendPacketAndWaitForResponse(stream.GetString().c_str(),
+                                             response, send_async);
+  if (result == PacketResult::Success) {
+    // We failed if the config result comes back other than OK.
+    if (strcmp(response.GetStringRef().c_str(), "OK") == 0) {
+      // Okay!
+      error.Clear();
+    } else {
+      error.SetErrorStringWithFormat("configuring StructuredData feature "
+                                     "%s failed with error %s",
+                                     type_name.AsCString(),
+                                     response.GetStringRef().c_str());
+    }
+  } else {
+    // Can we get more data here on the failure?
+    error.SetErrorStringWithFormat("configuring StructuredData feature %s "
+                                   "failed when sending packet: "
+                                   "PacketResult=%d",
+                                   type_name.AsCString(), result);
+  }
+  return error;
+}
+
+void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) {
+  GDBRemoteClientBase::OnRunPacketSent(first);
+  m_curr_tid = LLDB_INVALID_THREAD_ID;
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Tue Sep  6 15:57:50 2016
@@ -29,667 +29,552 @@
 namespace lldb_private {
 namespace process_gdb_remote {
 
-class GDBRemoteCommunicationClient : public GDBRemoteClientBase
-{
+class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
 public:
-    GDBRemoteCommunicationClient();
+  GDBRemoteCommunicationClient();
 
-    ~GDBRemoteCommunicationClient() override;
+  ~GDBRemoteCommunicationClient() override;
 
-    //------------------------------------------------------------------
-    // After connecting, send the handshake to the server to make sure
-    // we are communicating with it.
-    //------------------------------------------------------------------
-    bool
-    HandshakeWithServer (Error *error_ptr);
-
-    // For packets which specify a range of output to be returned,
-    // return all of the output via a series of request packets of the form
-    // <prefix>0,<size>
-    // <prefix><size>,<size>
-    // <prefix><size>*2,<size>
-    // <prefix><size>*3,<size>
-    // ...
-    // until a "$l..." packet is received, indicating the end.
-    // (size is in hex; this format is used by a standard gdbserver to
-    // return the given portion of the output specified by <prefix>;
-    // for example, "qXfer:libraries-svr4:read::fff,1000" means
-    // "return a chunk of the xml description file for shared
-    // library load addresses, where the chunk starts at offset 0xfff
-    // and continues for 0x1000 bytes").
-    // Concatenate the resulting server response packets together and
-    // return in response_string.  If any packet fails, the return value
-    // indicates that failure and the returned string value is undefined.
-    PacketResult
-    SendPacketsAndConcatenateResponses (const char *send_payload_prefix,
-                                        std::string &response_string);
-
-    bool
-    GetThreadSuffixSupported();
-
-    // This packet is usually sent first and the boolean return value
-    // indicates if the packet was send and any response was received
-    // even in the response is UNIMPLEMENTED. If the packet failed to
-    // get a response, then false is returned. This quickly tells us
-    // if we were able to connect and communicate with the remote GDB
-    // server
-    bool
-    QueryNoAckModeSupported ();
-
-    void
-    GetListThreadsInStopReplySupported ();
-
-    lldb::pid_t
-    GetCurrentProcessID (bool allow_lazy = true);
-
-    bool
-    GetLaunchSuccess (std::string &error_str);
-
-    bool
-    LaunchGDBServer (const char *remote_accept_hostname,
-                     lldb::pid_t &pid,
-                     uint16_t &port,
-                     std::string &socket_name);
-
-    size_t
-    QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls);
-
-    bool
-    KillSpawnedProcess (lldb::pid_t pid);
-
-    //------------------------------------------------------------------
-    /// Sends a GDB remote protocol 'A' packet that delivers program
-    /// arguments to the remote server.
-    ///
-    /// @param[in] argv
-    ///     A NULL terminated array of const C strings to use as the
-    ///     arguments.
-    ///
-    /// @return
-    ///     Zero if the response was "OK", a positive value if the
-    ///     the response was "Exx" where xx are two hex digits, or
-    ///     -1 if the call is unsupported or any other unexpected
-    ///     response was received.
-    //------------------------------------------------------------------
-    int
-    SendArgumentsPacket (const ProcessLaunchInfo &launch_info);
-
-    //------------------------------------------------------------------
-    /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
-    /// environment that will get used when launching an application
-    /// in conjunction with the 'A' packet. This function can be called
-    /// multiple times in a row in order to pass on the desired
-    /// environment that the inferior should be launched with.
-    ///
-    /// @param[in] name_equal_value
-    ///     A NULL terminated C string that contains a single environment
-    ///     in the format "NAME=VALUE".
-    ///
-    /// @return
-    ///     Zero if the response was "OK", a positive value if the
-    ///     the response was "Exx" where xx are two hex digits, or
-    ///     -1 if the call is unsupported or any other unexpected
-    ///     response was received.
-    //------------------------------------------------------------------
-    int
-    SendEnvironmentPacket (char const *name_equal_value);
-
-    int
-    SendLaunchArchPacket (const char *arch);
-    
-    int
-    SendLaunchEventDataPacket(const char *data, bool *was_supported = nullptr);
-    
-    //------------------------------------------------------------------
-    /// Sends a "vAttach:PID" where PID is in hex. 
-    ///
-    /// @param[in] pid
-    ///     A process ID for the remote gdb server to attach to.
-    ///
-    /// @param[out] response
-    ///     The response received from the gdb server. If the return
-    ///     value is zero, \a response will contain a stop reply 
-    ///     packet.
-    ///
-    /// @return
-    ///     Zero if the attach was successful, or an error indicating
-    ///     an error code.
-    //------------------------------------------------------------------
-    int
-    SendAttach (lldb::pid_t pid, 
-                StringExtractorGDBRemote& response);
-
-    //------------------------------------------------------------------
-    /// Sends a GDB remote protocol 'I' packet that delivers stdin
-    /// data to the remote process.
-    ///
-    /// @param[in] data
-    ///     A pointer to stdin data.
-    ///
-    /// @param[in] data_len
-    ///     The number of bytes available at \a data.
-    ///
-    /// @return
-    ///     Zero if the attach was successful, or an error indicating
-    ///     an error code.
-    //------------------------------------------------------------------
-    int
-    SendStdinNotification(const char* data, size_t data_len);
-
-    //------------------------------------------------------------------
-    /// Sets the path to use for stdin/out/err for a process
-    /// that will be launched with the 'A' packet.
-    ///
-    /// @param[in] path
-    ///     The path to use for stdin/out/err
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetSTDIN(const FileSpec &file_spec);
-    int
-    SetSTDOUT(const FileSpec &file_spec);
-    int
-    SetSTDERR(const FileSpec &file_spec);
-
-    //------------------------------------------------------------------
-    /// Sets the disable ASLR flag to \a enable for a process that will 
-    /// be launched with the 'A' packet.
-    ///
-    /// @param[in] enable
-    ///     A boolean value indicating whether to disable ASLR or not.
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetDisableASLR (bool enable);
-    
-    //------------------------------------------------------------------
-    /// Sets the DetachOnError flag to \a enable for the process controlled by the stub.
-    ///
-    /// @param[in] enable
-    ///     A boolean value indicating whether to detach on error or not.
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetDetachOnError (bool enable);
-
-    //------------------------------------------------------------------
-    /// Sets the working directory to \a path for a process that will 
-    /// be launched with the 'A' packet for non platform based
-    /// connections. If this packet is sent to a GDB server that
-    /// implements the platform, it will change the current working
-    /// directory for the platform process.
-    ///
-    /// @param[in] working_dir
-    ///     The path to a directory to use when launching our process
-    ///
-    /// @return
-    ///     Zero if the for success, or an error code for failure.
-    //------------------------------------------------------------------
-    int
-    SetWorkingDir(const FileSpec &working_dir);
-
-    //------------------------------------------------------------------
-    /// Gets the current working directory of a remote platform GDB
-    /// server.
-    ///
-    /// @param[out] working_dir
-    ///     The current working directory on the remote platform.
-    ///
-    /// @return
-    ///     Boolean for success
-    //------------------------------------------------------------------
-    bool
-    GetWorkingDir(FileSpec &working_dir);
-
-    lldb::addr_t
-    AllocateMemory (size_t size, uint32_t permissions);
-
-    bool
-    DeallocateMemory (lldb::addr_t addr);
-
-    Error
-    Detach (bool keep_stopped);
-
-    Error
-    GetMemoryRegionInfo (lldb::addr_t addr, MemoryRegionInfo &range_info); 
-
-    Error
-    GetWatchpointSupportInfo (uint32_t &num); 
-
-    Error
-    GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch);
-    
-    Error
-    GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch);
-
-    const ArchSpec &
-    GetHostArchitecture ();
-    
-    uint32_t
-    GetHostDefaultPacketTimeout();
-
-    const ArchSpec &
-    GetProcessArchitecture ();
-
-    void
-    GetRemoteQSupported();
-
-    bool
-    GetVContSupported (char flavor);
-
-    bool
-    GetpPacketSupported (lldb::tid_t tid);
-
-    bool
-    GetxPacketSupported ();
-
-    bool
-    GetVAttachOrWaitSupported ();
-    
-    bool
-    GetSyncThreadStateSupported();
-    
-    void
-    ResetDiscoverableSettings (bool did_exec);
-
-    bool
-    GetHostInfo (bool force = false);
-
-    bool
-    GetDefaultThreadId (lldb::tid_t &tid);
-    
-    bool
-    GetOSVersion (uint32_t &major, 
-                  uint32_t &minor, 
-                  uint32_t &update);
-
-    bool
-    GetOSBuildString (std::string &s);
-    
-    bool
-    GetOSKernelDescription (std::string &s);
-
-    ArchSpec
-    GetSystemArchitecture ();
-
-    bool
-    GetHostname (std::string &s);
-
-    lldb::addr_t
-    GetShlibInfoAddr();
-
-    bool
-    GetSupportsThreadSuffix ();
-
-    bool
-    GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info);
-
-    uint32_t
-    FindProcesses (const ProcessInstanceInfoMatch &process_match_info,
-                   ProcessInstanceInfoList &process_infos);
-
-    bool
-    GetUserName (uint32_t uid, std::string &name);
-    
-    bool
-    GetGroupName (uint32_t gid, std::string &name);
-
-    bool
-    HasFullVContSupport ()
-    {
-        return GetVContSupported ('A');
+  //------------------------------------------------------------------
+  // After connecting, send the handshake to the server to make sure
+  // we are communicating with it.
+  //------------------------------------------------------------------
+  bool HandshakeWithServer(Error *error_ptr);
+
+  // For packets which specify a range of output to be returned,
+  // return all of the output via a series of request packets of the form
+  // <prefix>0,<size>
+  // <prefix><size>,<size>
+  // <prefix><size>*2,<size>
+  // <prefix><size>*3,<size>
+  // ...
+  // until a "$l..." packet is received, indicating the end.
+  // (size is in hex; this format is used by a standard gdbserver to
+  // return the given portion of the output specified by <prefix>;
+  // for example, "qXfer:libraries-svr4:read::fff,1000" means
+  // "return a chunk of the xml description file for shared
+  // library load addresses, where the chunk starts at offset 0xfff
+  // and continues for 0x1000 bytes").
+  // Concatenate the resulting server response packets together and
+  // return in response_string.  If any packet fails, the return value
+  // indicates that failure and the returned string value is undefined.
+  PacketResult
+  SendPacketsAndConcatenateResponses(const char *send_payload_prefix,
+                                     std::string &response_string);
+
+  bool GetThreadSuffixSupported();
+
+  // This packet is usually sent first and the boolean return value
+  // indicates if the packet was send and any response was received
+  // even in the response is UNIMPLEMENTED. If the packet failed to
+  // get a response, then false is returned. This quickly tells us
+  // if we were able to connect and communicate with the remote GDB
+  // server
+  bool QueryNoAckModeSupported();
+
+  void GetListThreadsInStopReplySupported();
+
+  lldb::pid_t GetCurrentProcessID(bool allow_lazy = true);
+
+  bool GetLaunchSuccess(std::string &error_str);
+
+  bool LaunchGDBServer(const char *remote_accept_hostname, lldb::pid_t &pid,
+                       uint16_t &port, std::string &socket_name);
+
+  size_t QueryGDBServer(
+      std::vector<std::pair<uint16_t, std::string>> &connection_urls);
+
+  bool KillSpawnedProcess(lldb::pid_t pid);
+
+  //------------------------------------------------------------------
+  /// Sends a GDB remote protocol 'A' packet that delivers program
+  /// arguments to the remote server.
+  ///
+  /// @param[in] argv
+  ///     A NULL terminated array of const C strings to use as the
+  ///     arguments.
+  ///
+  /// @return
+  ///     Zero if the response was "OK", a positive value if the
+  ///     the response was "Exx" where xx are two hex digits, or
+  ///     -1 if the call is unsupported or any other unexpected
+  ///     response was received.
+  //------------------------------------------------------------------
+  int SendArgumentsPacket(const ProcessLaunchInfo &launch_info);
+
+  //------------------------------------------------------------------
+  /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
+  /// environment that will get used when launching an application
+  /// in conjunction with the 'A' packet. This function can be called
+  /// multiple times in a row in order to pass on the desired
+  /// environment that the inferior should be launched with.
+  ///
+  /// @param[in] name_equal_value
+  ///     A NULL terminated C string that contains a single environment
+  ///     in the format "NAME=VALUE".
+  ///
+  /// @return
+  ///     Zero if the response was "OK", a positive value if the
+  ///     the response was "Exx" where xx are two hex digits, or
+  ///     -1 if the call is unsupported or any other unexpected
+  ///     response was received.
+  //------------------------------------------------------------------
+  int SendEnvironmentPacket(char const *name_equal_value);
+
+  int SendLaunchArchPacket(const char *arch);
+
+  int SendLaunchEventDataPacket(const char *data,
+                                bool *was_supported = nullptr);
+
+  //------------------------------------------------------------------
+  /// Sends a "vAttach:PID" where PID is in hex.
+  ///
+  /// @param[in] pid
+  ///     A process ID for the remote gdb server to attach to.
+  ///
+  /// @param[out] response
+  ///     The response received from the gdb server. If the return
+  ///     value is zero, \a response will contain a stop reply
+  ///     packet.
+  ///
+  /// @return
+  ///     Zero if the attach was successful, or an error indicating
+  ///     an error code.
+  //------------------------------------------------------------------
+  int SendAttach(lldb::pid_t pid, StringExtractorGDBRemote &response);
+
+  //------------------------------------------------------------------
+  /// Sends a GDB remote protocol 'I' packet that delivers stdin
+  /// data to the remote process.
+  ///
+  /// @param[in] data
+  ///     A pointer to stdin data.
+  ///
+  /// @param[in] data_len
+  ///     The number of bytes available at \a data.
+  ///
+  /// @return
+  ///     Zero if the attach was successful, or an error indicating
+  ///     an error code.
+  //------------------------------------------------------------------
+  int SendStdinNotification(const char *data, size_t data_len);
+
+  //------------------------------------------------------------------
+  /// Sets the path to use for stdin/out/err for a process
+  /// that will be launched with the 'A' packet.
+  ///
+  /// @param[in] path
+  ///     The path to use for stdin/out/err
+  ///
+  /// @return
+  ///     Zero if the for success, or an error code for failure.
+  //------------------------------------------------------------------
+  int SetSTDIN(const FileSpec &file_spec);
+  int SetSTDOUT(const FileSpec &file_spec);
+  int SetSTDERR(const FileSpec &file_spec);
+
+  //------------------------------------------------------------------
+  /// Sets the disable ASLR flag to \a enable for a process that will
+  /// be launched with the 'A' packet.
+  ///
+  /// @param[in] enable
+  ///     A boolean value indicating whether to disable ASLR or not.
+  ///
+  /// @return
+  ///     Zero if the for success, or an error code for failure.
+  //------------------------------------------------------------------
+  int SetDisableASLR(bool enable);
+
+  //------------------------------------------------------------------
+  /// Sets the DetachOnError flag to \a enable for the process controlled by the
+  /// stub.
+  ///
+  /// @param[in] enable
+  ///     A boolean value indicating whether to detach on error or not.
+  ///
+  /// @return
+  ///     Zero if the for success, or an error code for failure.
+  //------------------------------------------------------------------
+  int SetDetachOnError(bool enable);
+
+  //------------------------------------------------------------------
+  /// Sets the working directory to \a path for a process that will
+  /// be launched with the 'A' packet for non platform based
+  /// connections. If this packet is sent to a GDB server that
+  /// implements the platform, it will change the current working
+  /// directory for the platform process.
+  ///
+  /// @param[in] working_dir
+  ///     The path to a directory to use when launching our process
+  ///
+  /// @return
+  ///     Zero if the for success, or an error code for failure.
+  //------------------------------------------------------------------
+  int SetWorkingDir(const FileSpec &working_dir);
+
+  //------------------------------------------------------------------
+  /// Gets the current working directory of a remote platform GDB
+  /// server.
+  ///
+  /// @param[out] working_dir
+  ///     The current working directory on the remote platform.
+  ///
+  /// @return
+  ///     Boolean for success
+  //------------------------------------------------------------------
+  bool GetWorkingDir(FileSpec &working_dir);
+
+  lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);
+
+  bool DeallocateMemory(lldb::addr_t addr);
+
+  Error Detach(bool keep_stopped);
+
+  Error GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info);
+
+  Error GetWatchpointSupportInfo(uint32_t &num);
+
+  Error GetWatchpointSupportInfo(uint32_t &num, bool &after,
+                                 const ArchSpec &arch);
+
+  Error GetWatchpointsTriggerAfterInstruction(bool &after,
+                                              const ArchSpec &arch);
+
+  const ArchSpec &GetHostArchitecture();
+
+  uint32_t GetHostDefaultPacketTimeout();
+
+  const ArchSpec &GetProcessArchitecture();
+
+  void GetRemoteQSupported();
+
+  bool GetVContSupported(char flavor);
+
+  bool GetpPacketSupported(lldb::tid_t tid);
+
+  bool GetxPacketSupported();
+
+  bool GetVAttachOrWaitSupported();
+
+  bool GetSyncThreadStateSupported();
+
+  void ResetDiscoverableSettings(bool did_exec);
+
+  bool GetHostInfo(bool force = false);
+
+  bool GetDefaultThreadId(lldb::tid_t &tid);
+
+  bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
+
+  bool GetOSBuildString(std::string &s);
+
+  bool GetOSKernelDescription(std::string &s);
+
+  ArchSpec GetSystemArchitecture();
+
+  bool GetHostname(std::string &s);
+
+  lldb::addr_t GetShlibInfoAddr();
+
+  bool GetSupportsThreadSuffix();
+
+  bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info);
+
+  uint32_t FindProcesses(const ProcessInstanceInfoMatch &process_match_info,
+                         ProcessInstanceInfoList &process_infos);
+
+  bool GetUserName(uint32_t uid, std::string &name);
+
+  bool GetGroupName(uint32_t gid, std::string &name);
+
+  bool HasFullVContSupport() { return GetVContSupported('A'); }
+
+  bool HasAnyVContSupport() { return GetVContSupported('a'); }
+
+  bool GetStopReply(StringExtractorGDBRemote &response);
+
+  bool GetThreadStopInfo(lldb::tid_t tid, StringExtractorGDBRemote &response);
+
+  bool SupportsGDBStoppointPacket(GDBStoppointType type) {
+    switch (type) {
+    case eBreakpointSoftware:
+      return m_supports_z0;
+    case eBreakpointHardware:
+      return m_supports_z1;
+    case eWatchpointWrite:
+      return m_supports_z2;
+    case eWatchpointRead:
+      return m_supports_z3;
+    case eWatchpointReadWrite:
+      return m_supports_z4;
+    default:
+      return false;
     }
+  }
 
-    bool
-    HasAnyVContSupport ()
-    {
-        return GetVContSupported ('a');
-    }
-    
-    bool
-    GetStopReply (StringExtractorGDBRemote &response);
-
-    bool
-    GetThreadStopInfo (lldb::tid_t tid, 
-                       StringExtractorGDBRemote &response);
-
-    bool
-    SupportsGDBStoppointPacket (GDBStoppointType type)
-    {
-        switch (type)
-        {
-        case eBreakpointSoftware:   return m_supports_z0;
-        case eBreakpointHardware:   return m_supports_z1;
-        case eWatchpointWrite:      return m_supports_z2;
-        case eWatchpointRead:       return m_supports_z3;
-        case eWatchpointReadWrite:  return m_supports_z4;
-        default:                    return false;
-        }
-    }
+  uint8_t SendGDBStoppointTypePacket(
+      GDBStoppointType type, // Type of breakpoint or watchpoint
+      bool insert,           // Insert or remove?
+      lldb::addr_t addr,     // Address of breakpoint or watchpoint
+      uint32_t length);      // Byte Size of breakpoint or watchpoint
 
-    uint8_t
-    SendGDBStoppointTypePacket (GDBStoppointType type,   // Type of breakpoint or watchpoint
-                                bool insert,              // Insert or remove?
-                                lldb::addr_t addr,        // Address of breakpoint or watchpoint
-                                uint32_t length);         // Byte Size of breakpoint or watchpoint
-
-    bool
-    SetNonStopMode (const bool enable);
-
-    void
-    TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm);
-
-    // This packet is for testing the speed of the interface only. Both
-    // the client and server need to support it, but this allows us to
-    // measure the packet speed without any other work being done on the
-    // other end and avoids any of that work affecting the packet send
-    // and response times.
-    bool
-    SendSpeedTestPacket (uint32_t send_size, 
-                         uint32_t recv_size);
-    
-    bool
-    SetCurrentThread (uint64_t tid);
-    
-    bool
-    SetCurrentThreadForRun (uint64_t tid);
-
-    bool
-    GetQXferAuxvReadSupported ();
-
-    bool
-    GetQXferLibrariesReadSupported ();
-
-    bool
-    GetQXferLibrariesSVR4ReadSupported ();
-
-    uint64_t
-    GetRemoteMaxPacketSize();
-
-    bool
-    GetEchoSupported ();
-
-    bool
-    GetAugmentedLibrariesSVR4ReadSupported ();
-
-    bool
-    GetQXferFeaturesReadSupported ();
-
-    LazyBool
-    SupportsAllocDeallocMemory () // const
-    {
-        // Uncomment this to have lldb pretend the debug server doesn't respond to alloc/dealloc memory packets.
-        // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
-        return m_supports_alloc_dealloc_memory;
-    }
+  bool SetNonStopMode(const bool enable);
 
-    size_t
-    GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids,
-                         bool &sequence_mutex_unavailable);
-    
-    lldb::user_id_t
-    OpenFile (const FileSpec& file_spec, uint32_t flags, mode_t mode, Error &error);
-    
-    bool
-    CloseFile (lldb::user_id_t fd, Error &error);
-    
-    lldb::user_id_t
-    GetFileSize (const FileSpec& file_spec);
-    
-    Error
-    GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions);
-
-    Error
-    SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
-
-    uint64_t
-    ReadFile (lldb::user_id_t fd,
-              uint64_t offset,
-              void *dst,
-              uint64_t dst_len,
-              Error &error);
-    
-    uint64_t
-    WriteFile (lldb::user_id_t fd,
-               uint64_t offset,
-               const void* src,
-               uint64_t src_len,
-               Error &error);
-    
-    Error
-    CreateSymlink(const FileSpec &src,
-                  const FileSpec &dst);
-    
-    Error
-    Unlink(const FileSpec &file_spec);
-
-    Error
-    MakeDirectory(const FileSpec &file_spec, uint32_t mode);
-
-    bool
-    GetFileExists (const FileSpec& file_spec);
-    
-    Error
-    RunShellCommand(const char *command,           // Shouldn't be nullptr
-                    const FileSpec &working_dir,   // Pass empty FileSpec to use the current working directory
-                    int *status_ptr,               // Pass nullptr if you don't want the process exit status
-                    int *signo_ptr,                // Pass nullptr if you don't want the signal that caused the process to exit
-                    std::string *command_output,   // Pass nullptr if you don't want the command output
-                    uint32_t timeout_sec);         // Timeout in seconds to wait for shell program to finish
-
-    bool
-    CalculateMD5 (const FileSpec& file_spec, uint64_t &high, uint64_t &low);
-
-    lldb::DataBufferSP
-    ReadRegister(lldb::tid_t tid,
-                 uint32_t reg_num); // Must be the eRegisterKindProcessPlugin register number
-
-    lldb::DataBufferSP
-    ReadAllRegisters(lldb::tid_t tid);
-
-    bool
-    WriteRegister(lldb::tid_t tid, uint32_t reg_num, // eRegisterKindProcessPlugin register number
-                  llvm::ArrayRef<uint8_t> data);
-
-    bool
-    WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
-
-    bool
-    SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
-
-    bool
-    RestoreRegisterState (lldb::tid_t tid, uint32_t save_id);
-
-    bool
-    SyncThreadState(lldb::tid_t tid);
-
-    const char *
-    GetGDBServerProgramName();
-    
-    uint32_t
-    GetGDBServerProgramVersion();
-
-    bool
-    AvoidGPackets(ProcessGDBRemote *process);
-
-    StructuredData::ObjectSP
-    GetThreadsInfo();
-
-    bool
-    GetThreadExtendedInfoSupported();
-
-    bool
-    GetLoadedDynamicLibrariesInfosSupported();
-
-    bool
-    GetSharedCacheInfoSupported();
-
-    bool
-    GetModuleInfo (const FileSpec& module_file_spec,
-                   const ArchSpec& arch_spec,
-                   ModuleSpec &module_spec);
-
-    bool
-    ReadExtFeature (const lldb_private::ConstString object,
-                    const lldb_private::ConstString annex,
-                    std::string & out,
-                    lldb_private::Error & err);
-
-    void
-    ServeSymbolLookups(lldb_private::Process *process);
-
-    //------------------------------------------------------------------
-    /// Return the feature set supported by the gdb-remote server.
-    ///
-    /// This method returns the remote side's response to the qSupported
-    /// packet.  The response is the complete string payload returned
-    /// to the client.
-    ///
-    /// @return
-    ///     The string returned by the server to the qSupported query.
-    //------------------------------------------------------------------
-    const std::string&
-    GetServerSupportedFeatures() const
-    {
-        return m_qSupported_response;
-    }
+  void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send,
+                       uint32_t max_recv, bool json, Stream &strm);
+
+  // This packet is for testing the speed of the interface only. Both
+  // the client and server need to support it, but this allows us to
+  // measure the packet speed without any other work being done on the
+  // other end and avoids any of that work affecting the packet send
+  // and response times.
+  bool SendSpeedTestPacket(uint32_t send_size, uint32_t recv_size);
+
+  bool SetCurrentThread(uint64_t tid);
+
+  bool SetCurrentThreadForRun(uint64_t tid);
+
+  bool GetQXferAuxvReadSupported();
+
+  bool GetQXferLibrariesReadSupported();
+
+  bool GetQXferLibrariesSVR4ReadSupported();
+
+  uint64_t GetRemoteMaxPacketSize();
+
+  bool GetEchoSupported();
+
+  bool GetAugmentedLibrariesSVR4ReadSupported();
+
+  bool GetQXferFeaturesReadSupported();
+
+  LazyBool SupportsAllocDeallocMemory() // const
+  {
+    // Uncomment this to have lldb pretend the debug server doesn't respond to
+    // alloc/dealloc memory packets.
+    // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
+    return m_supports_alloc_dealloc_memory;
+  }
+
+  size_t GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids,
+                             bool &sequence_mutex_unavailable);
+
+  lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+                           mode_t mode, Error &error);
+
+  bool CloseFile(lldb::user_id_t fd, Error &error);
+
+  lldb::user_id_t GetFileSize(const FileSpec &file_spec);
+
+  Error GetFilePermissions(const FileSpec &file_spec,
+                           uint32_t &file_permissions);
+
+  Error SetFilePermissions(const FileSpec &file_spec,
+                           uint32_t file_permissions);
+
+  uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+                    uint64_t dst_len, Error &error);
+
+  uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
+                     uint64_t src_len, Error &error);
+
+  Error CreateSymlink(const FileSpec &src, const FileSpec &dst);
+
+  Error Unlink(const FileSpec &file_spec);
+
+  Error MakeDirectory(const FileSpec &file_spec, uint32_t mode);
+
+  bool GetFileExists(const FileSpec &file_spec);
+
+  Error RunShellCommand(
+      const char *command,         // Shouldn't be nullptr
+      const FileSpec &working_dir, // Pass empty FileSpec to use the current
+                                   // working directory
+      int *status_ptr, // Pass nullptr if you don't want the process exit status
+      int *signo_ptr,  // Pass nullptr if you don't want the signal that caused
+                       // the process to exit
+      std::string
+          *command_output, // Pass nullptr if you don't want the command output
+      uint32_t timeout_sec); // Timeout in seconds to wait for shell program to
+                             // finish
+
+  bool CalculateMD5(const FileSpec &file_spec, uint64_t &high, uint64_t &low);
+
+  lldb::DataBufferSP ReadRegister(
+      lldb::tid_t tid,
+      uint32_t
+          reg_num); // Must be the eRegisterKindProcessPlugin register number
+
+  lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid);
+
+  bool
+  WriteRegister(lldb::tid_t tid,
+                uint32_t reg_num, // eRegisterKindProcessPlugin register number
+                llvm::ArrayRef<uint8_t> data);
+
+  bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
+
+  bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
+
+  bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id);
+
+  bool SyncThreadState(lldb::tid_t tid);
+
+  const char *GetGDBServerProgramName();
+
+  uint32_t GetGDBServerProgramVersion();
+
+  bool AvoidGPackets(ProcessGDBRemote *process);
+
+  StructuredData::ObjectSP GetThreadsInfo();
+
+  bool GetThreadExtendedInfoSupported();
+
+  bool GetLoadedDynamicLibrariesInfosSupported();
+
+  bool GetSharedCacheInfoSupported();
+
+  bool GetModuleInfo(const FileSpec &module_file_spec,
+                     const ArchSpec &arch_spec, ModuleSpec &module_spec);
+
+  bool ReadExtFeature(const lldb_private::ConstString object,
+                      const lldb_private::ConstString annex, std::string &out,
+                      lldb_private::Error &err);
+
+  void ServeSymbolLookups(lldb_private::Process *process);
+
+  //------------------------------------------------------------------
+  /// Return the feature set supported by the gdb-remote server.
+  ///
+  /// This method returns the remote side's response to the qSupported
+  /// packet.  The response is the complete string payload returned
+  /// to the client.
+  ///
+  /// @return
+  ///     The string returned by the server to the qSupported query.
+  //------------------------------------------------------------------
+  const std::string &GetServerSupportedFeatures() const {
+    return m_qSupported_response;
+  }
+
+  //------------------------------------------------------------------
+  /// Return the array of async JSON packet types supported by the remote.
+  ///
+  /// This method returns the remote side's array of supported JSON
+  /// packet types as a list of type names.  Each of the results are
+  /// expected to have an Enable{type_name} command to enable and configure
+  /// the related feature.  Each type_name for an enabled feature will
+  /// possibly send async-style packets that contain a payload of a
+  /// binhex-encoded JSON dictionary.  The dictionary will have a
+  /// string field named 'type', that contains the type_name of the
+  /// supported packet type.
+  ///
+  /// There is a Plugin category called structured-data plugins.
+  /// A plugin indicates whether it knows how to handle a type_name.
+  /// If so, it can be used to process the async JSON packet.
+  ///
+  /// @return
+  ///     The string returned by the server to the qSupported query.
+  //------------------------------------------------------------------
+  lldb_private::StructuredData::Array *GetSupportedStructuredDataPlugins();
 
-    //------------------------------------------------------------------
-    /// Return the array of async JSON packet types supported by the remote.
-    ///
-    /// This method returns the remote side's array of supported JSON
-    /// packet types as a list of type names.  Each of the results are
-    /// expected to have an Enable{type_name} command to enable and configure
-    /// the related feature.  Each type_name for an enabled feature will
-    /// possibly send async-style packets that contain a payload of a
-    /// binhex-encoded JSON dictionary.  The dictionary will have a
-    /// string field named 'type', that contains the type_name of the
-    /// supported packet type.
-    ///
-    /// There is a Plugin category called structured-data plugins.
-    /// A plugin indicates whether it knows how to handle a type_name.
-    /// If so, it can be used to process the async JSON packet.
-    ///
-    /// @return
-    ///     The string returned by the server to the qSupported query.
-    //------------------------------------------------------------------
-    lldb_private::StructuredData::Array*
-    GetSupportedStructuredDataPlugins();
-
-    //------------------------------------------------------------------
-    /// Configure a StructuredData feature on the remote end.
-    ///
-    /// @see \b Process::ConfigureStructuredData(...) for details.
-    //------------------------------------------------------------------
-    Error
-    ConfigureRemoteStructuredData(const ConstString &type_name,
-                                  const StructuredData::ObjectSP &config_sp);
+  //------------------------------------------------------------------
+  /// Configure a StructuredData feature on the remote end.
+  ///
+  /// @see \b Process::ConfigureStructuredData(...) for details.
+  //------------------------------------------------------------------
+  Error
+  ConfigureRemoteStructuredData(const ConstString &type_name,
+                                const StructuredData::ObjectSP &config_sp);
 
 protected:
-    LazyBool m_supports_not_sending_acks;
-    LazyBool m_supports_thread_suffix;
-    LazyBool m_supports_threads_in_stop_reply;
-    LazyBool m_supports_vCont_all;
-    LazyBool m_supports_vCont_any;
-    LazyBool m_supports_vCont_c;
-    LazyBool m_supports_vCont_C;
-    LazyBool m_supports_vCont_s;
-    LazyBool m_supports_vCont_S;
-    LazyBool m_qHostInfo_is_valid;
-    LazyBool m_curr_pid_is_valid;
-    LazyBool m_qProcessInfo_is_valid;
-    LazyBool m_qGDBServerVersion_is_valid;
-    LazyBool m_supports_alloc_dealloc_memory;
-    LazyBool m_supports_memory_region_info;
-    LazyBool m_supports_watchpoint_support_info;
-    LazyBool m_supports_detach_stay_stopped;
-    LazyBool m_watchpoints_trigger_after_instruction;
-    LazyBool m_attach_or_wait_reply;
-    LazyBool m_prepare_for_reg_writing_reply;
-    LazyBool m_supports_p;
-    LazyBool m_supports_x;
-    LazyBool m_avoid_g_packets;
-    LazyBool m_supports_QSaveRegisterState;
-    LazyBool m_supports_qXfer_auxv_read;
-    LazyBool m_supports_qXfer_libraries_read;
-    LazyBool m_supports_qXfer_libraries_svr4_read;
-    LazyBool m_supports_qXfer_features_read;
-    LazyBool m_supports_augmented_libraries_svr4_read;
-    LazyBool m_supports_jThreadExtendedInfo;
-    LazyBool m_supports_jLoadedDynamicLibrariesInfos;
-    LazyBool m_supports_jGetSharedCacheInfo;
-
-    bool
-        m_supports_qProcessInfoPID:1,
-        m_supports_qfProcessInfo:1,
-        m_supports_qUserName:1,
-        m_supports_qGroupName:1,
-        m_supports_qThreadStopInfo:1,
-        m_supports_z0:1,
-        m_supports_z1:1,
-        m_supports_z2:1,
-        m_supports_z3:1,
-        m_supports_z4:1,
-        m_supports_QEnvironment:1,
-        m_supports_QEnvironmentHexEncoded:1,
-        m_supports_qSymbol:1,
-        m_qSymbol_requests_done:1,
-        m_supports_qModuleInfo:1,
-        m_supports_jThreadsInfo:1;
-    
-    lldb::pid_t m_curr_pid;
-    lldb::tid_t m_curr_tid;         // Current gdb remote protocol thread index for all other operations
-    lldb::tid_t m_curr_tid_run;     // Current gdb remote protocol thread index for continue, step, etc
-
-    uint32_t m_num_supported_hardware_watchpoints;
-
-    ArchSpec m_host_arch;
-    ArchSpec m_process_arch;
-    uint32_t m_os_version_major;
-    uint32_t m_os_version_minor;
-    uint32_t m_os_version_update;
-    std::string m_os_build;
-    std::string m_os_kernel;
-    std::string m_hostname;
-    std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if qGDBServerVersion is not supported
-    uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if qGDBServerVersion is not supported
-    uint32_t m_default_packet_timeout;
-    uint64_t m_max_packet_size;  // as returned by qSupported
-    std::string m_qSupported_response; // the complete response to qSupported
-
-    bool m_supported_async_json_packets_is_valid;
-    lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
-
-    bool
-    GetCurrentProcessInfo (bool allow_lazy_pid = true);
-
-    bool
-    GetGDBServerVersion();
-
-    // Given the list of compression types that the remote debug stub can support,
-    // possibly enable compression if we find an encoding we can handle.
-    void
-    MaybeEnableCompression (std::vector<std::string> supported_compressions);
-
-    bool
-    DecodeProcessInfoResponse (StringExtractorGDBRemote &response, 
-                               ProcessInstanceInfo &process_info);
-
-    void
-    OnRunPacketSent(bool first) override;
-
-    PacketResult
-    SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload,
-                                               StringExtractorGDBRemote &response, bool send_async);
+  LazyBool m_supports_not_sending_acks;
+  LazyBool m_supports_thread_suffix;
+  LazyBool m_supports_threads_in_stop_reply;
+  LazyBool m_supports_vCont_all;
+  LazyBool m_supports_vCont_any;
+  LazyBool m_supports_vCont_c;
+  LazyBool m_supports_vCont_C;
+  LazyBool m_supports_vCont_s;
+  LazyBool m_supports_vCont_S;
+  LazyBool m_qHostInfo_is_valid;
+  LazyBool m_curr_pid_is_valid;
+  LazyBool m_qProcessInfo_is_valid;
+  LazyBool m_qGDBServerVersion_is_valid;
+  LazyBool m_supports_alloc_dealloc_memory;
+  LazyBool m_supports_memory_region_info;
+  LazyBool m_supports_watchpoint_support_info;
+  LazyBool m_supports_detach_stay_stopped;
+  LazyBool m_watchpoints_trigger_after_instruction;
+  LazyBool m_attach_or_wait_reply;
+  LazyBool m_prepare_for_reg_writing_reply;
+  LazyBool m_supports_p;
+  LazyBool m_supports_x;
+  LazyBool m_avoid_g_packets;
+  LazyBool m_supports_QSaveRegisterState;
+  LazyBool m_supports_qXfer_auxv_read;
+  LazyBool m_supports_qXfer_libraries_read;
+  LazyBool m_supports_qXfer_libraries_svr4_read;
+  LazyBool m_supports_qXfer_features_read;
+  LazyBool m_supports_augmented_libraries_svr4_read;
+  LazyBool m_supports_jThreadExtendedInfo;
+  LazyBool m_supports_jLoadedDynamicLibrariesInfos;
+  LazyBool m_supports_jGetSharedCacheInfo;
+
+  bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
+      m_supports_qUserName : 1, m_supports_qGroupName : 1,
+      m_supports_qThreadStopInfo : 1, m_supports_z0 : 1, m_supports_z1 : 1,
+      m_supports_z2 : 1, m_supports_z3 : 1, m_supports_z4 : 1,
+      m_supports_QEnvironment : 1, m_supports_QEnvironmentHexEncoded : 1,
+      m_supports_qSymbol : 1, m_qSymbol_requests_done : 1,
+      m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1;
+
+  lldb::pid_t m_curr_pid;
+  lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all
+                          // other operations
+  lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for
+                              // continue, step, etc
+
+  uint32_t m_num_supported_hardware_watchpoints;
+
+  ArchSpec m_host_arch;
+  ArchSpec m_process_arch;
+  uint32_t m_os_version_major;
+  uint32_t m_os_version_minor;
+  uint32_t m_os_version_update;
+  std::string m_os_build;
+  std::string m_os_kernel;
+  std::string m_hostname;
+  std::string m_gdb_server_name; // from reply to qGDBServerVersion, empty if
+                                 // qGDBServerVersion is not supported
+  uint32_t m_gdb_server_version; // from reply to qGDBServerVersion, zero if
+                                 // qGDBServerVersion is not supported
+  uint32_t m_default_packet_timeout;
+  uint64_t m_max_packet_size;        // as returned by qSupported
+  std::string m_qSupported_response; // the complete response to qSupported
+
+  bool m_supported_async_json_packets_is_valid;
+  lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
+
+  bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
+
+  bool GetGDBServerVersion();
+
+  // Given the list of compression types that the remote debug stub can support,
+  // possibly enable compression if we find an encoding we can handle.
+  void MaybeEnableCompression(std::vector<std::string> supported_compressions);
+
+  bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
+                                 ProcessInstanceInfo &process_info);
+
+  void OnRunPacketSent(bool first) override;
+
+  PacketResult SendThreadSpecificPacketAndWaitForResponse(
+      lldb::tid_t tid, StreamString &&payload,
+      StringExtractorGDBRemote &response, bool send_async);
 
 private:
-    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationClient);
+  DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
 };
 
 } // namespace process_gdb_remote

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Tue Sep  6 15:57:50 2016
@@ -25,114 +25,99 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::process_gdb_remote;
 
-GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(const char *comm_name,
-                                                           const char *listener_name) :
-    GDBRemoteCommunication (comm_name, listener_name),
-    m_exit_now (false)
-{
-}
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
+    const char *comm_name, const char *listener_name)
+    : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {}
 
-GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
-{
-}
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
 
 void GDBRemoteCommunicationServer::RegisterPacketHandler(
-        StringExtractorGDBRemote::ServerPacketType packet_type,
-        PacketHandler handler)
-{
-    m_packet_handlers[packet_type] = std::move(handler);
+    StringExtractorGDBRemote::ServerPacketType packet_type,
+    PacketHandler handler) {
+  m_packet_handlers[packet_type] = std::move(handler);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
-                                                        Error &error,
-                                                        bool &interrupt,
-                                                        bool &quit)
-{
-    StringExtractorGDBRemote packet;
-
-    PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec, false);
-    if (packet_result == PacketResult::Success)
-    {
-        const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
-        switch (packet_type)
-        {
-        case StringExtractorGDBRemote::eServerPacketType_nack:
-        case StringExtractorGDBRemote::eServerPacketType_ack:
-            break;
-
-        case StringExtractorGDBRemote::eServerPacketType_invalid:
-            error.SetErrorString("invalid packet");
-            quit = true;
-            break;
-
-        case StringExtractorGDBRemote::eServerPacketType_unimplemented:
-            packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
-            break;
-
-        default:
-            auto handler_it = m_packet_handlers.find(packet_type);
-            if (handler_it == m_packet_handlers.end())
-                packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
-            else
-                packet_result = handler_it->second (packet, error, interrupt, quit);
-            break;
-        }
+GDBRemoteCommunicationServer::GetPacketAndSendResponse(uint32_t timeout_usec,
+                                                       Error &error,
+                                                       bool &interrupt,
+                                                       bool &quit) {
+  StringExtractorGDBRemote packet;
+
+  PacketResult packet_result =
+      WaitForPacketWithTimeoutMicroSecondsNoLock(packet, timeout_usec, false);
+  if (packet_result == PacketResult::Success) {
+    const StringExtractorGDBRemote::ServerPacketType packet_type =
+        packet.GetServerPacketType();
+    switch (packet_type) {
+    case StringExtractorGDBRemote::eServerPacketType_nack:
+    case StringExtractorGDBRemote::eServerPacketType_ack:
+      break;
+
+    case StringExtractorGDBRemote::eServerPacketType_invalid:
+      error.SetErrorString("invalid packet");
+      quit = true;
+      break;
+
+    case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+      packet_result = SendUnimplementedResponse(packet.GetStringRef().c_str());
+      break;
+
+    default:
+      auto handler_it = m_packet_handlers.find(packet_type);
+      if (handler_it == m_packet_handlers.end())
+        packet_result =
+            SendUnimplementedResponse(packet.GetStringRef().c_str());
+      else
+        packet_result = handler_it->second(packet, error, interrupt, quit);
+      break;
     }
-    else
-    {
-        if (!IsConnected())
-        {
-            error.SetErrorString("lost connection");
-            quit = true;
-        }
-        else
-        {
-            error.SetErrorString("timeout");
-        }
+  } else {
+    if (!IsConnected()) {
+      error.SetErrorString("lost connection");
+      quit = true;
+    } else {
+      error.SetErrorString("timeout");
     }
+  }
 
-    // Check if anything occurred that would force us to want to exit.
-    if (m_exit_now)
-        quit = true;
+  // Check if anything occurred that would force us to want to exit.
+  if (m_exit_now)
+    quit = true;
 
-    return packet_result;
+  return packet_result;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
-{
-    // TODO: Log the packet we aren't handling...
-    return SendPacketNoLock ("");
+GDBRemoteCommunicationServer::SendUnimplementedResponse(const char *) {
+  // TODO: Log the packet we aren't handling...
+  return SendPacketNoLock("");
 }
 
-
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
-{
-    char packet[16];
-    int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err);
-    assert (packet_len < (int)sizeof(packet));
-    return SendPacketNoLock (llvm::StringRef(packet, packet_len));
+GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
+  char packet[16];
+  int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
+  assert(packet_len < (int)sizeof(packet));
+  return SendPacketNoLock(llvm::StringRef(packet, packet_len));
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendIllFormedResponse (const StringExtractorGDBRemote &failed_packet, const char *message)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)", __FUNCTION__, failed_packet.GetStringRef ().c_str (), message ? message : "");
-    return SendErrorResponse (0x03);
+GDBRemoteCommunicationServer::SendIllFormedResponse(
+    const StringExtractorGDBRemote &failed_packet, const char *message) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
+                __FUNCTION__, failed_packet.GetStringRef().c_str(),
+                message ? message : "");
+  return SendErrorResponse(0x03);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServer::SendOKResponse ()
-{
-    return SendPacketNoLock ("OK");
+GDBRemoteCommunicationServer::SendOKResponse() {
+  return SendPacketNoLock("OK");
 }
 
-bool
-GDBRemoteCommunicationServer::HandshakeWithClient()
-{
-    return GetAck() == PacketResult::Success;
+bool GDBRemoteCommunicationServer::HandshakeWithClient() {
+  return GetAck() == PacketResult::Success;
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Tue Sep  6 15:57:50 2016
@@ -17,8 +17,8 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-private-forward.h"
 #include "GDBRemoteCommunication.h"
+#include "lldb/lldb-private-forward.h"
 
 class StringExtractorGDBRemote;
 
@@ -27,52 +27,46 @@ namespace process_gdb_remote {
 
 class ProcessGDBRemote;
 
-class GDBRemoteCommunicationServer : public GDBRemoteCommunication
-{
+class GDBRemoteCommunicationServer : public GDBRemoteCommunication {
 public:
-    using PortMap = std::map<uint16_t, lldb::pid_t>;
-    using PacketHandler = std::function<PacketResult(StringExtractorGDBRemote &packet,
-                                                     Error &error,
-                                                     bool &interrupt,
-                                                     bool &quit)>;
-
-    GDBRemoteCommunicationServer(const char *comm_name,
-                                 const char *listener_name);
-
-    ~GDBRemoteCommunicationServer() override;
-
-    void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
-                               PacketHandler handler);
-
-    PacketResult
-    GetPacketAndSendResponse (uint32_t timeout_usec,
-                              Error &error,
-                              bool &interrupt, 
-                              bool &quit);
-
-    // After connecting, do a little handshake with the client to make sure
-    // we are at least communicating
-    bool
-    HandshakeWithClient ();
+  using PortMap = std::map<uint16_t, lldb::pid_t>;
+  using PacketHandler =
+      std::function<PacketResult(StringExtractorGDBRemote &packet, Error &error,
+                                 bool &interrupt, bool &quit)>;
+
+  GDBRemoteCommunicationServer(const char *comm_name,
+                               const char *listener_name);
+
+  ~GDBRemoteCommunicationServer() override;
+
+  void
+  RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
+                        PacketHandler handler);
+
+  PacketResult GetPacketAndSendResponse(uint32_t timeout_usec, Error &error,
+                                        bool &interrupt, bool &quit);
+
+  // After connecting, do a little handshake with the client to make sure
+  // we are at least communicating
+  bool HandshakeWithClient();
 
 protected:
-    std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers;
-    bool m_exit_now; // use in asynchronous handling to indicate process should exit.
+  std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler>
+      m_packet_handlers;
+  bool m_exit_now; // use in asynchronous handling to indicate process should
+                   // exit.
 
-    PacketResult
-    SendUnimplementedResponse (const char *packet);
+  PacketResult SendUnimplementedResponse(const char *packet);
 
-    PacketResult
-    SendErrorResponse (uint8_t error);
+  PacketResult SendErrorResponse(uint8_t error);
 
-    PacketResult
-    SendIllFormedResponse (const StringExtractorGDBRemote &packet, const char *error_message);
+  PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet,
+                                     const char *error_message);
 
-    PacketResult
-    SendOKResponse ();
+  PacketResult SendOKResponse();
 
 private:
-    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer);
+  DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServer);
 };
 
 } // namespace process_gdb_remote

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp Tue Sep  6 15:57:50 2016
@@ -18,11 +18,10 @@
 #endif
 
 // C++ Includes
-#include <cstring>
 #include <chrono>
+#include <cstring>
 
 // Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/StreamGDBRemote.h"
@@ -39,6 +38,7 @@
 #include "lldb/Target/FileAction.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
+#include "llvm/ADT/Triple.h"
 
 // Project includes
 #include "ProcessGDBRemoteLog.h"
@@ -55,1232 +55,1178 @@ using namespace lldb_private;
 using namespace lldb_private::process_gdb_remote;
 
 #ifdef __ANDROID__
-    const static uint32_t g_default_packet_timeout_sec = 20; // seconds
+const static uint32_t g_default_packet_timeout_sec = 20; // seconds
 #else
-    const static uint32_t g_default_packet_timeout_sec = 0; // not specified
+const static uint32_t g_default_packet_timeout_sec = 0; // not specified
 #endif
 
 //----------------------------------------------------------------------
 // GDBRemoteCommunicationServerCommon constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name) :
-    GDBRemoteCommunicationServer (comm_name, listener_name),
-    m_process_launch_info (),
-    m_process_launch_error (),
-    m_proc_infos (),
-    m_proc_infos_index (0),
-    m_thread_suffix_supported (false),
-    m_list_threads_in_stop_reply (false)
-{
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
-                                  &GDBRemoteCommunicationServerCommon::Handle_A);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironment,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGroupName,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qHostInfo,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qEcho,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qEcho);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSupported,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qSupported);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
-                                  &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qUserName,
-                                  &GDBRemoteCommunicationServerCommon::Handle_qUserName);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_close,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_exists,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_md5,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_mode,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_open,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pread,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_size,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_stat,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
-                                  &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
+GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(
+    const char *comm_name, const char *listener_name)
+    : GDBRemoteCommunicationServer(comm_name, listener_name),
+      m_process_launch_info(), m_process_launch_error(), m_proc_infos(),
+      m_proc_infos_index(0), m_thread_suffix_supported(false),
+      m_list_threads_in_stop_reply(false) {
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A,
+                                &GDBRemoteCommunicationServerCommon::Handle_A);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QEnvironment,
+      &GDBRemoteCommunicationServerCommon::Handle_QEnvironment);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded,
+      &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qfProcessInfo,
+      &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qGroupName,
+      &GDBRemoteCommunicationServerCommon::Handle_qGroupName);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qHostInfo,
+      &GDBRemoteCommunicationServerCommon::Handle_qHostInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QLaunchArch,
+      &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess,
+      &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply,
+      &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qEcho,
+      &GDBRemoteCommunicationServerCommon::Handle_qEcho);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qModuleInfo,
+      &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod,
+      &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir,
+      &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qPlatform_shell,
+      &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID,
+      &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError,
+      &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetSTDERR,
+      &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetSTDIN,
+      &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT,
+      &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qSpeedTest,
+      &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qsProcessInfo,
+      &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode,
+      &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qSupported,
+      &GDBRemoteCommunicationServerCommon::Handle_qSupported);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported,
+      &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qUserName,
+      &GDBRemoteCommunicationServerCommon::Handle_qUserName);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_close,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_Close);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_exists,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_md5,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_mode,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_open,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_Open);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_pread,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_pwrite,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_size,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_Size);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_stat,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_symlink,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vFile_unlink,
+      &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink);
 }
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon()
-{
-}
+GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() {}
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qHostInfo (StringExtractorGDBRemote &packet)
-{
-    StreamString response;
-
-    // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
-
-    ArchSpec host_arch(HostInfo::GetArchitecture());
-    const llvm::Triple &host_triple = host_arch.GetTriple();
-    response.PutCString("triple:");
-    response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
-    response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
-
-    const char* distribution_id = host_arch.GetDistributionId ().AsCString ();
-    if (distribution_id)
-    {
-        response.PutCString("distribution_id:");
-        response.PutCStringAsRawHex8(distribution_id);
-        response.PutCString(";");
-    }
+GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
+    StringExtractorGDBRemote &packet) {
+  StreamString response;
+
+  // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
+
+  ArchSpec host_arch(HostInfo::GetArchitecture());
+  const llvm::Triple &host_triple = host_arch.GetTriple();
+  response.PutCString("triple:");
+  response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
+  response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize());
+
+  const char *distribution_id = host_arch.GetDistributionId().AsCString();
+  if (distribution_id) {
+    response.PutCString("distribution_id:");
+    response.PutCStringAsRawHex8(distribution_id);
+    response.PutCString(";");
+  }
 
 #if defined(__APPLE__)
-    // For parity with debugserver, we'll include the vendor key.
-    response.PutCString("vendor:apple;");
+  // For parity with debugserver, we'll include the vendor key.
+  response.PutCString("vendor:apple;");
 
-    // Send out MachO info.
-    uint32_t cpu = host_arch.GetMachOCPUType();
-    uint32_t sub = host_arch.GetMachOCPUSubType();
-    if (cpu != LLDB_INVALID_CPUTYPE)
-        response.Printf ("cputype:%u;", cpu);
-    if (sub != LLDB_INVALID_CPUTYPE)
-        response.Printf ("cpusubtype:%u;", sub);
-
-    if (cpu == ArchSpec::kCore_arm_any)
-    {
-        // Indicate the OS type.
-#if defined (TARGET_OS_TV) && TARGET_OS_TV == 1
-        response.PutCString("ostype:tvos;");
-#elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
-        response.PutCString("ostype:watchos;");
+  // Send out MachO info.
+  uint32_t cpu = host_arch.GetMachOCPUType();
+  uint32_t sub = host_arch.GetMachOCPUSubType();
+  if (cpu != LLDB_INVALID_CPUTYPE)
+    response.Printf("cputype:%u;", cpu);
+  if (sub != LLDB_INVALID_CPUTYPE)
+    response.Printf("cpusubtype:%u;", sub);
+
+  if (cpu == ArchSpec::kCore_arm_any) {
+// Indicate the OS type.
+#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
+    response.PutCString("ostype:tvos;");
+#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
+    response.PutCString("ostype:watchos;");
 #else
-        response.PutCString("ostype:ios;");
+    response.PutCString("ostype:ios;");
 #endif
 
-        // On arm, we use "synchronous" watchpoints which means the exception is
-        // delivered before the instruction executes.
-        response.PutCString("watchpoint_exceptions_received:before;");
-    }
-    else
-    {
-        response.PutCString("ostype:macosx;");
-        response.Printf("watchpoint_exceptions_received:after;");
-    }
+    // On arm, we use "synchronous" watchpoints which means the exception is
+    // delivered before the instruction executes.
+    response.PutCString("watchpoint_exceptions_received:before;");
+  } else {
+    response.PutCString("ostype:macosx;");
+    response.Printf("watchpoint_exceptions_received:after;");
+  }
 
 #else
-    if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
-        host_arch.GetMachine() == llvm::Triple::aarch64_be ||
-        host_arch.GetMachine() == llvm::Triple::arm ||
-        host_arch.GetMachine() == llvm::Triple::armeb ||
-        host_arch.GetMachine() == llvm::Triple::mips64 ||
-        host_arch.GetMachine() == llvm::Triple::mips64el ||
-        host_arch.GetMachine() == llvm::Triple::mips ||
-        host_arch.GetMachine() == llvm::Triple::mipsel)
-        response.Printf("watchpoint_exceptions_received:before;");
-    else
-        response.Printf("watchpoint_exceptions_received:after;");
+  if (host_arch.GetMachine() == llvm::Triple::aarch64 ||
+      host_arch.GetMachine() == llvm::Triple::aarch64_be ||
+      host_arch.GetMachine() == llvm::Triple::arm ||
+      host_arch.GetMachine() == llvm::Triple::armeb ||
+      host_arch.GetMachine() == llvm::Triple::mips64 ||
+      host_arch.GetMachine() == llvm::Triple::mips64el ||
+      host_arch.GetMachine() == llvm::Triple::mips ||
+      host_arch.GetMachine() == llvm::Triple::mipsel)
+    response.Printf("watchpoint_exceptions_received:before;");
+  else
+    response.Printf("watchpoint_exceptions_received:after;");
 #endif
 
-    switch (endian::InlHostByteOrder())
-    {
-    case eByteOrderBig:     response.PutCString ("endian:big;"); break;
-    case eByteOrderLittle:  response.PutCString ("endian:little;"); break;
-    case eByteOrderPDP:     response.PutCString ("endian:pdp;"); break;
-    default:                response.PutCString ("endian:unknown;"); break;
-    }
-
-    uint32_t major = UINT32_MAX;
-    uint32_t minor = UINT32_MAX;
-    uint32_t update = UINT32_MAX;
-    if (HostInfo::GetOSVersion(major, minor, update))
-    {
-        if (major != UINT32_MAX)
-        {
-            response.Printf("os_version:%u", major);
-            if (minor != UINT32_MAX)
-            {
-                response.Printf(".%u", minor);
-                if (update != UINT32_MAX)
-                    response.Printf(".%u", update);
-            }
-            response.PutChar(';');
-        }
-    }
-
-    std::string s;
-    if (HostInfo::GetOSBuildString(s))
-    {
-        response.PutCString ("os_build:");
-        response.PutCStringAsRawHex8(s.c_str());
-        response.PutChar(';');
-    }
-    if (HostInfo::GetOSKernelDescription(s))
-    {
-        response.PutCString ("os_kernel:");
-        response.PutCStringAsRawHex8(s.c_str());
-        response.PutChar(';');
-    }
+  switch (endian::InlHostByteOrder()) {
+  case eByteOrderBig:
+    response.PutCString("endian:big;");
+    break;
+  case eByteOrderLittle:
+    response.PutCString("endian:little;");
+    break;
+  case eByteOrderPDP:
+    response.PutCString("endian:pdp;");
+    break;
+  default:
+    response.PutCString("endian:unknown;");
+    break;
+  }
+
+  uint32_t major = UINT32_MAX;
+  uint32_t minor = UINT32_MAX;
+  uint32_t update = UINT32_MAX;
+  if (HostInfo::GetOSVersion(major, minor, update)) {
+    if (major != UINT32_MAX) {
+      response.Printf("os_version:%u", major);
+      if (minor != UINT32_MAX) {
+        response.Printf(".%u", minor);
+        if (update != UINT32_MAX)
+          response.Printf(".%u", update);
+      }
+      response.PutChar(';');
+    }
+  }
+
+  std::string s;
+  if (HostInfo::GetOSBuildString(s)) {
+    response.PutCString("os_build:");
+    response.PutCStringAsRawHex8(s.c_str());
+    response.PutChar(';');
+  }
+  if (HostInfo::GetOSKernelDescription(s)) {
+    response.PutCString("os_kernel:");
+    response.PutCStringAsRawHex8(s.c_str());
+    response.PutChar(';');
+  }
 
 #if defined(__APPLE__)
 
 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-    // For iOS devices, we are connected through a USB Mux so we never pretend
-    // to actually have a hostname as far as the remote lldb that is connecting
-    // to this lldb-platform is concerned
-    response.PutCString ("hostname:");
-    response.PutCStringAsRawHex8("127.0.0.1");
+  // For iOS devices, we are connected through a USB Mux so we never pretend
+  // to actually have a hostname as far as the remote lldb that is connecting
+  // to this lldb-platform is concerned
+  response.PutCString("hostname:");
+  response.PutCStringAsRawHex8("127.0.0.1");
+  response.PutChar(';');
+#else  // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+  if (HostInfo::GetHostname(s)) {
+    response.PutCString("hostname:");
+    response.PutCStringAsRawHex8(s.c_str());
     response.PutChar(';');
-#else   // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-    if (HostInfo::GetHostname(s))
-    {
-        response.PutCString ("hostname:");
-        response.PutCStringAsRawHex8(s.c_str());
-        response.PutChar(';');
-    }
-#endif  // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
+  }
+#endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
 
-#else   // #if defined(__APPLE__)
-    if (HostInfo::GetHostname(s))
-    {
-        response.PutCString ("hostname:");
-        response.PutCStringAsRawHex8(s.c_str());
-        response.PutChar(';');
-    }
-#endif  // #if defined(__APPLE__)
+#else  // #if defined(__APPLE__)
+  if (HostInfo::GetHostname(s)) {
+    response.PutCString("hostname:");
+    response.PutCStringAsRawHex8(s.c_str());
+    response.PutChar(';');
+  }
+#endif // #if defined(__APPLE__)
 
-    if (g_default_packet_timeout_sec > 0)
-        response.Printf ("default_packet_timeout:%u;", g_default_packet_timeout_sec);
+  if (g_default_packet_timeout_sec > 0)
+    response.Printf("default_packet_timeout:%u;", g_default_packet_timeout_sec);
 
-    return SendPacketNoLock (response.GetString());
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
-{
-    // Packet format: "qProcessInfoPID:%i" where %i is the pid
-    packet.SetFilePos (::strlen ("qProcessInfoPID:"));
-    lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID);
-    if (pid != LLDB_INVALID_PROCESS_ID)
-    {
-        ProcessInstanceInfo proc_info;
-        if (Host::GetProcessInfo (pid, proc_info))
-        {
-            StreamString response;
-            CreateProcessInfoResponse (proc_info, response);
-            return SendPacketNoLock (response.GetString());
-        }
+GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID(
+    StringExtractorGDBRemote &packet) {
+  // Packet format: "qProcessInfoPID:%i" where %i is the pid
+  packet.SetFilePos(::strlen("qProcessInfoPID:"));
+  lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID);
+  if (pid != LLDB_INVALID_PROCESS_ID) {
+    ProcessInstanceInfo proc_info;
+    if (Host::GetProcessInfo(pid, proc_info)) {
+      StreamString response;
+      CreateProcessInfoResponse(proc_info, response);
+      return SendPacketNoLock(response.GetString());
     }
-    return SendErrorResponse (1);
+  }
+  return SendErrorResponse(1);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
-{
-    m_proc_infos_index = 0;
-    m_proc_infos.Clear();
-
-    ProcessInstanceInfoMatch match_info;
-    packet.SetFilePos(::strlen ("qfProcessInfo"));
-    if (packet.GetChar() == ':')
-    {
-        llvm::StringRef key;
-        llvm::StringRef value;
-        while (packet.GetNameColonValue(key, value))
-        {
-            bool success = true;
-            if (key.equals("name"))
-            {
-                StringExtractor extractor(value);
-                std::string file;
-                extractor.GetHexByteString(file);
-                match_info.GetProcessInfo().GetExecutableFile().SetFile(file.c_str(), false);
-            }
-            else if (key.equals("name_match"))
-            {
-                NameMatchType name_match = llvm::StringSwitch<NameMatchType>(value)
-                                               .Case("equals", eNameMatchEquals)
-                                               .Case("starts_with", eNameMatchStartsWith)
-                                               .Case("ends_with", eNameMatchEndsWith)
-                                               .Case("contains", eNameMatchContains)
-                                               .Case("regex", eNameMatchRegularExpression)
-                                               .Default(eNameMatchIgnore);
-                match_info.SetNameMatchType(name_match);
-                if (name_match == eNameMatchIgnore)
-                    return SendErrorResponse(2);
-            }
-            else if (key.equals("pid"))
-            {
-                lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-                if (value.getAsInteger(0, pid))
-                    return SendErrorResponse(2);
-                match_info.GetProcessInfo().SetProcessID(pid);
-            }
-            else if (key.equals("parent_pid"))
-            {
-                lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-                if (value.getAsInteger(0, pid))
-                    return SendErrorResponse(2);
-                match_info.GetProcessInfo().SetParentProcessID(pid);
-            }
-            else if (key.equals("uid"))
-            {
-                uint32_t uid = UINT32_MAX;
-                if (value.getAsInteger(0, uid))
-                    return SendErrorResponse(2);
-                match_info.GetProcessInfo().SetUserID(uid);
-            }
-            else if (key.equals("gid"))
-            {
-                uint32_t gid = UINT32_MAX;
-                if (value.getAsInteger(0, gid))
-                    return SendErrorResponse(2);
-                match_info.GetProcessInfo().SetGroupID(gid);
-            }
-            else if (key.equals("euid"))
-            {
-                uint32_t uid = UINT32_MAX;
-                if (value.getAsInteger(0, uid))
-                    return SendErrorResponse(2);
-                match_info.GetProcessInfo().SetEffectiveUserID(uid);
-            }
-            else if (key.equals("egid"))
-            {
-                uint32_t gid = UINT32_MAX;
-                if (value.getAsInteger(0, gid))
-                    return SendErrorResponse(2);
-                match_info.GetProcessInfo().SetEffectiveGroupID(gid);
-            }
-            else if (key.equals("all_users"))
-            {
-                match_info.SetMatchAllUsers(Args::StringToBoolean(value, false, &success));
-            }
-            else if (key.equals("triple"))
-            {
-                match_info.GetProcessInfo().GetArchitecture().SetTriple(value.str().c_str(), NULL);
-            }
-            else
-            {
-                success = false;
-            }
-
-            if (!success)
-                return SendErrorResponse (2);
-        }
-    }
-
-    if (Host::FindProcesses (match_info, m_proc_infos))
-    {
-        // We found something, return the first item by calling the get
-        // subsequent process info packet handler...
-        return Handle_qsProcessInfo (packet);
-    }
-    return SendErrorResponse (3);
-}
+GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo(
+    StringExtractorGDBRemote &packet) {
+  m_proc_infos_index = 0;
+  m_proc_infos.Clear();
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
-{
-    if (m_proc_infos_index < m_proc_infos.GetSize())
-    {
-        StreamString response;
-        CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
-        ++m_proc_infos_index;
-        return SendPacketNoLock (response.GetString());
-    }
-    return SendErrorResponse (4);
+  ProcessInstanceInfoMatch match_info;
+  packet.SetFilePos(::strlen("qfProcessInfo"));
+  if (packet.GetChar() == ':') {
+    llvm::StringRef key;
+    llvm::StringRef value;
+    while (packet.GetNameColonValue(key, value)) {
+      bool success = true;
+      if (key.equals("name")) {
+        StringExtractor extractor(value);
+        std::string file;
+        extractor.GetHexByteString(file);
+        match_info.GetProcessInfo().GetExecutableFile().SetFile(file.c_str(),
+                                                                false);
+      } else if (key.equals("name_match")) {
+        NameMatchType name_match =
+            llvm::StringSwitch<NameMatchType>(value)
+                .Case("equals", eNameMatchEquals)
+                .Case("starts_with", eNameMatchStartsWith)
+                .Case("ends_with", eNameMatchEndsWith)
+                .Case("contains", eNameMatchContains)
+                .Case("regex", eNameMatchRegularExpression)
+                .Default(eNameMatchIgnore);
+        match_info.SetNameMatchType(name_match);
+        if (name_match == eNameMatchIgnore)
+          return SendErrorResponse(2);
+      } else if (key.equals("pid")) {
+        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+        if (value.getAsInteger(0, pid))
+          return SendErrorResponse(2);
+        match_info.GetProcessInfo().SetProcessID(pid);
+      } else if (key.equals("parent_pid")) {
+        lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+        if (value.getAsInteger(0, pid))
+          return SendErrorResponse(2);
+        match_info.GetProcessInfo().SetParentProcessID(pid);
+      } else if (key.equals("uid")) {
+        uint32_t uid = UINT32_MAX;
+        if (value.getAsInteger(0, uid))
+          return SendErrorResponse(2);
+        match_info.GetProcessInfo().SetUserID(uid);
+      } else if (key.equals("gid")) {
+        uint32_t gid = UINT32_MAX;
+        if (value.getAsInteger(0, gid))
+          return SendErrorResponse(2);
+        match_info.GetProcessInfo().SetGroupID(gid);
+      } else if (key.equals("euid")) {
+        uint32_t uid = UINT32_MAX;
+        if (value.getAsInteger(0, uid))
+          return SendErrorResponse(2);
+        match_info.GetProcessInfo().SetEffectiveUserID(uid);
+      } else if (key.equals("egid")) {
+        uint32_t gid = UINT32_MAX;
+        if (value.getAsInteger(0, gid))
+          return SendErrorResponse(2);
+        match_info.GetProcessInfo().SetEffectiveGroupID(gid);
+      } else if (key.equals("all_users")) {
+        match_info.SetMatchAllUsers(
+            Args::StringToBoolean(value, false, &success));
+      } else if (key.equals("triple")) {
+        match_info.GetProcessInfo().GetArchitecture().SetTriple(
+            value.str().c_str(), NULL);
+      } else {
+        success = false;
+      }
+
+      if (!success)
+        return SendErrorResponse(2);
+    }
+  }
+
+  if (Host::FindProcesses(match_info, m_proc_infos)) {
+    // We found something, return the first item by calling the get
+    // subsequent process info packet handler...
+    return Handle_qsProcessInfo(packet);
+  }
+  return SendErrorResponse(3);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
+    StringExtractorGDBRemote &packet) {
+  if (m_proc_infos_index < m_proc_infos.GetSize()) {
+    StreamString response;
+    CreateProcessInfoResponse(
+        m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response);
+    ++m_proc_infos_index;
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(4);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qUserName (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_qUserName(
+    StringExtractorGDBRemote &packet) {
 #if !defined(LLDB_DISABLE_POSIX)
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    if (log)
-        log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
-
-    // Packet format: "qUserName:%i" where %i is the uid
-    packet.SetFilePos(::strlen ("qUserName:"));
-    uint32_t uid = packet.GetU32 (UINT32_MAX);
-    if (uid != UINT32_MAX)
-    {
-        std::string name;
-        if (HostInfo::LookupUserName(uid, name))
-        {
-            StreamString response;
-            response.PutCStringAsRawHex8 (name.c_str());
-            return SendPacketNoLock (response.GetString());
-        }
-    }
-    if (log)
-        log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
+
+  // Packet format: "qUserName:%i" where %i is the uid
+  packet.SetFilePos(::strlen("qUserName:"));
+  uint32_t uid = packet.GetU32(UINT32_MAX);
+  if (uid != UINT32_MAX) {
+    std::string name;
+    if (HostInfo::LookupUserName(uid, name)) {
+      StreamString response;
+      response.PutCStringAsRawHex8(name.c_str());
+      return SendPacketNoLock(response.GetString());
+    }
+  }
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
 #endif
-    return SendErrorResponse (5);
-
+  return SendErrorResponse(5);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qGroupName (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_qGroupName(
+    StringExtractorGDBRemote &packet) {
 #if !defined(LLDB_DISABLE_POSIX)
-    // Packet format: "qGroupName:%i" where %i is the gid
-    packet.SetFilePos(::strlen ("qGroupName:"));
-    uint32_t gid = packet.GetU32 (UINT32_MAX);
-    if (gid != UINT32_MAX)
-    {
-        std::string name;
-        if (HostInfo::LookupGroupName(gid, name))
-        {
-            StreamString response;
-            response.PutCStringAsRawHex8 (name.c_str());
-            return SendPacketNoLock (response.GetString());
-        }
+  // Packet format: "qGroupName:%i" where %i is the gid
+  packet.SetFilePos(::strlen("qGroupName:"));
+  uint32_t gid = packet.GetU32(UINT32_MAX);
+  if (gid != UINT32_MAX) {
+    std::string name;
+    if (HostInfo::LookupGroupName(gid, name)) {
+      StreamString response;
+      response.PutCStringAsRawHex8(name.c_str());
+      return SendPacketNoLock(response.GetString());
     }
+  }
 #endif
-    return SendErrorResponse (6);
+  return SendErrorResponse(6);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("qSpeedTest:"));
+GDBRemoteCommunicationServerCommon::Handle_qSpeedTest(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("qSpeedTest:"));
 
-    llvm::StringRef key;
-    llvm::StringRef value;
-    bool success = packet.GetNameColonValue(key, value);
-    if (success && key.equals("response_size"))
-    {
-        uint32_t response_size = 0;
-        if (!value.getAsInteger(0, response_size))
-        {
-            if (response_size == 0)
-                return SendOKResponse();
-            StreamString response;
-            uint32_t bytes_left = response_size;
-            response.PutCString("data:");
-            while (bytes_left > 0)
-            {
-                if (bytes_left >= 26)
-                {
-                    response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-                    bytes_left -= 26;
-                }
-                else
-                {
-                    response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
-                    bytes_left = 0;
-                }
-            }
-            return SendPacketNoLock (response.GetString());
+  llvm::StringRef key;
+  llvm::StringRef value;
+  bool success = packet.GetNameColonValue(key, value);
+  if (success && key.equals("response_size")) {
+    uint32_t response_size = 0;
+    if (!value.getAsInteger(0, response_size)) {
+      if (response_size == 0)
+        return SendOKResponse();
+      StreamString response;
+      uint32_t bytes_left = response_size;
+      response.PutCString("data:");
+      while (bytes_left > 0) {
+        if (bytes_left >= 26) {
+          response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+          bytes_left -= 26;
+        } else {
+          response.Printf("%*.*s;", bytes_left, bytes_left,
+                          "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+          bytes_left = 0;
         }
+      }
+      return SendPacketNoLock(response.GetString());
     }
-    return SendErrorResponse (7);
+  }
+  return SendErrorResponse(7);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:open:"));
-    std::string path;
-    packet.GetHexByteStringTerminatedBy(path,',');
-    if (!path.empty())
-    {
-        if (packet.GetChar() == ',')
-        {
-            uint32_t flags = File::ConvertOpenOptionsForPOSIXOpen(
-                packet.GetHexMaxU32(false, 0));
-            if (packet.GetChar() == ',')
-            {
-                mode_t mode = packet.GetHexMaxU32(false, 0600);
-                Error error;
-                const FileSpec path_spec{path, true};
-                int fd = ::open(path_spec.GetCString(), flags, mode);
-                const int save_errno = fd == -1 ? errno : 0;
-                StreamString response;
-                response.PutChar('F');
-                response.Printf("%i", fd);
-                if (save_errno)
-                    response.Printf(",%i", save_errno);
-                return SendPacketNoLock(response.GetString());
-            }
-        }
+GDBRemoteCommunicationServerCommon::Handle_vFile_Open(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:open:"));
+  std::string path;
+  packet.GetHexByteStringTerminatedBy(path, ',');
+  if (!path.empty()) {
+    if (packet.GetChar() == ',') {
+      uint32_t flags =
+          File::ConvertOpenOptionsForPOSIXOpen(packet.GetHexMaxU32(false, 0));
+      if (packet.GetChar() == ',') {
+        mode_t mode = packet.GetHexMaxU32(false, 0600);
+        Error error;
+        const FileSpec path_spec{path, true};
+        int fd = ::open(path_spec.GetCString(), flags, mode);
+        const int save_errno = fd == -1 ? errno : 0;
+        StreamString response;
+        response.PutChar('F');
+        response.Printf("%i", fd);
+        if (save_errno)
+          response.Printf(",%i", save_errno);
+        return SendPacketNoLock(response.GetString());
+      }
     }
-    return SendErrorResponse(18);
+  }
+  return SendErrorResponse(18);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Close (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:close:"));
-    int fd = packet.GetS32(-1);
-    Error error;
-    int err = -1;
-    int save_errno = 0;
-    if (fd >= 0)
-    {
-        err = close(fd);
-        save_errno = err == -1 ? errno : 0;
-    }
-    else
-    {
-        save_errno = EINVAL;
-    }
-    StreamString response;
-    response.PutChar('F');
-    response.Printf("%i", err);
-    if (save_errno)
-        response.Printf(",%i", save_errno);
-    return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerCommon::Handle_vFile_Close(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:close:"));
+  int fd = packet.GetS32(-1);
+  Error error;
+  int err = -1;
+  int save_errno = 0;
+  if (fd >= 0) {
+    err = close(fd);
+    save_errno = err == -1 ? errno : 0;
+  } else {
+    save_errno = EINVAL;
+  }
+  StreamString response;
+  response.PutChar('F');
+  response.Printf("%i", err);
+  if (save_errno)
+    response.Printf(",%i", save_errno);
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
+    StringExtractorGDBRemote &packet) {
 #ifdef _WIN32
-    // Not implemented on Windows
-    return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
+  // Not implemented on Windows
+  return SendUnimplementedResponse(
+      "GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented");
 #else
-    StreamGDBRemote response;
-    packet.SetFilePos(::strlen("vFile:pread:"));
-    int fd = packet.GetS32(-1);
-    if (packet.GetChar() == ',')
-    {
-        uint64_t count = packet.GetU64(UINT64_MAX);
-        if (packet.GetChar() == ',')
-        {
-            uint64_t offset = packet.GetU64(UINT32_MAX);
-            if (count == UINT64_MAX)
-            {
-                response.Printf("F-1:%i", EINVAL);
-                return SendPacketNoLock(response.GetString());
-            }
+  StreamGDBRemote response;
+  packet.SetFilePos(::strlen("vFile:pread:"));
+  int fd = packet.GetS32(-1);
+  if (packet.GetChar() == ',') {
+    uint64_t count = packet.GetU64(UINT64_MAX);
+    if (packet.GetChar() == ',') {
+      uint64_t offset = packet.GetU64(UINT32_MAX);
+      if (count == UINT64_MAX) {
+        response.Printf("F-1:%i", EINVAL);
+        return SendPacketNoLock(response.GetString());
+      }
 
-            std::string buffer(count, 0);
-            const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
-            const int save_errno = bytes_read == -1 ? errno : 0;
-            response.PutChar('F');
-            response.Printf("%zi", bytes_read);
-            if (save_errno)
-                response.Printf(",%i", save_errno);
-            else
-            {
-                response.PutChar(';');
-                response.PutEscapedBytes(&buffer[0], bytes_read);
-            }
-            return SendPacketNoLock(response.GetString());
-        }
+      std::string buffer(count, 0);
+      const ssize_t bytes_read = ::pread(fd, &buffer[0], buffer.size(), offset);
+      const int save_errno = bytes_read == -1 ? errno : 0;
+      response.PutChar('F');
+      response.Printf("%zi", bytes_read);
+      if (save_errno)
+        response.Printf(",%i", save_errno);
+      else {
+        response.PutChar(';');
+        response.PutEscapedBytes(&buffer[0], bytes_read);
+      }
+      return SendPacketNoLock(response.GetString());
     }
-    return SendErrorResponse(21);
+  }
+  return SendErrorResponse(21);
 
 #endif
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
+    StringExtractorGDBRemote &packet) {
 #ifdef _WIN32
-    return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite() unimplemented");
+  return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_"
+                                   "vFile_pWrite() unimplemented");
 #else
-    packet.SetFilePos(::strlen("vFile:pwrite:"));
+  packet.SetFilePos(::strlen("vFile:pwrite:"));
 
-    StreamGDBRemote response;
-    response.PutChar('F');
+  StreamGDBRemote response;
+  response.PutChar('F');
 
-    int fd = packet.GetU32(UINT32_MAX);
-    if (packet.GetChar() == ',')
-    {
-        off_t offset = packet.GetU64(UINT32_MAX);
-        if (packet.GetChar() == ',')
-        {
-            std::string buffer;
-            if (packet.GetEscapedBinaryData(buffer))
-            {
-                const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset);
-                const int save_errno = bytes_written == -1 ? errno : 0;
-                response.Printf("%zi", bytes_written);
-                if (save_errno)
-                    response.Printf(",%i", save_errno);
-            }
-            else
-            {
-                response.Printf ("-1,%i", EINVAL);
-            }
-            return SendPacketNoLock(response.GetString());
-        }
+  int fd = packet.GetU32(UINT32_MAX);
+  if (packet.GetChar() == ',') {
+    off_t offset = packet.GetU64(UINT32_MAX);
+    if (packet.GetChar() == ',') {
+      std::string buffer;
+      if (packet.GetEscapedBinaryData(buffer)) {
+        const ssize_t bytes_written =
+            ::pwrite(fd, buffer.data(), buffer.size(), offset);
+        const int save_errno = bytes_written == -1 ? errno : 0;
+        response.Printf("%zi", bytes_written);
+        if (save_errno)
+          response.Printf(",%i", save_errno);
+      } else {
+        response.Printf("-1,%i", EINVAL);
+      }
+      return SendPacketNoLock(response.GetString());
     }
-    return SendErrorResponse(27);
+  }
+  return SendErrorResponse(27);
 #endif
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Size (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:size:"));
-    std::string path;
-    packet.GetHexByteString(path);
-    if (!path.empty())
-    {
-        lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path.c_str(), false));
-        StreamString response;
-        response.PutChar('F');
-        response.PutHex64(retcode);
-        if (retcode == UINT64_MAX)
-        {
-            response.PutChar(',');
-            response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode()
-        }
-        return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:size:"));
+  std::string path;
+  packet.GetHexByteString(path);
+  if (!path.empty()) {
+    lldb::user_id_t retcode =
+        FileSystem::GetFileSize(FileSpec(path.c_str(), false));
+    StreamString response;
+    response.PutChar('F');
+    response.PutHex64(retcode);
+    if (retcode == UINT64_MAX) {
+      response.PutChar(',');
+      response.PutHex64(
+          retcode); // TODO: replace with Host::GetSyswideErrorCode()
     }
-    return SendErrorResponse(22);
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(22);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:mode:"));
-    std::string path;
-    packet.GetHexByteString(path);
-    if (!path.empty())
-    {
-        Error error;
-        const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
-        StreamString response;
-        response.Printf("F%u", mode);
-        if (mode == 0 || error.Fail())
-            response.Printf(",%i", (int)error.GetError());
-        return SendPacketNoLock(response.GetString());
-    }
-    return SendErrorResponse(23);
+GDBRemoteCommunicationServerCommon::Handle_vFile_Mode(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:mode:"));
+  std::string path;
+  packet.GetHexByteString(path);
+  if (!path.empty()) {
+    Error error;
+    const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error);
+    StreamString response;
+    response.Printf("F%u", mode);
+    if (mode == 0 || error.Fail())
+      response.Printf(",%i", (int)error.GetError());
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(23);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:exists:"));
-    std::string path;
-    packet.GetHexByteString(path);
-    if (!path.empty())
-    {
-        bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false));
-        StreamString response;
-        response.PutChar('F');
-        response.PutChar(',');
-        if (retcode)
-            response.PutChar('1');
-        else
-            response.PutChar('0');
-        return SendPacketNoLock(response.GetString());
-    }
-    return SendErrorResponse(24);
+GDBRemoteCommunicationServerCommon::Handle_vFile_Exists(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:exists:"));
+  std::string path;
+  packet.GetHexByteString(path);
+  if (!path.empty()) {
+    bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false));
+    StreamString response;
+    response.PutChar('F');
+    response.PutChar(',');
+    if (retcode)
+      response.PutChar('1');
+    else
+      response.PutChar('0');
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(24);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:symlink:"));
-    std::string dst, src;
-    packet.GetHexByteStringTerminatedBy(dst, ',');
-    packet.GetChar(); // Skip ',' char
-    packet.GetHexByteString(src);
-    Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
-    StreamString response;
-    response.Printf("F%u,%u", error.GetError(), error.GetError());
-    return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerCommon::Handle_vFile_symlink(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:symlink:"));
+  std::string dst, src;
+  packet.GetHexByteStringTerminatedBy(dst, ',');
+  packet.GetChar(); // Skip ',' char
+  packet.GetHexByteString(src);
+  Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false});
+  StreamString response;
+  response.Printf("F%u,%u", error.GetError(), error.GetError());
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:unlink:"));
-    std::string path;
-    packet.GetHexByteString(path);
-    Error error = FileSystem::Unlink(FileSpec{path, true});
-    StreamString response;
-    response.Printf("F%u,%u", error.GetError(), error.GetError());
-    return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:unlink:"));
+  std::string path;
+  packet.GetHexByteString(path);
+  Error error = FileSystem::Unlink(FileSpec{path, true});
+  StreamString response;
+  response.Printf("F%u,%u", error.GetError(), error.GetError());
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("qPlatform_shell:"));
-    std::string path;
-    std::string working_dir;
-    packet.GetHexByteStringTerminatedBy(path,',');
-    if (!path.empty())
-    {
-        if (packet.GetChar() == ',')
-        {
-            // FIXME: add timeout to qPlatform_shell packet
-            // uint32_t timeout = packet.GetHexMaxU32(false, 32);
-            uint32_t timeout = 10;
-            if (packet.GetChar() == ',')
-                packet.GetHexByteString(working_dir);
-            int status, signo;
-            std::string output;
-            Error err = Host::RunShellCommand(path.c_str(),
-                                              FileSpec{working_dir, true},
-                                              &status, &signo, &output, timeout);
-            StreamGDBRemote response;
-            if (err.Fail())
-            {
-                response.PutCString("F,");
-                response.PutHex32(UINT32_MAX);
-            }
-            else
-            {
-                response.PutCString("F,");
-                response.PutHex32(status);
-                response.PutChar(',');
-                response.PutHex32(signo);
-                response.PutChar(',');
-                response.PutEscapedBytes(output.c_str(), output.size());
-            }
-            return SendPacketNoLock(response.GetString());
-        }
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("qPlatform_shell:"));
+  std::string path;
+  std::string working_dir;
+  packet.GetHexByteStringTerminatedBy(path, ',');
+  if (!path.empty()) {
+    if (packet.GetChar() == ',') {
+      // FIXME: add timeout to qPlatform_shell packet
+      // uint32_t timeout = packet.GetHexMaxU32(false, 32);
+      uint32_t timeout = 10;
+      if (packet.GetChar() == ',')
+        packet.GetHexByteString(working_dir);
+      int status, signo;
+      std::string output;
+      Error err =
+          Host::RunShellCommand(path.c_str(), FileSpec{working_dir, true},
+                                &status, &signo, &output, timeout);
+      StreamGDBRemote response;
+      if (err.Fail()) {
+        response.PutCString("F,");
+        response.PutHex32(UINT32_MAX);
+      } else {
+        response.PutCString("F,");
+        response.PutHex32(status);
+        response.PutChar(',');
+        response.PutHex32(signo);
+        response.PutChar(',');
+        response.PutEscapedBytes(output.c_str(), output.size());
+      }
+      return SendPacketNoLock(response.GetString());
     }
-    return SendErrorResponse(24);
+  }
+  return SendErrorResponse(24);
 }
 
-
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
-{
-    return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
+GDBRemoteCommunicationServerCommon::Handle_vFile_Stat(
+    StringExtractorGDBRemote &packet) {
+  return SendUnimplementedResponse(
+      "GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented");
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:MD5:"));
-    std::string path;
-    packet.GetHexByteString(path);
-    if (!path.empty())
-    {
-        uint64_t a,b;
-        StreamGDBRemote response;
-        if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b))
-        {
-            response.PutCString("F,");
-            response.PutCString("x");
-        }
-        else
-        {
-            response.PutCString("F,");
-            response.PutHex64(a);
-            response.PutHex64(b);
-        }
-        return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerCommon::Handle_vFile_MD5(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("vFile:MD5:"));
+  std::string path;
+  packet.GetHexByteString(path);
+  if (!path.empty()) {
+    uint64_t a, b;
+    StreamGDBRemote response;
+    if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b)) {
+      response.PutCString("F,");
+      response.PutCString("x");
+    } else {
+      response.PutCString("F,");
+      response.PutHex64(a);
+      response.PutHex64(b);
     }
-    return SendErrorResponse(25);
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(25);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("qPlatform_mkdir:"));
-    mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
-    if (packet.GetChar() == ',')
-    {
-        std::string path;
-        packet.GetHexByteString(path);
-        Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("qPlatform_mkdir:"));
+  mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+  if (packet.GetChar() == ',') {
+    std::string path;
+    packet.GetHexByteString(path);
+    Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
 
-        StreamGDBRemote response;
-        response.Printf("F%u", error.GetError());
+    StreamGDBRemote response;
+    response.Printf("F%u", error.GetError());
 
-        return SendPacketNoLock(response.GetString());
-    }
-    return SendErrorResponse(20);
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(20);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("qPlatform_chmod:"));
+GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("qPlatform_chmod:"));
 
-    mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
-    if (packet.GetChar() == ',')
-    {
-        std::string path;
-        packet.GetHexByteString(path);
-        Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
+  mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
+  if (packet.GetChar() == ',') {
+    std::string path;
+    packet.GetHexByteString(path);
+    Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);
 
-        StreamGDBRemote response;
-        response.Printf("F%u", error.GetError());
+    StreamGDBRemote response;
+    response.Printf("F%u", error.GetError());
 
-        return SendPacketNoLock(response.GetString());
-    }
-    return SendErrorResponse(19);
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(19);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSupported (StringExtractorGDBRemote &packet)
-{
-    StreamGDBRemote response;
+GDBRemoteCommunicationServerCommon::Handle_qSupported(
+    StringExtractorGDBRemote &packet) {
+  StreamGDBRemote response;
 
-    // Features common to lldb-platform and llgs.
-    uint32_t max_packet_size = 128 * 1024;  // 128KBytes is a reasonable max packet size--debugger can always use less
-    response.Printf ("PacketSize=%x", max_packet_size);
-
-    response.PutCString (";QStartNoAckMode+");
-    response.PutCString (";QThreadSuffixSupported+");
-    response.PutCString (";QListThreadsInStopReply+");
-    response.PutCString (";qEcho+");
+  // Features common to lldb-platform and llgs.
+  uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet
+                                         // size--debugger can always use less
+  response.Printf("PacketSize=%x", max_packet_size);
+
+  response.PutCString(";QStartNoAckMode+");
+  response.PutCString(";QThreadSuffixSupported+");
+  response.PutCString(";QListThreadsInStopReply+");
+  response.PutCString(";qEcho+");
 #if defined(__linux__)
-    response.PutCString (";qXfer:auxv:read+");
+  response.PutCString(";qXfer:auxv:read+");
 #endif
 
-    return SendPacketNoLock(response.GetString());
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet)
-{
-    m_thread_suffix_supported = true;
-    return SendOKResponse();
+GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported(
+    StringExtractorGDBRemote &packet) {
+  m_thread_suffix_supported = true;
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet)
-{
-    m_list_threads_in_stop_reply = true;
-    return SendOKResponse();
+GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply(
+    StringExtractorGDBRemote &packet) {
+  m_list_threads_in_stop_reply = true;
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QSetDetachOnError:"));
-    if (packet.GetU32(0))
-        m_process_launch_info.GetFlags().Set (eLaunchFlagDetachOnError);
-    else
-        m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError);
-    return SendOKResponse ();
+GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetDetachOnError:"));
+  if (packet.GetU32(0))
+    m_process_launch_info.GetFlags().Set(eLaunchFlagDetachOnError);
+  else
+    m_process_launch_info.GetFlags().Clear(eLaunchFlagDetachOnError);
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
-{
-    // Send response first before changing m_send_acks to we ack this packet
-    PacketResult packet_result = SendOKResponse ();
-    m_send_acks = false;
-    return packet_result;
+GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode(
+    StringExtractorGDBRemote &packet) {
+  // Send response first before changing m_send_acks to we ack this packet
+  PacketResult packet_result = SendOKResponse();
+  m_send_acks = false;
+  return packet_result;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QSetSTDIN:"));
-    FileAction file_action;
-    std::string path;
-    packet.GetHexByteString(path);
-    const bool read = true;
-    const bool write = false;
-    if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write))
-    {
-        m_process_launch_info.AppendFileAction(file_action);
-        return SendOKResponse ();
-    }
-    return SendErrorResponse (15);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetSTDIN:"));
+  FileAction file_action;
+  std::string path;
+  packet.GetHexByteString(path);
+  const bool read = true;
+  const bool write = false;
+  if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) {
+    m_process_launch_info.AppendFileAction(file_action);
+    return SendOKResponse();
+  }
+  return SendErrorResponse(15);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QSetSTDOUT:"));
-    FileAction file_action;
-    std::string path;
-    packet.GetHexByteString(path);
-    const bool read = false;
-    const bool write = true;
-    if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write))
-    {
-        m_process_launch_info.AppendFileAction(file_action);
-        return SendOKResponse ();
-    }
-    return SendErrorResponse (16);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetSTDOUT:"));
+  FileAction file_action;
+  std::string path;
+  packet.GetHexByteString(path);
+  const bool read = false;
+  const bool write = true;
+  if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) {
+    m_process_launch_info.AppendFileAction(file_action);
+    return SendOKResponse();
+  }
+  return SendErrorResponse(16);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QSetSTDERR:"));
-    FileAction file_action;
-    std::string path;
-    packet.GetHexByteString(path);
-    const bool read = false;
-    const bool write = true;
-    if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write))
-    {
-        m_process_launch_info.AppendFileAction(file_action);
-        return SendOKResponse ();
-    }
-    return SendErrorResponse (17);
+GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetSTDERR:"));
+  FileAction file_action;
+  std::string path;
+  packet.GetHexByteString(path);
+  const bool read = false;
+  const bool write = true;
+  if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) {
+    m_process_launch_info.AppendFileAction(file_action);
+    return SendOKResponse();
+  }
+  return SendErrorResponse(17);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
-{
-    if (m_process_launch_error.Success())
-        return SendOKResponse();
-    StreamString response;
-    response.PutChar('E');
-    response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
-    return SendPacketNoLock (response.GetString());
+GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess(
+    StringExtractorGDBRemote &packet) {
+  if (m_process_launch_error.Success())
+    return SendOKResponse();
+  StreamString response;
+  response.PutChar('E');
+  response.PutCString(m_process_launch_error.AsCString("<unknown error>"));
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QEnvironment (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QEnvironment:"));
-    const uint32_t bytes_left = packet.GetBytesLeft();
-    if (bytes_left > 0)
-    {
-        m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek());
-        return SendOKResponse ();
-    }
-    return SendErrorResponse (12);
+GDBRemoteCommunicationServerCommon::Handle_QEnvironment(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QEnvironment:"));
+  const uint32_t bytes_left = packet.GetBytesLeft();
+  if (bytes_left > 0) {
+    m_process_launch_info.GetEnvironmentEntries().AppendArgument(packet.Peek());
+    return SendOKResponse();
+  }
+  return SendErrorResponse(12);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
-    const uint32_t bytes_left = packet.GetBytesLeft();
-    if (bytes_left > 0)
-    {
-        std::string str;
-        packet.GetHexByteString(str);
-        m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str());
-        return SendOKResponse();
-    }
-    return SendErrorResponse(12);
+GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QEnvironmentHexEncoded:"));
+  const uint32_t bytes_left = packet.GetBytesLeft();
+  if (bytes_left > 0) {
+    std::string str;
+    packet.GetHexByteString(str);
+    m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str());
+    return SendOKResponse();
+  }
+  return SendErrorResponse(12);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QLaunchArch:"));
-    const uint32_t bytes_left = packet.GetBytesLeft();
-    if (bytes_left > 0)
-    {
-        const char* arch_triple = packet.Peek();
-        ArchSpec arch_spec(arch_triple,NULL);
-        m_process_launch_info.SetArchitecture(arch_spec);
-        return SendOKResponse();
-    }
-    return SendErrorResponse(13);
+GDBRemoteCommunicationServerCommon::Handle_QLaunchArch(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QLaunchArch:"));
+  const uint32_t bytes_left = packet.GetBytesLeft();
+  if (bytes_left > 0) {
+    const char *arch_triple = packet.Peek();
+    ArchSpec arch_spec(arch_triple, NULL);
+    m_process_launch_info.SetArchitecture(arch_spec);
+    return SendOKResponse();
+  }
+  return SendErrorResponse(13);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_A (StringExtractorGDBRemote &packet)
-{
-    // The 'A' packet is the most over designed packet ever here with
-    // redundant argument indexes, redundant argument lengths and needed hex
-    // encoded argument string values. Really all that is needed is a comma
-    // separated hex encoded argument value list, but we will stay true to the
-    // documented version of the 'A' packet here...
-
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    int actual_arg_index = 0;
-
-    packet.SetFilePos(1); // Skip the 'A'
-    bool success = true;
-    while (success && packet.GetBytesLeft() > 0)
-    {
-        // Decode the decimal argument string length. This length is the
-        // number of hex nibbles in the argument string value.
-        const uint32_t arg_len = packet.GetU32(UINT32_MAX);
-        if (arg_len == UINT32_MAX)
+GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
+  // The 'A' packet is the most over designed packet ever here with
+  // redundant argument indexes, redundant argument lengths and needed hex
+  // encoded argument string values. Really all that is needed is a comma
+  // separated hex encoded argument value list, but we will stay true to the
+  // documented version of the 'A' packet here...
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  int actual_arg_index = 0;
+
+  packet.SetFilePos(1); // Skip the 'A'
+  bool success = true;
+  while (success && packet.GetBytesLeft() > 0) {
+    // Decode the decimal argument string length. This length is the
+    // number of hex nibbles in the argument string value.
+    const uint32_t arg_len = packet.GetU32(UINT32_MAX);
+    if (arg_len == UINT32_MAX)
+      success = false;
+    else {
+      // Make sure the argument hex string length is followed by a comma
+      if (packet.GetChar() != ',')
+        success = false;
+      else {
+        // Decode the argument index. We ignore this really because
+        // who would really send down the arguments in a random order???
+        const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
+        if (arg_idx == UINT32_MAX)
+          success = false;
+        else {
+          // Make sure the argument index is followed by a comma
+          if (packet.GetChar() != ',')
             success = false;
-        else
-        {
-            // Make sure the argument hex string length is followed by a comma
-            if (packet.GetChar() != ',')
-                success = false;
-            else
-            {
-                // Decode the argument index. We ignore this really because
-                // who would really send down the arguments in a random order???
-                const uint32_t arg_idx = packet.GetU32(UINT32_MAX);
-                if (arg_idx == UINT32_MAX)
-                    success = false;
-                else
-                {
-                    // Make sure the argument index is followed by a comma
-                    if (packet.GetChar() != ',')
-                        success = false;
-                    else
-                    {
-                        // Decode the argument string value from hex bytes
-                        // back into a UTF8 string and make sure the length
-                        // matches the one supplied in the packet
-                        std::string arg;
-                        if (packet.GetHexByteStringFixedLength(arg, arg_len) != (arg_len / 2))
-                            success = false;
-                        else
-                        {
-                            // If there are any bytes left
-                            if (packet.GetBytesLeft())
-                            {
-                                if (packet.GetChar() != ',')
-                                    success = false;
-                            }
-
-                            if (success)
-                            {
-                                if (arg_idx == 0)
-                                    m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false);
-                                m_process_launch_info.GetArguments().AppendArgument(arg.c_str());
-                                if (log)
-                                    log->Printf ("LLGSPacketHandler::%s added arg %d: \"%s\"", __FUNCTION__, actual_arg_index, arg.c_str ());
-                                ++actual_arg_index;
-                            }
-                        }
-                    }
-                }
+          else {
+            // Decode the argument string value from hex bytes
+            // back into a UTF8 string and make sure the length
+            // matches the one supplied in the packet
+            std::string arg;
+            if (packet.GetHexByteStringFixedLength(arg, arg_len) !=
+                (arg_len / 2))
+              success = false;
+            else {
+              // If there are any bytes left
+              if (packet.GetBytesLeft()) {
+                if (packet.GetChar() != ',')
+                  success = false;
+              }
+
+              if (success) {
+                if (arg_idx == 0)
+                  m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(),
+                                                                    false);
+                m_process_launch_info.GetArguments().AppendArgument(
+                    arg.c_str());
+                if (log)
+                  log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"",
+                              __FUNCTION__, actual_arg_index, arg.c_str());
+                ++actual_arg_index;
+              }
             }
+          }
         }
+      }
     }
+  }
 
-    if (success)
-    {
-        m_process_launch_error = LaunchProcess ();
-        if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
-        {
-            return SendOKResponse ();
-        }
-        else
-        {
-            Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-            if (log)
-                log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
-                        __FUNCTION__,
-                        m_process_launch_error.AsCString());
-
-        }
-    }
-    return SendErrorResponse (8);
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qEcho (StringExtractorGDBRemote &packet)
-{
-    // Just echo back the exact same packet for qEcho...
-    return SendPacketNoLock(packet.GetStringRef());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("qModuleInfo:"));
-
-    std::string module_path;
-    packet.GetHexByteStringTerminatedBy(module_path, ';');
-    if (module_path.empty())
-        return SendErrorResponse (1);
-
-    if (packet.GetChar() != ';')
-        return SendErrorResponse (2);
-
-    std::string triple;
-    packet.GetHexByteString(triple);
-    ArchSpec arch(triple.c_str());
-
-    const FileSpec req_module_path_spec(module_path.c_str(), true);
-    const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch);
-    const ModuleSpec module_spec(module_path_spec, arch);
-
-    ModuleSpecList module_specs;
-    if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs))
-        return SendErrorResponse (3);
-
-    ModuleSpec matched_module_spec;
-    if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
-        return SendErrorResponse (4);
-
-    const auto file_offset = matched_module_spec.GetObjectOffset();
-    const auto file_size = matched_module_spec.GetObjectSize();
-    const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
-
-    StreamGDBRemote response;
-
-    if (uuid_str.empty())
-    {
-        std::string md5_hash;
-        if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash))
-            return SendErrorResponse (5);
-        response.PutCString ("md5:");
-        response.PutCStringAsRawHex8(md5_hash.c_str());
-    }
-    else{
-        response.PutCString ("uuid:");
-        response.PutCStringAsRawHex8(uuid_str.c_str());
-    }
-    response.PutChar(';');
-
-    const auto &module_arch = matched_module_spec.GetArchitecture();
+  if (success) {
+    m_process_launch_error = LaunchProcess();
+    if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+      return SendOKResponse();
+    } else {
+      Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+      if (log)
+        log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
+                    __FUNCTION__, m_process_launch_error.AsCString());
+    }
+  }
+  return SendErrorResponse(8);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_qEcho(
+    StringExtractorGDBRemote &packet) {
+  // Just echo back the exact same packet for qEcho...
+  return SendPacketNoLock(packet.GetStringRef());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_qModuleInfo(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("qModuleInfo:"));
+
+  std::string module_path;
+  packet.GetHexByteStringTerminatedBy(module_path, ';');
+  if (module_path.empty())
+    return SendErrorResponse(1);
+
+  if (packet.GetChar() != ';')
+    return SendErrorResponse(2);
+
+  std::string triple;
+  packet.GetHexByteString(triple);
+  ArchSpec arch(triple.c_str());
+
+  const FileSpec req_module_path_spec(module_path.c_str(), true);
+  const FileSpec module_path_spec =
+      FindModuleFile(req_module_path_spec.GetPath(), arch);
+  const ModuleSpec module_spec(module_path_spec, arch);
+
+  ModuleSpecList module_specs;
+  if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0,
+                                           module_specs))
+    return SendErrorResponse(3);
+
+  ModuleSpec matched_module_spec;
+  if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
+    return SendErrorResponse(4);
+
+  const auto file_offset = matched_module_spec.GetObjectOffset();
+  const auto file_size = matched_module_spec.GetObjectSize();
+  const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
+
+  StreamGDBRemote response;
+
+  if (uuid_str.empty()) {
+    std::string md5_hash;
+    if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(),
+                                          file_offset, file_size, md5_hash))
+      return SendErrorResponse(5);
+    response.PutCString("md5:");
+    response.PutCStringAsRawHex8(md5_hash.c_str());
+  } else {
+    response.PutCString("uuid:");
+    response.PutCStringAsRawHex8(uuid_str.c_str());
+  }
+  response.PutChar(';');
+
+  const auto &module_arch = matched_module_spec.GetArchitecture();
+  response.PutCString("triple:");
+  response.PutCStringAsRawHex8(module_arch.GetTriple().getTriple().c_str());
+  response.PutChar(';');
+
+  response.PutCString("file_path:");
+  response.PutCStringAsRawHex8(module_path_spec.GetCString());
+  response.PutChar(';');
+  response.PutCString("file_offset:");
+  response.PutHex64(file_offset);
+  response.PutChar(';');
+  response.PutCString("file_size:");
+  response.PutHex64(file_size);
+  response.PutChar(';');
+
+  return SendPacketNoLock(response.GetString());
+}
+
+void GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse(
+    const ProcessInstanceInfo &proc_info, StreamString &response) {
+  response.Printf(
+      "pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
+      proc_info.GetProcessID(), proc_info.GetParentProcessID(),
+      proc_info.GetUserID(), proc_info.GetGroupID(),
+      proc_info.GetEffectiveUserID(), proc_info.GetEffectiveGroupID());
+  response.PutCString("name:");
+  response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+  response.PutChar(';');
+  const ArchSpec &proc_arch = proc_info.GetArchitecture();
+  if (proc_arch.IsValid()) {
+    const llvm::Triple &proc_triple = proc_arch.GetTriple();
     response.PutCString("triple:");
-    response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str());
-    response.PutChar(';');
-
-    response.PutCString("file_path:");
-    response.PutCStringAsRawHex8(module_path_spec.GetCString());
-    response.PutChar(';');
-    response.PutCString("file_offset:");
-    response.PutHex64(file_offset);
-    response.PutChar(';');
-    response.PutCString("file_size:");
-    response.PutHex64(file_size);
-    response.PutChar(';');
-
-    return SendPacketNoLock(response.GetString());
-}
-
-void
-GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
-                                                    StreamString &response)
-{
-    response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
-                     proc_info.GetProcessID(),
-                     proc_info.GetParentProcessID(),
-                     proc_info.GetUserID(),
-                     proc_info.GetGroupID(),
-                     proc_info.GetEffectiveUserID(),
-                     proc_info.GetEffectiveGroupID());
-    response.PutCString ("name:");
-    response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString());
+    response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
     response.PutChar(';');
-    const ArchSpec &proc_arch = proc_info.GetArchitecture();
-    if (proc_arch.IsValid())
-    {
-        const llvm::Triple &proc_triple = proc_arch.GetTriple();
-        response.PutCString("triple:");
-        response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
-        response.PutChar(';');
-    }
+  }
 }
 
-void
-GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse_DebugServerStyle (
-    const ProcessInstanceInfo &proc_info, StreamString &response)
-{
-    response.Printf ("pid:%" PRIx64 ";parent-pid:%" PRIx64 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
-                     proc_info.GetProcessID(),
-                     proc_info.GetParentProcessID(),
-                     proc_info.GetUserID(),
-                     proc_info.GetGroupID(),
-                     proc_info.GetEffectiveUserID(),
-                     proc_info.GetEffectiveGroupID());
-
-    const ArchSpec &proc_arch = proc_info.GetArchitecture();
-    if (proc_arch.IsValid())
-    {
-        const llvm::Triple &proc_triple = proc_arch.GetTriple();
+void GDBRemoteCommunicationServerCommon::
+    CreateProcessInfoResponse_DebugServerStyle(
+        const ProcessInstanceInfo &proc_info, StreamString &response) {
+  response.Printf("pid:%" PRIx64 ";parent-pid:%" PRIx64
+                  ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;",
+                  proc_info.GetProcessID(), proc_info.GetParentProcessID(),
+                  proc_info.GetUserID(), proc_info.GetGroupID(),
+                  proc_info.GetEffectiveUserID(),
+                  proc_info.GetEffectiveGroupID());
+
+  const ArchSpec &proc_arch = proc_info.GetArchitecture();
+  if (proc_arch.IsValid()) {
+    const llvm::Triple &proc_triple = proc_arch.GetTriple();
 #if defined(__APPLE__)
-        // We'll send cputype/cpusubtype.
-        const uint32_t cpu_type = proc_arch.GetMachOCPUType();
-        if (cpu_type != 0)
-            response.Printf ("cputype:%" PRIx32 ";", cpu_type);
-
-        const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
-        if (cpu_subtype != 0)
-            response.Printf ("cpusubtype:%" PRIx32 ";", cpu_subtype);
-
-        const std::string vendor = proc_triple.getVendorName ();
-        if (!vendor.empty ())
-            response.Printf ("vendor:%s;", vendor.c_str ());
+    // We'll send cputype/cpusubtype.
+    const uint32_t cpu_type = proc_arch.GetMachOCPUType();
+    if (cpu_type != 0)
+      response.Printf("cputype:%" PRIx32 ";", cpu_type);
+
+    const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType();
+    if (cpu_subtype != 0)
+      response.Printf("cpusubtype:%" PRIx32 ";", cpu_subtype);
+
+    const std::string vendor = proc_triple.getVendorName();
+    if (!vendor.empty())
+      response.Printf("vendor:%s;", vendor.c_str());
 #else
-        // We'll send the triple.
-        response.PutCString("triple:");
-        response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
-        response.PutChar(';');
+    // We'll send the triple.
+    response.PutCString("triple:");
+    response.PutCStringAsRawHex8(proc_triple.getTriple().c_str());
+    response.PutChar(';');
 #endif
-        std::string ostype = proc_triple.getOSName ();
-        // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
-        if (proc_triple.getVendor () == llvm::Triple::Apple)
-        {
-            switch (proc_triple.getArch ())
-            {
-                case llvm::Triple::arm:
-                case llvm::Triple::thumb:
-                case llvm::Triple::aarch64:
-                    ostype = "ios";
-                    break;
-                default:
-                    // No change.
-                    break;
-            }
-        }
-        response.Printf ("ostype:%s;", ostype.c_str ());
-
-
-        switch (proc_arch.GetByteOrder ())
-        {
-            case lldb::eByteOrderLittle: response.PutCString ("endian:little;"); break;
-            case lldb::eByteOrderBig:    response.PutCString ("endian:big;");    break;
-            case lldb::eByteOrderPDP:    response.PutCString ("endian:pdp;");    break;
-            default:
-                // Nothing.
-                break;
-        }
-
-        if (proc_triple.isArch64Bit ())
-            response.PutCString ("ptrsize:8;");
-        else if (proc_triple.isArch32Bit ())
-            response.PutCString ("ptrsize:4;");
-        else if (proc_triple.isArch16Bit ())
-            response.PutCString ("ptrsize:2;");
-    }
+    std::string ostype = proc_triple.getOSName();
+    // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64.
+    if (proc_triple.getVendor() == llvm::Triple::Apple) {
+      switch (proc_triple.getArch()) {
+      case llvm::Triple::arm:
+      case llvm::Triple::thumb:
+      case llvm::Triple::aarch64:
+        ostype = "ios";
+        break;
+      default:
+        // No change.
+        break;
+      }
+    }
+    response.Printf("ostype:%s;", ostype.c_str());
+
+    switch (proc_arch.GetByteOrder()) {
+    case lldb::eByteOrderLittle:
+      response.PutCString("endian:little;");
+      break;
+    case lldb::eByteOrderBig:
+      response.PutCString("endian:big;");
+      break;
+    case lldb::eByteOrderPDP:
+      response.PutCString("endian:pdp;");
+      break;
+    default:
+      // Nothing.
+      break;
+    }
+
+    if (proc_triple.isArch64Bit())
+      response.PutCString("ptrsize:8;");
+    else if (proc_triple.isArch32Bit())
+      response.PutCString("ptrsize:4;");
+    else if (proc_triple.isArch16Bit())
+      response.PutCString("ptrsize:2;");
+  }
 }
 
-FileSpec
-GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path,
-                                                   const ArchSpec& arch)
-{
+FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
+    const std::string &module_path, const ArchSpec &arch) {
 #ifdef __ANDROID__
-    return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
+  return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
 #else
-    return FileSpec(module_path.c_str(), true);
+  return FileSpec(module_path.c_str(), true);
 #endif
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h Tue Sep  6 15:57:50 2016
@@ -16,8 +16,8 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-private-forward.h"
 #include "lldb/Target/Process.h"
+#include "lldb/lldb-private-forward.h"
 
 #include "GDBRemoteCommunicationServer.h"
 #include "GDBRemoteCommunicationServerCommon.h"
@@ -29,169 +29,126 @@ namespace process_gdb_remote {
 
 class ProcessGDBRemote;
 
-class GDBRemoteCommunicationServerCommon :
-    public GDBRemoteCommunicationServer
-{
+class GDBRemoteCommunicationServerCommon : public GDBRemoteCommunicationServer {
 public:
-    GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name);
+  GDBRemoteCommunicationServerCommon(const char *comm_name,
+                                     const char *listener_name);
 
-    ~GDBRemoteCommunicationServerCommon() override;
+  ~GDBRemoteCommunicationServerCommon() override;
 
 protected:
-    ProcessLaunchInfo m_process_launch_info;
-    Error m_process_launch_error;
-    ProcessInstanceInfoList m_proc_infos;
-    uint32_t m_proc_infos_index;
-    bool m_thread_suffix_supported;
-    bool m_list_threads_in_stop_reply;
+  ProcessLaunchInfo m_process_launch_info;
+  Error m_process_launch_error;
+  ProcessInstanceInfoList m_proc_infos;
+  uint32_t m_proc_infos_index;
+  bool m_thread_suffix_supported;
+  bool m_list_threads_in_stop_reply;
 
-    PacketResult
-    Handle_A (StringExtractorGDBRemote &packet);
+  PacketResult Handle_A(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qHostInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qHostInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qProcessInfoPID(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qfProcessInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qsProcessInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qUserName (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qUserName(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qGroupName (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qGroupName(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qSpeedTest (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qSpeedTest(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_Open (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_Open(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_Close (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_Close(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_pRead (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_pRead(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_pWrite(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_Size (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_Size(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_Mode (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_Mode(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_Exists (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_Exists(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_symlink (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_symlink(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_unlink (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_unlink(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_Stat (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_Stat(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vFile_MD5(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qEcho (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qEcho(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qModuleInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qModuleInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qPlatform_shell(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qPlatform_mkdir(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qPlatform_chmod(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qSupported (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qSupported(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QThreadSuffixSupported(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QListThreadsInStopReply(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetDetachOnError (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetDetachOnError(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QStartNoAckMode(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetSTDIN(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetSTDOUT(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetSTDERR(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qLaunchSuccess(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QEnvironment (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QEnvironment(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QEnvironmentHexEncoded(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QLaunchArch (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QLaunchArch(StringExtractorGDBRemote &packet);
 
-    static void
-    CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info,
-                               StreamString &response);
+  static void CreateProcessInfoResponse(const ProcessInstanceInfo &proc_info,
+                                        StreamString &response);
 
-    static void
-    CreateProcessInfoResponse_DebugServerStyle (const ProcessInstanceInfo &proc_info,
-                                                StreamString &response);
+  static void CreateProcessInfoResponse_DebugServerStyle(
+      const ProcessInstanceInfo &proc_info, StreamString &response);
 
-    template <typename T>
-    void
-    RegisterMemberFunctionHandler (StringExtractorGDBRemote::ServerPacketType packet_type,
-                                   PacketResult (T::*handler) (StringExtractorGDBRemote& packet))
-    {
-        RegisterPacketHandler(packet_type,
-                              [this, handler] (StringExtractorGDBRemote packet,
-                                               Error &error,
-                                               bool &interrupt,
-                                               bool &quit)
-                              {
-                                  return (static_cast<T*>(this)->*handler) (packet);
-                              });
-    }
+  template <typename T>
+  void RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::ServerPacketType packet_type,
+      PacketResult (T::*handler)(StringExtractorGDBRemote &packet)) {
+    RegisterPacketHandler(packet_type,
+                          [this, handler](StringExtractorGDBRemote packet,
+                                          Error &error, bool &interrupt,
+                                          bool &quit) {
+                            return (static_cast<T *>(this)->*handler)(packet);
+                          });
+  }
 
-    //------------------------------------------------------------------
-    /// Launch a process with the current launch settings.
-    ///
-    /// This method supports running an lldb-gdbserver or similar
-    /// server in a situation where the startup code has been provided
-    /// with all the information for a child process to be launched.
-    ///
-    /// @return
-    ///     An Error object indicating the success or failure of the
-    ///     launch.
-    //------------------------------------------------------------------
-    virtual Error
-    LaunchProcess () = 0;
+  //------------------------------------------------------------------
+  /// Launch a process with the current launch settings.
+  ///
+  /// This method supports running an lldb-gdbserver or similar
+  /// server in a situation where the startup code has been provided
+  /// with all the information for a child process to be launched.
+  ///
+  /// @return
+  ///     An Error object indicating the success or failure of the
+  ///     launch.
+  //------------------------------------------------------------------
+  virtual Error LaunchProcess() = 0;
 
-    virtual FileSpec
-    FindModuleFile (const std::string& module_path, const ArchSpec& arch);
+  virtual FileSpec FindModuleFile(const std::string &module_path,
+                                  const ArchSpec &arch);
 };
 
 } // namespace process_gdb_remote

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Tue Sep  6 15:57:50 2016
@@ -16,8 +16,8 @@
 
 // C Includes
 // C++ Includes
-#include <cstring>
 #include <chrono>
+#include <cstring>
 #include <thread>
 
 // Other libraries and framework includes
@@ -47,10 +47,10 @@
 #include "llvm/Support/ScopedPrinter.h"
 
 // Project includes
-#include "Utility/StringExtractorGDBRemote.h"
-#include "Utility/UriParser.h"
 #include "ProcessGDBRemote.h"
 #include "ProcessGDBRemoteLog.h"
+#include "Utility/StringExtractorGDBRemote.h"
+#include "Utility/UriParser.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -61,2940 +61,3107 @@ using namespace llvm;
 // GDBRemote Errors
 //----------------------------------------------------------------------
 
-namespace
-{
-    enum GDBRemoteServerError
-    {
-        // Set to the first unused error number in literal form below
-        eErrorFirst = 29,
-        eErrorNoProcess = eErrorFirst,
-        eErrorResume,
-        eErrorExitStatus
-    };
+namespace {
+enum GDBRemoteServerError {
+  // Set to the first unused error number in literal form below
+  eErrorFirst = 29,
+  eErrorNoProcess = eErrorFirst,
+  eErrorResume,
+  eErrorExitStatus
+};
 }
 
 //----------------------------------------------------------------------
 // GDBRemoteCommunicationServerLLGS constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(MainLoop &mainloop)
-    : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
-      m_mainloop(mainloop),
-      m_current_tid(LLDB_INVALID_THREAD_ID),
-      m_continue_tid(LLDB_INVALID_THREAD_ID),
-      m_debugged_process_mutex(),
-      m_debugged_process_sp(),
-      m_stdio_communication("process.stdio"),
+GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
+    MainLoop &mainloop)
+    : GDBRemoteCommunicationServerCommon("gdb-remote.server",
+                                         "gdb-remote.server.rx_packet"),
+      m_mainloop(mainloop), m_current_tid(LLDB_INVALID_THREAD_ID),
+      m_continue_tid(LLDB_INVALID_THREAD_ID), m_debugged_process_mutex(),
+      m_debugged_process_sp(), m_stdio_communication("process.stdio"),
       m_inferior_prev_state(StateType::eStateInvalid),
-      m_active_auxv_buffer_sp(),
-      m_saved_registers_mutex(),
-      m_saved_registers_map(),
-      m_next_saved_registers_id(1),
-      m_handshake_completed(false)
-{
-    RegisterPacketHandlers();
-}
-
-void
-GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers()
-{
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_C);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_c);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_D);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_H);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_I);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_m,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_M);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_p);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_P);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qC);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_s);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_stop_reason,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vAttach,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_vCont);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vCont_actions,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_x,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_Z);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
-                                  &GDBRemoteCommunicationServerLLGS::Handle_z);
-
-    RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
-                          [this](StringExtractorGDBRemote packet,
-                                 Error &error,
-                                 bool &interrupt,
-                                 bool &quit)
-                          {
-                              quit = true;
-                              return this->Handle_k (packet);
-                          });
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetLaunchArguments (const char *const args[], int argc)
-{
-    if ((argc < 1) || !args || !args[0] || !args[0][0])
-        return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
-    m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
-    return Error ();
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::SetLaunchFlags (unsigned int launch_flags)
-{
-    m_process_launch_info.GetFlags ().Set (launch_flags);
-    return Error ();
-}
-
-Error
-GDBRemoteCommunicationServerLLGS::LaunchProcess ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
-        return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
-    const bool should_forward_stdio = m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
-                                      m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
-                                      m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr;
-    m_process_launch_info.SetLaunchInSeparateProcessGroup(true);
-    m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
-
-    const bool default_to_use_pty = true;
-    m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
-
-    Error error;
-    {
-        std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
-        assert (!m_debugged_process_sp && "lldb-server creating debugged "
-                "process but one already exists");
-        error = NativeProcessProtocol::Launch(
-            m_process_launch_info,
-            *this,
-            m_mainloop,
-            m_debugged_process_sp);
-    }
+      m_active_auxv_buffer_sp(), m_saved_registers_mutex(),
+      m_saved_registers_map(), m_next_saved_registers_id(1),
+      m_handshake_completed(false) {
+  RegisterPacketHandlers();
+}
+
+void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_C,
+                                &GDBRemoteCommunicationServerLLGS::Handle_C);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_c,
+                                &GDBRemoteCommunicationServerLLGS::Handle_c);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_D,
+                                &GDBRemoteCommunicationServerLLGS::Handle_D);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_H,
+                                &GDBRemoteCommunicationServerLLGS::Handle_H);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_I,
+                                &GDBRemoteCommunicationServerLLGS::Handle_I);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_interrupt,
+      &GDBRemoteCommunicationServerLLGS::Handle_interrupt);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_m,
+      &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_M,
+                                &GDBRemoteCommunicationServerLLGS::Handle_M);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_p,
+                                &GDBRemoteCommunicationServerLLGS::Handle_p);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_P,
+                                &GDBRemoteCommunicationServerLLGS::Handle_P);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
+                                &GDBRemoteCommunicationServerLLGS::Handle_qC);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
+      &GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
+      &GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfoSupported,
+      &GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qRegisterInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QRestoreRegisterState,
+      &GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSaveRegisterState,
+      &GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR,
+      &GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
+      &GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qThreadStopInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_jThreadsInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qWatchpointSupportInfo,
+      &GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qXfer_auxv_read,
+      &GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_s,
+                                &GDBRemoteCommunicationServerLLGS::Handle_s);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_stop_reason,
+      &GDBRemoteCommunicationServerLLGS::Handle_stop_reason); // ?
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vAttach,
+      &GDBRemoteCommunicationServerLLGS::Handle_vAttach);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vCont,
+      &GDBRemoteCommunicationServerLLGS::Handle_vCont);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_vCont_actions,
+      &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_x,
+      &GDBRemoteCommunicationServerLLGS::Handle_memory_read);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z,
+                                &GDBRemoteCommunicationServerLLGS::Handle_Z);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_z,
+                                &GDBRemoteCommunicationServerLLGS::Handle_z);
+
+  RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
+                        [this](StringExtractorGDBRemote packet, Error &error,
+                               bool &interrupt, bool &quit) {
+                          quit = true;
+                          return this->Handle_k(packet);
+                        });
+}
+
+Error GDBRemoteCommunicationServerLLGS::SetLaunchArguments(
+    const char *const args[], int argc) {
+  if ((argc < 1) || !args || !args[0] || !args[0][0])
+    return Error("%s: no process command line specified to launch",
+                 __FUNCTION__);
+
+  m_process_launch_info.SetArguments(const_cast<const char **>(args), true);
+  return Error();
+}
+
+Error GDBRemoteCommunicationServerLLGS::SetLaunchFlags(
+    unsigned int launch_flags) {
+  m_process_launch_info.GetFlags().Set(launch_flags);
+  return Error();
+}
+
+Error GDBRemoteCommunicationServerLLGS::LaunchProcess() {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  if (!m_process_launch_info.GetArguments().GetArgumentCount())
+    return Error("%s: no process command line specified to launch",
+                 __FUNCTION__);
+
+  const bool should_forward_stdio =
+      m_process_launch_info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
+      m_process_launch_info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
+      m_process_launch_info.GetFileActionForFD(STDERR_FILENO) == nullptr;
+  m_process_launch_info.SetLaunchInSeparateProcessGroup(true);
+  m_process_launch_info.GetFlags().Set(eLaunchFlagDebug);
+
+  const bool default_to_use_pty = true;
+  m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
+
+  Error error;
+  {
+    std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
+    assert(!m_debugged_process_sp && "lldb-server creating debugged "
+                                     "process but one already exists");
+    error = NativeProcessProtocol::Launch(m_process_launch_info, *this,
+                                          m_mainloop, m_debugged_process_sp);
+  }
+
+  if (!error.Success()) {
+    fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+            m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
+    return error;
+  }
 
-    if (!error.Success ())
-    {
-        fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
+  // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
+  // as needed.
+  // llgs local-process debugging may specify PTY paths, which will make these
+  // file actions non-null
+  // process launch -i/e/o will also make these file actions non-null
+  // nullptr means that the traffic is expected to flow over gdb-remote protocol
+  if (should_forward_stdio) {
+    // nullptr means it's not redirected to file or pty (in case of LLGS local)
+    // at least one of stdio will be transferred pty<->gdb-remote
+    // we need to give the pty master handle to this object to read and/or write
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+          " setting up stdout/stderr redirection via $O gdb-remote commands",
+          __FUNCTION__, m_debugged_process_sp->GetID());
+
+    // Setup stdout/stderr mapping from inferior to $O
+    auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+    if (terminal_fd >= 0) {
+      if (log)
+        log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+                    "inferior STDIO fd to %d",
+                    __FUNCTION__, terminal_fd);
+      error = SetSTDIOFileDescriptor(terminal_fd);
+      if (error.Fail())
         return error;
-    }
+    } else {
+      if (log)
+        log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+                    "inferior STDIO since terminal fd reported as %d",
+                    __FUNCTION__, terminal_fd);
+    }
+  } else {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " skipping stdout/stderr redirection via $O: inferior will "
+                  "communicate over client-provided file descriptors",
+                  __FUNCTION__, m_debugged_process_sp->GetID());
+  }
+
+  printf("Launched '%s' as process %" PRIu64 "...\n",
+         m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+         m_process_launch_info.GetProcessID());
+
+  return error;
+}
+
+Error GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
+  Error error;
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
+                __FUNCTION__, pid);
+
+  // Before we try to attach, make sure we aren't already monitoring something
+  // else.
+  if (m_debugged_process_sp &&
+      m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
+    return Error("cannot attach to a process %" PRIu64
+                 " when another process with pid %" PRIu64
+                 " is being debugged.",
+                 pid, m_debugged_process_sp->GetID());
+
+  // Try to attach.
+  error = NativeProcessProtocol::Attach(pid, *this, m_mainloop,
+                                        m_debugged_process_sp);
+  if (!error.Success()) {
+    fprintf(stderr, "%s: failed to attach to process %" PRIu64 ": %s",
+            __FUNCTION__, pid, error.AsCString());
+    return error;
+  }
 
-    // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
-    // as needed.
-    // llgs local-process debugging may specify PTY paths, which will make these
-    // file actions non-null
-    // process launch -i/e/o will also make these file actions non-null
-    // nullptr means that the traffic is expected to flow over gdb-remote protocol
-    if (should_forward_stdio)
-    {
-        // nullptr means it's not redirected to file or pty (in case of LLGS local)
-        // at least one of stdio will be transferred pty<->gdb-remote
-        // we need to give the pty master handle to this object to read and/or write
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " setting up stdout/stderr redirection via $O gdb-remote commands", __FUNCTION__, m_debugged_process_sp->GetID ());
+  // Setup stdout/stderr mapping from inferior.
+  auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+  if (terminal_fd >= 0) {
+    if (log)
+      log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
+                  "inferior STDIO fd to %d",
+                  __FUNCTION__, terminal_fd);
+    error = SetSTDIOFileDescriptor(terminal_fd);
+    if (error.Fail())
+      return error;
+  } else {
+    if (log)
+      log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
+                  "inferior STDIO since terminal fd reported as %d",
+                  __FUNCTION__, terminal_fd);
+  }
 
-        // Setup stdout/stderr mapping from inferior to $O
-        auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
-        if (terminal_fd >= 0)
-        {
-            if (log)
-                log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
-            error = SetSTDIOFileDescriptor (terminal_fd);
-            if (error.Fail ())
-                return error;
-        }
-        else
-        {
-            if (log)
-                log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
-        }
-    }
-    else
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " skipping stdout/stderr redirection via $O: inferior will communicate over client-provided file descriptors", __FUNCTION__, m_debugged_process_sp->GetID ());
-    }
+  printf("Attached to process %" PRIu64 "...\n", pid);
 
-    printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID ());
+  return error;
+}
 
-    return error;
+void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
+    NativeProcessProtocol *process) {
+  assert(process && "process cannot be NULL");
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log) {
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
+                "NativeProcessProtocol pid %" PRIu64 ", current state: %s",
+                __FUNCTION__, process->GetID(),
+                StateAsCString(process->GetState()));
+  }
 }
 
-Error
-GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid)
-{
-    Error error;
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendWResponse(
+    NativeProcessProtocol *process) {
+  assert(process && "process cannot be NULL");
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+  // send W notification
+  ExitType exit_type = ExitType::eExitTypeInvalid;
+  int return_code = 0;
+  std::string exit_description;
+
+  const bool got_exit_info =
+      process->GetExitStatus(&exit_type, &return_code, exit_description);
+  if (!got_exit_info) {
     if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64, __FUNCTION__, pid);
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  ", failed to retrieve process exit status",
+                  __FUNCTION__, process->GetID());
 
-    // Before we try to attach, make sure we aren't already monitoring something else.
-    if (m_debugged_process_sp  && m_debugged_process_sp->GetID() != LLDB_INVALID_PROCESS_ID)
-        return Error("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, m_debugged_process_sp->GetID());
-
-    // Try to attach.
-    error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp);
-    if (!error.Success ())
-    {
-        fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ());
-        return error;
-    }
+    StreamGDBRemote response;
+    response.PutChar('E');
+    response.PutHex8(GDBRemoteServerError::eErrorExitStatus);
+    return SendPacketNoLock(response.GetString());
+  } else {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  ", returning exit type %d, return code %d [%s]",
+                  __FUNCTION__, process->GetID(), exit_type, return_code,
+                  exit_description.c_str());
 
-    // Setup stdout/stderr mapping from inferior.
-    auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor ();
-    if (terminal_fd >= 0)
-    {
-        if (log)
-            log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s setting inferior STDIO fd to %d", __FUNCTION__, terminal_fd);
-        error = SetSTDIOFileDescriptor (terminal_fd);
-        if (error.Fail ())
-            return error;
-    }
-    else
-    {
-        if (log)
-            log->Printf ("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring inferior STDIO since terminal fd reported as %d", __FUNCTION__, terminal_fd);
+    StreamGDBRemote response;
+
+    char return_type_code;
+    switch (exit_type) {
+    case ExitType::eExitTypeExit:
+      return_type_code = 'W';
+      break;
+    case ExitType::eExitTypeSignal:
+      return_type_code = 'X';
+      break;
+    case ExitType::eExitTypeStop:
+      return_type_code = 'S';
+      break;
+    case ExitType::eExitTypeInvalid:
+      return_type_code = 'E';
+      break;
     }
+    response.PutChar(return_type_code);
 
-    printf ("Attached to process %" PRIu64 "...\n", pid);
+    // POSIX exit status limited to unsigned 8 bits.
+    response.PutHex8(return_code);
 
-    return error;
+    return SendPacketNoLock(response.GetString());
+  }
 }
 
-void
-GDBRemoteCommunicationServerLLGS::InitializeDelegate (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    if (log)
-    {
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", current state: %s",
-                __FUNCTION__,
-                process->GetID (),
-                StateAsCString (process->GetState ()));
-    }
-}
+static void AppendHexValue(StreamString &response, const uint8_t *buf,
+                           uint32_t buf_size, bool swap) {
+  int64_t i;
+  if (swap) {
+    for (i = buf_size - 1; i >= 0; i--)
+      response.PutHex8(buf[i]);
+  } else {
+    for (i = 0; i < buf_size; i++)
+      response.PutHex8(buf[i]);
+  }
+}
+
+static void WriteRegisterValueInHexFixedWidth(
+    StreamString &response, NativeRegisterContextSP &reg_ctx_sp,
+    const RegisterInfo &reg_info, const RegisterValue *reg_value_p) {
+  RegisterValue reg_value;
+  if (!reg_value_p) {
+    Error error = reg_ctx_sp->ReadRegister(&reg_info, reg_value);
+    if (error.Success())
+      reg_value_p = &reg_value;
+    // else log.
+  }
+
+  if (reg_value_p) {
+    AppendHexValue(response, (const uint8_t *)reg_value_p->GetBytes(),
+                   reg_value_p->GetByteSize(), false);
+  } else {
+    // Zero-out any unreadable values.
+    if (reg_info.byte_size > 0) {
+      std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
+      AppendHexValue(response, zeros.data(), zeros.size(), false);
+    }
+  }
+}
+
+static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread,
+                                         bool abridged) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendWResponse (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+  if (!reg_ctx_sp)
+    return nullptr;
 
-    // send W notification
-    ExitType exit_type = ExitType::eExitTypeInvalid;
-    int return_code = 0;
-    std::string exit_description;
+  JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
 
-    const bool got_exit_info = process->GetExitStatus (&exit_type, &return_code, exit_description);
-    if (!got_exit_info)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", failed to retrieve process exit status", __FUNCTION__, process->GetID ());
+#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
+  // Expedite all registers in the first register set (i.e. should be GPRs) that
+  // are not contained in other registers.
+  const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
+  if (!reg_set_p)
+    return nullptr;
+  for (const uint32_t *reg_num_p = reg_set_p->registers;
+       *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+    uint32_t reg_num = *reg_num_p;
+#else
+  // Expedite only a couple of registers until we figure out why sending
+  // registers is
+  // expensive.
+  static const uint32_t k_expedited_registers[] = {
+      LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP,
+      LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM};
+  static const uint32_t k_abridged_expedited_registers[] = {
+      LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM};
+
+  for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers
+                                                : k_expedited_registers;
+       *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) {
+    uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+        eRegisterKindGeneric, *generic_reg_p);
+    if (reg_num == LLDB_INVALID_REGNUM)
+      continue; // Target does not support the given register.
+#endif
 
-        StreamGDBRemote response;
-        response.PutChar ('E');
-        response.PutHex8 (GDBRemoteServerError::eErrorExitStatus);
-        return SendPacketNoLock(response.GetString());
+    const RegisterInfo *const reg_info_p =
+        reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+    if (reg_info_p == nullptr) {
+      if (log)
+        log->Printf(
+            "%s failed to get register info for register index %" PRIu32,
+            __FUNCTION__, reg_num);
+      continue;
     }
-    else
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", returning exit type %d, return code %d [%s]", __FUNCTION__, process->GetID (), exit_type, return_code, exit_description.c_str ());
 
-        StreamGDBRemote response;
+    if (reg_info_p->value_regs != nullptr)
+      continue; // Only expedite registers that are not contained in other
+                // registers.
 
-        char return_type_code;
-        switch (exit_type)
-        {
-            case ExitType::eExitTypeExit:
-                return_type_code = 'W';
-                break;
-            case ExitType::eExitTypeSignal:
-                return_type_code = 'X';
-                break;
-            case ExitType::eExitTypeStop:
-                return_type_code = 'S';
-                break;
-            case ExitType::eExitTypeInvalid:
-                return_type_code = 'E';
-                break;
-        }
-        response.PutChar (return_type_code);
+    RegisterValue reg_value;
+    Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+    if (error.Fail()) {
+      if (log)
+        log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s",
+                    __FUNCTION__,
+                    reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+                    reg_num, error.AsCString());
+      continue;
+    }
+
+    StreamString stream;
+    WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p,
+                                      &reg_value);
+
+    register_object_sp->SetObject(
+        llvm::to_string(reg_num),
+        std::make_shared<JSONString>(stream.GetString()));
+  }
+
+  return register_object_sp;
+}
+
+static const char *GetStopReasonString(StopReason stop_reason) {
+  switch (stop_reason) {
+  case eStopReasonTrace:
+    return "trace";
+  case eStopReasonBreakpoint:
+    return "breakpoint";
+  case eStopReasonWatchpoint:
+    return "watchpoint";
+  case eStopReasonSignal:
+    return "signal";
+  case eStopReasonException:
+    return "exception";
+  case eStopReasonExec:
+    return "exec";
+  case eStopReasonInstrumentation:
+  case eStopReasonInvalid:
+  case eStopReasonPlanComplete:
+  case eStopReasonThreadExiting:
+  case eStopReasonNone:
+    break; // ignored
+  }
+  return nullptr;
+}
+
+static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
+                                        bool abridged) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+  JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
+
+  // Ensure we can get info on the given thread.
+  uint32_t thread_idx = 0;
+  for (NativeThreadProtocolSP thread_sp;
+       (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
+       ++thread_idx) {
 
-        // POSIX exit status limited to unsigned 8 bits.
-        response.PutHex8 (return_code);
+    lldb::tid_t tid = thread_sp->GetID();
 
-        return SendPacketNoLock(response.GetString());
-    }
-}
+    // Grab the reason this thread stopped.
+    struct ThreadStopInfo tid_stop_info;
+    std::string description;
+    if (!thread_sp->GetStopReason(tid_stop_info, description))
+      return nullptr;
 
-static void
-AppendHexValue (StreamString &response, const uint8_t* buf, uint32_t buf_size, bool swap)
-{
-    int64_t i;
-    if (swap)
-    {
-        for (i = buf_size-1; i >= 0; i--)
-            response.PutHex8 (buf[i]);
-    }
-    else
-    {
-        for (i = 0; i < buf_size; i++)
-            response.PutHex8 (buf[i]);
-    }
-}
+    const int signum = tid_stop_info.details.signal.signo;
+    if (log) {
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " tid %" PRIu64
+                  " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+                  __FUNCTION__, process.GetID(), tid, signum,
+                  tid_stop_info.reason, tid_stop_info.details.exception.type);
+    }
+
+    JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
+    threads_array_sp->AppendObject(thread_obj_sp);
+
+    if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
+      thread_obj_sp->SetObject("registers", registers_sp);
+
+    thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
+    if (signum != 0)
+      thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
+
+    const std::string thread_name = thread_sp->GetName();
+    if (!thread_name.empty())
+      thread_obj_sp->SetObject("name",
+                               std::make_shared<JSONString>(thread_name));
+
+    if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
+      thread_obj_sp->SetObject("reason",
+                               std::make_shared<JSONString>(stop_reason_str));
 
-static void
-WriteRegisterValueInHexFixedWidth (StreamString &response,
-                                   NativeRegisterContextSP &reg_ctx_sp,
-                                   const RegisterInfo &reg_info,
-                                   const RegisterValue *reg_value_p)
-{
-    RegisterValue reg_value;
-    if (!reg_value_p)
-    {
-        Error error = reg_ctx_sp->ReadRegister (&reg_info, reg_value);
-        if (error.Success ())
-            reg_value_p = &reg_value;
-        // else log.
-    }
+    if (!description.empty())
+      thread_obj_sp->SetObject("description",
+                               std::make_shared<JSONString>(description));
 
-    if (reg_value_p)
-    {
-        AppendHexValue (response, (const uint8_t*) reg_value_p->GetBytes (), reg_value_p->GetByteSize (), false);
-    }
-    else
-    {
-        // Zero-out any unreadable values.
-        if (reg_info.byte_size > 0)
-        {
-            std::basic_string<uint8_t> zeros(reg_info.byte_size, '\0');
-            AppendHexValue (response, zeros.data(), zeros.size(), false);
-        }
+    if ((tid_stop_info.reason == eStopReasonException) &&
+        tid_stop_info.details.exception.type) {
+      thread_obj_sp->SetObject(
+          "metype",
+          std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
+
+      JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
+      for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count;
+           ++i) {
+        medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
+            tid_stop_info.details.exception.data[i]));
+      }
+      thread_obj_sp->SetObject("medata", medata_array_sp);
+    }
+
+    // TODO: Expedite interesting regions of inferior memory
+  }
+
+  return threads_array_sp;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
+    lldb::tid_t tid) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+  // Ensure we have a debugged process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(50);
+
+  if (log)
+    log->Printf(
+        "GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64
+        " tid %" PRIu64,
+        __FUNCTION__, m_debugged_process_sp->GetID(), tid);
+
+  // Ensure we can get info on the given thread.
+  NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid));
+  if (!thread_sp)
+    return SendErrorResponse(51);
+
+  // Grab the reason this thread stopped.
+  struct ThreadStopInfo tid_stop_info;
+  std::string description;
+  if (!thread_sp->GetStopReason(tid_stop_info, description))
+    return SendErrorResponse(52);
+
+  // FIXME implement register handling for exec'd inferiors.
+  // if (tid_stop_info.reason == eStopReasonExec)
+  // {
+  //     const bool force = true;
+  //     InitializeRegisters(force);
+  // }
+
+  StreamString response;
+  // Output the T packet with the thread
+  response.PutChar('T');
+  int signum = tid_stop_info.details.signal.signo;
+  if (log) {
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                " tid %" PRIu64
+                " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
+                __FUNCTION__, m_debugged_process_sp->GetID(), tid, signum,
+                tid_stop_info.reason, tid_stop_info.details.exception.type);
+  }
+
+  // Print the signal number.
+  response.PutHex8(signum & 0xff);
+
+  // Include the tid.
+  response.Printf("thread:%" PRIx64 ";", tid);
+
+  // Include the thread name if there is one.
+  const std::string thread_name = thread_sp->GetName();
+  if (!thread_name.empty()) {
+    size_t thread_name_len = thread_name.length();
+
+    if (::strcspn(thread_name.c_str(), "$#+-;:") == thread_name_len) {
+      response.PutCString("name:");
+      response.PutCString(thread_name.c_str());
+    } else {
+      // The thread name contains special chars, send as hex bytes.
+      response.PutCString("hexname:");
+      response.PutCStringAsRawHex8(thread_name.c_str());
+    }
+    response.PutChar(';');
+  }
+
+  // If a 'QListThreadsInStopReply' was sent to enable this feature, we
+  // will send all thread IDs back in the "threads" key whose value is
+  // a list of hex thread IDs separated by commas:
+  //  "threads:10a,10b,10c;"
+  // This will save the debugger from having to send a pair of qfThreadInfo
+  // and qsThreadInfo packets, but it also might take a lot of room in the
+  // stop reply packet, so it must be enabled only on systems where there
+  // are no limits on packet lengths.
+  if (m_list_threads_in_stop_reply) {
+    response.PutCString("threads:");
+
+    uint32_t thread_index = 0;
+    NativeThreadProtocolSP listed_thread_sp;
+    for (listed_thread_sp =
+             m_debugged_process_sp->GetThreadAtIndex(thread_index);
+         listed_thread_sp; ++thread_index,
+        listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex(
+            thread_index)) {
+      if (thread_index > 0)
+        response.PutChar(',');
+      response.Printf("%" PRIx64, listed_thread_sp->GetID());
+    }
+    response.PutChar(';');
+
+    // Include JSON info that describes the stop reason for any threads
+    // that actually have stop reasons. We use the new "jstopinfo" key
+    // whose values is hex ascii JSON that contains the thread IDs
+    // thread stop info only for threads that have stop reasons. Only send
+    // this if we have more than one thread otherwise this packet has all
+    // the info it needs.
+    if (thread_index > 0) {
+      const bool threads_with_valid_stop_info_only = true;
+      JSONArray::SP threads_info_sp = GetJSONThreadsInfo(
+          *m_debugged_process_sp, threads_with_valid_stop_info_only);
+      if (threads_info_sp) {
+        response.PutCString("jstopinfo:");
+        StreamString unescaped_response;
+        threads_info_sp->Write(unescaped_response);
+        response.PutCStringAsRawHex8(unescaped_response.GetData());
+        response.PutChar(';');
+      } else if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a "
+                    "jstopinfo field for pid %" PRIu64,
+                    __FUNCTION__, m_debugged_process_sp->GetID());
     }
-}
+  }
 
-static JSONObject::SP
-GetRegistersAsJSON(NativeThreadProtocol &thread, bool abridged)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
-
-    NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext ();
-    if (! reg_ctx_sp)
-        return nullptr;
+  //
+  // Expedite registers.
+  //
+
+  // Grab the register context.
+  NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext();
+  if (reg_ctx_sp) {
+    // Expedite all registers in the first register set (i.e. should be GPRs)
+    // that are not contained in other registers.
+    const RegisterSet *reg_set_p;
+    if (reg_ctx_sp->GetRegisterSetCount() > 0 &&
+        ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers "
+                    "from set '%s' (registers set count: %zu)",
+                    __FUNCTION__,
+                    reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+                    reg_set_p->num_registers);
 
-    JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
+      for (const uint32_t *reg_num_p = reg_set_p->registers;
+           *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) {
+        const RegisterInfo *const reg_info_p =
+            reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p);
+        if (reg_info_p == nullptr) {
+          if (log)
+            log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get "
+                        "register info for register set '%s', register index "
+                        "%" PRIu32,
+                        __FUNCTION__,
+                        reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
+                        *reg_num_p);
+        } else if (reg_info_p->value_regs == nullptr) {
+          // Only expediate registers that are not contained in other registers.
+          RegisterValue reg_value;
+          Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
+          if (error.Success()) {
+            response.Printf("%.02x:", *reg_num_p);
+            WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p,
+                                              &reg_value);
+            response.PutChar(';');
+          } else {
+            if (log)
+              log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read "
+                          "register '%s' index %" PRIu32 ": %s",
+                          __FUNCTION__, reg_info_p->name ? reg_info_p->name
+                                                         : "<unnamed-register>",
+                          *reg_num_p, error.AsCString());
+          }
+        }
+      }
+    }
+  }
+
+  const char *reason_str = GetStopReasonString(tid_stop_info.reason);
+  if (reason_str != nullptr) {
+    response.Printf("reason:%s;", reason_str);
+  }
+
+  if (!description.empty()) {
+    // Description may contains special chars, send as hex bytes.
+    response.PutCString("description:");
+    response.PutCStringAsRawHex8(description.c_str());
+    response.PutChar(';');
+  } else if ((tid_stop_info.reason == eStopReasonException) &&
+             tid_stop_info.details.exception.type) {
+    response.PutCString("metype:");
+    response.PutHex64(tid_stop_info.details.exception.type);
+    response.PutCString(";mecount:");
+    response.PutHex32(tid_stop_info.details.exception.data_count);
+    response.PutChar(';');
+
+    for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i) {
+      response.PutCString("medata:");
+      response.PutHex64(tid_stop_info.details.exception.data[i]);
+      response.PutChar(';');
+    }
+  }
+
+  return SendPacketNoLock(response.GetString());
+}
+
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
+    NativeProcessProtocol *process) {
+  assert(process && "process cannot be NULL");
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+
+  PacketResult result = SendStopReasonForState(StateType::eStateExited);
+  if (result != PacketResult::Success) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+                  "notification for PID %" PRIu64 ", state: eStateExited",
+                  __FUNCTION__, process->GetID());
+  }
+
+  // Close the pipe to the inferior terminal i/o if we launched it
+  // and set one up.
+  MaybeCloseInferiorTerminalConnection();
+
+  // We are ready to exit the debug monitor.
+  m_exit_now = true;
+}
+
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
+    NativeProcessProtocol *process) {
+  assert(process && "process cannot be NULL");
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+
+  // Send the stop reason unless this is the stop after the
+  // launch or attach.
+  switch (m_inferior_prev_state) {
+  case eStateLaunching:
+  case eStateAttaching:
+    // Don't send anything per debugserver behavior.
+    break;
+  default:
+    // In all other cases, send the stop reason.
+    PacketResult result = SendStopReasonForState(StateType::eStateStopped);
+    if (result != PacketResult::Success) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+                    "notification for PID %" PRIu64 ", state: eStateExited",
+                    __FUNCTION__, process->GetID());
+    }
+    break;
+  }
+}
+
+void GDBRemoteCommunicationServerLLGS::ProcessStateChanged(
+    NativeProcessProtocol *process, lldb::StateType state) {
+  assert(process && "process cannot be NULL");
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log) {
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s called with "
+                "NativeProcessProtocol pid %" PRIu64 ", state: %s",
+                __FUNCTION__, process->GetID(), StateAsCString(state));
+  }
+
+  switch (state) {
+  case StateType::eStateRunning:
+    StartSTDIOForwarding();
+    break;
+
+  case StateType::eStateStopped:
+    // Make sure we get all of the pending stdout/stderr from the inferior
+    // and send it to the lldb host before we send the state change
+    // notification
+    SendProcessOutput();
+    // Then stop the forwarding, so that any late output (see llvm.org/pr25652)
+    // does not
+    // interfere with our protocol.
+    StopSTDIOForwarding();
+    HandleInferiorState_Stopped(process);
+    break;
 
-#ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET
-    // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers.
-    const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0);
-    if (! reg_set_p)
-        return nullptr;
-    for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p)
-    {
-        uint32_t reg_num = *reg_num_p;
-#else
-    // Expedite only a couple of registers until we figure out why sending registers is
-    // expensive.
-    static const uint32_t k_expedited_registers[] = {
-        LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM
-    };
-    static const uint32_t k_abridged_expedited_registers[] = {
-        LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM
-    };
-
-    for (const uint32_t *generic_reg_p = abridged ? k_abridged_expedited_registers : k_expedited_registers;
-         *generic_reg_p != LLDB_INVALID_REGNUM;
-         ++generic_reg_p)
-    {
-        uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, *generic_reg_p);
-        if (reg_num == LLDB_INVALID_REGNUM)
-            continue; // Target does not support the given register.
-#endif
+  case StateType::eStateExited:
+    // Same as above
+    SendProcessOutput();
+    StopSTDIOForwarding();
+    HandleInferiorState_Exited(process);
+    break;
 
-        const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
-        if (reg_info_p == nullptr)
-        {
-            if (log)
-                log->Printf("%s failed to get register info for register index %" PRIu32,
-                        __FUNCTION__, reg_num);
-            continue;
-        }
+  default:
+    if (log) {
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state "
+                  "change for pid %" PRIu64 ", new state: %s",
+                  __FUNCTION__, process->GetID(), StateAsCString(state));
+    }
+    break;
+  }
+
+  // Remember the previous state reported to us.
+  m_inferior_prev_state = state;
+}
+
+void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) {
+  ClearProcessSpecificData();
+}
+
+void GDBRemoteCommunicationServerLLGS::DataAvailableCallback() {
+  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
+
+  if (!m_handshake_completed) {
+    if (!HandshakeWithClient()) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with "
+                    "client failed, exiting",
+                    __FUNCTION__);
+      m_mainloop.RequestTermination();
+      return;
+    }
+    m_handshake_completed = true;
+  }
+
+  bool interrupt = false;
+  bool done = false;
+  Error error;
+  while (true) {
+    const PacketResult result =
+        GetPacketAndSendResponse(0, error, interrupt, done);
+    if (result == PacketResult::ErrorReplyTimeout)
+      break; // No more packets in the queue
+
+    if ((result != PacketResult::Success)) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet "
+                    "failed: %s",
+                    __FUNCTION__, error.AsCString());
+      m_mainloop.RequestTermination();
+      break;
+    }
+  }
+}
+
+Error GDBRemoteCommunicationServerLLGS::InitializeConnection(
+    std::unique_ptr<Connection> &&connection) {
+  IOObjectSP read_object_sp = connection->GetReadObject();
+  GDBRemoteCommunicationServer::SetConnection(connection.release());
+
+  Error error;
+  m_network_handle_up = m_mainloop.RegisterReadObject(
+      read_object_sp, [this](MainLoopBase &) { DataAvailableCallback(); },
+      error);
+  return error;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer,
+                                                    uint32_t len) {
+  if ((buffer == nullptr) || (len == 0)) {
+    // Nothing to send.
+    return PacketResult::Success;
+  }
 
-        if (reg_info_p->value_regs != nullptr)
-            continue; // Only expedite registers that are not contained in other registers.
+  StreamString response;
+  response.PutChar('O');
+  response.PutBytesAsRawHex8(buffer, len);
 
-        RegisterValue reg_value;
-        Error error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value);
-        if (error.Fail())
-        {
-            if (log)
-                log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__,
-                        reg_info_p->name ? reg_info_p->name : "<unnamed-register>", reg_num,
-                        error.AsCString ());
-            continue;
-        }
+  return SendPacketNoLock(response.GetString());
+}
 
-        StreamString stream;
-        WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, &reg_value);
+Error GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor(int fd) {
+  Error error;
 
-        register_object_sp->SetObject(llvm::to_string(reg_num), std::make_shared<JSONString>(stream.GetString()));
-    }
+  // Set up the reading/handling of process I/O
+  std::unique_ptr<ConnectionFileDescriptor> conn_up(
+      new ConnectionFileDescriptor(fd, true));
+  if (!conn_up) {
+    error.SetErrorString("failed to create ConnectionFileDescriptor");
+    return error;
+  }
 
-    return register_object_sp;
-}
+  m_stdio_communication.SetCloseOnEOF(false);
+  m_stdio_communication.SetConnection(conn_up.release());
+  if (!m_stdio_communication.IsConnected()) {
+    error.SetErrorString(
+        "failed to set connection for inferior I/O communication");
+    return error;
+  }
 
-static const char *
-GetStopReasonString(StopReason stop_reason)
-{
-    switch (stop_reason)
-    {
-    case eStopReasonTrace:
-        return "trace";
-    case eStopReasonBreakpoint:
-        return "breakpoint";
-    case eStopReasonWatchpoint:
-        return "watchpoint";
-    case eStopReasonSignal:
-        return "signal";
-    case eStopReasonException:
-        return "exception";
-    case eStopReasonExec:
-        return "exec";
-    case eStopReasonInstrumentation:
-    case eStopReasonInvalid:
-    case eStopReasonPlanComplete:
-    case eStopReasonThreadExiting:
-    case eStopReasonNone:
-        break; // ignored
-    }
-    return nullptr;
+  return Error();
 }
 
-static JSONArray::SP
-GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
-    JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
-
-    // Ensure we can get info on the given thread.
-    uint32_t thread_idx = 0;
-    for ( NativeThreadProtocolSP thread_sp;
-          (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr;
-          ++thread_idx)
-    {
-
-        lldb::tid_t tid = thread_sp->GetID();
-
-        // Grab the reason this thread stopped.
-        struct ThreadStopInfo tid_stop_info;
-        std::string description;
-        if (!thread_sp->GetStopReason (tid_stop_info, description))
-            return nullptr;
+void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
+  // Don't forward if not connected (e.g. when attaching).
+  if (!m_stdio_communication.IsConnected())
+    return;
 
-        const int signum = tid_stop_info.details.signal.signo;
-        if (log)
-        {
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64,
-                    __FUNCTION__,
-                    process.GetID (),
-                    tid,
-                    signum,
-                    tid_stop_info.reason,
-                    tid_stop_info.details.exception.type);
-        }
+  Error error;
+  lldbassert(!m_stdio_handle_up);
+  m_stdio_handle_up = m_mainloop.RegisterReadObject(
+      m_stdio_communication.GetConnection()->GetReadObject(),
+      [this](MainLoopBase &) { SendProcessOutput(); }, error);
 
-        JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
-        threads_array_sp->AppendObject(thread_obj_sp);
+  if (!m_stdio_handle_up) {
+    // Not much we can do about the failure. Log it and continue without
+    // forwarding.
+    if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
+                  "forwarding: %s",
+                  __FUNCTION__, error.AsCString());
+  }
+}
 
-        if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
-            thread_obj_sp->SetObject("registers", registers_sp);
+void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() {
+  m_stdio_handle_up.reset();
+}
 
-        thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
-        if (signum != 0)
-            thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
-
-        const std::string thread_name = thread_sp->GetName ();
-        if (! thread_name.empty())
-            thread_obj_sp->SetObject("name", std::make_shared<JSONString>(thread_name));
-
-        if (const char *stop_reason_str = GetStopReasonString(tid_stop_info.reason))
-            thread_obj_sp->SetObject("reason", std::make_shared<JSONString>(stop_reason_str));
-
-        if (! description.empty())
-            thread_obj_sp->SetObject("description", std::make_shared<JSONString>(description));
-
-        if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
-        {
-            thread_obj_sp->SetObject("metype",
-                    std::make_shared<JSONNumber>(tid_stop_info.details.exception.type));
-
-            JSONArray::SP medata_array_sp = std::make_shared<JSONArray>();
-            for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
-            {
-                medata_array_sp->AppendObject(std::make_shared<JSONNumber>(
-                            tid_stop_info.details.exception.data[i]));
-            }
-            thread_obj_sp->SetObject("medata", medata_array_sp);
-        }
+void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
+  char buffer[1024];
+  ConnectionStatus status;
+  Error error;
+  while (true) {
+    size_t bytes_read =
+        m_stdio_communication.Read(buffer, sizeof buffer, 0, status, &error);
+    switch (status) {
+    case eConnectionStatusSuccess:
+      SendONotification(buffer, bytes_read);
+      break;
+    case eConnectionStatusLostConnection:
+    case eConnectionStatusEndOfFile:
+    case eConnectionStatusError:
+    case eConnectionStatusNoConnection:
+      if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio "
+                    "forwarding as communication returned status %d (error: "
+                    "%s)",
+                    __FUNCTION__, status, error.AsCString());
+      m_stdio_handle_up.reset();
+      return;
 
-        // TODO: Expedite interesting regions of inferior memory
+    case eConnectionStatusInterrupted:
+    case eConnectionStatusTimedOut:
+      return;
     }
-
-    return threads_array_sp;
+  }
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread (lldb::tid_t tid)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
+    StringExtractorGDBRemote &packet) {
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(68);
 
-    // Ensure we have a debugged process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (50);
+  lldb::pid_t pid = m_debugged_process_sp->GetID();
 
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64 " tid %" PRIu64,
-                __FUNCTION__, m_debugged_process_sp->GetID (), tid);
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(1);
 
-    // Ensure we can get info on the given thread.
-    NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
-    if (!thread_sp)
-        return SendErrorResponse (51);
+  ProcessInstanceInfo proc_info;
+  if (!Host::GetProcessInfo(pid, proc_info))
+    return SendErrorResponse(1);
 
-    // Grab the reason this thread stopped.
-    struct ThreadStopInfo tid_stop_info;
-    std::string description;
-    if (!thread_sp->GetStopReason (tid_stop_info, description))
-        return SendErrorResponse (52);
+  StreamString response;
+  CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+  return SendPacketNoLock(response.GetString());
+}
 
-    // FIXME implement register handling for exec'd inferiors.
-    // if (tid_stop_info.reason == eStopReasonExec)
-    // {
-    //     const bool force = true;
-    //     InitializeRegisters(force);
-    // }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) {
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(68);
 
-    StreamString response;
-    // Output the T packet with the thread
-    response.PutChar ('T');
-    int signum = tid_stop_info.details.signal.signo;
-    if (log)
-    {
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " got signal signo = %d, reason = %d, exc_type = %" PRIu64, 
-                __FUNCTION__,
-                m_debugged_process_sp->GetID (),
-                tid,
-                signum,
-                tid_stop_info.reason,
-                tid_stop_info.details.exception.type);
-    }
-
-    // Print the signal number.
-    response.PutHex8 (signum & 0xff);
-
-    // Include the tid.
-    response.Printf ("thread:%" PRIx64 ";", tid);
-
-    // Include the thread name if there is one.
-    const std::string thread_name = thread_sp->GetName ();
-    if (!thread_name.empty ())
-    {
-        size_t thread_name_len = thread_name.length ();
-
-        if (::strcspn (thread_name.c_str (), "$#+-;:") == thread_name_len)
-        {
-            response.PutCString ("name:");
-            response.PutCString (thread_name.c_str ());
-        }
-        else
-        {
-            // The thread name contains special chars, send as hex bytes.
-            response.PutCString ("hexname:");
-            response.PutCStringAsRawHex8 (thread_name.c_str ());
-        }
-        response.PutChar (';');
-    }
+  // Make sure we set the current thread so g and p packets return
+  // the data the gdb will expect.
+  lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID();
+  SetCurrentThreadID(tid);
 
-    // If a 'QListThreadsInStopReply' was sent to enable this feature, we
-    // will send all thread IDs back in the "threads" key whose value is
-    // a list of hex thread IDs separated by commas:
-    //  "threads:10a,10b,10c;"
-    // This will save the debugger from having to send a pair of qfThreadInfo
-    // and qsThreadInfo packets, but it also might take a lot of room in the
-    // stop reply packet, so it must be enabled only on systems where there
-    // are no limits on packet lengths.
-    if (m_list_threads_in_stop_reply)
-    {
-        response.PutCString ("threads:");
-
-        uint32_t thread_index = 0;
-        NativeThreadProtocolSP listed_thread_sp;
-        for (listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index); listed_thread_sp; ++thread_index, listed_thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index))
-        {
-            if (thread_index > 0)
-                response.PutChar (',');
-            response.Printf ("%" PRIx64, listed_thread_sp->GetID ());
-        }
-        response.PutChar (';');
+  NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread();
+  if (!thread_sp)
+    return SendErrorResponse(69);
 
-        // Include JSON info that describes the stop reason for any threads
-        // that actually have stop reasons. We use the new "jstopinfo" key
-        // whose values is hex ascii JSON that contains the thread IDs
-        // thread stop info only for threads that have stop reasons. Only send
-        // this if we have more than one thread otherwise this packet has all
-        // the info it needs.
-        if (thread_index > 0)
-        {
-            const bool threads_with_valid_stop_info_only = true;
-            JSONArray::SP threads_info_sp = GetJSONThreadsInfo(*m_debugged_process_sp,
-                                                               threads_with_valid_stop_info_only);
-            if (threads_info_sp)
-            {
-                response.PutCString("jstopinfo:");
-                StreamString unescaped_response;
-                threads_info_sp->Write(unescaped_response);
-                response.PutCStringAsRawHex8(unescaped_response.GetData());
-                response.PutChar(';');
-            }
-            else if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a jstopinfo field for pid %" PRIu64,
-                        __FUNCTION__, m_debugged_process_sp->GetID());
+  StreamString response;
+  response.Printf("QC%" PRIx64, thread_sp->GetID());
 
-        }
-    }
+  return SendPacketNoLock(response.GetString());
+}
 
-    //
-    // Expedite registers.
-    //
-
-    // Grab the register context.
-    NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext ();
-    if (reg_ctx_sp)
-    {
-        // Expedite all registers in the first register set (i.e. should be GPRs) that are not contained in other registers.
-        const RegisterSet *reg_set_p;
-        if (reg_ctx_sp->GetRegisterSetCount () > 0 && ((reg_set_p = reg_ctx_sp->GetRegisterSet (0)) != nullptr))
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s expediting registers from set '%s' (registers set count: %zu)", __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", reg_set_p->num_registers);
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-            for (const uint32_t *reg_num_p = reg_set_p->registers; *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p)
-            {
-                const RegisterInfo *const reg_info_p = reg_ctx_sp->GetRegisterInfoAtIndex (*reg_num_p);
-                if (reg_info_p == nullptr)
-                {
-                    if (log)
-                        log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get register info for register set '%s', register index %" PRIu32, __FUNCTION__, reg_set_p->name ? reg_set_p->name : "<unnamed-set>", *reg_num_p);
-                }
-                else if (reg_info_p->value_regs == nullptr)
-                {
-                    // Only expediate registers that are not contained in other registers.
-                    RegisterValue reg_value;
-                    Error error = reg_ctx_sp->ReadRegister (reg_info_p, reg_value);
-                    if (error.Success ())
-                    {
-                        response.Printf ("%.02x:", *reg_num_p);
-                        WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, &reg_value);
-                        response.PutChar (';');
-                    }
-                    else
-                    {
-                        if (log)
-                            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to read register '%s' index %" PRIu32 ": %s", __FUNCTION__, reg_info_p->name ? reg_info_p->name : "<unnamed-register>", *reg_num_p, error.AsCString ());
-
-                    }
-                }
-            }
-        }
-    }
+  StopSTDIOForwarding();
 
-    const char* reason_str = GetStopReasonString(tid_stop_info.reason);
-    if (reason_str != nullptr)
-    {
-        response.Printf ("reason:%s;", reason_str);
-    }
+  if (!m_debugged_process_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s No debugged process found.",
+          __FUNCTION__);
+    return PacketResult::Success;
+  }
 
-    if (!description.empty())
-    {
-        // Description may contains special chars, send as hex bytes.
-        response.PutCString ("description:");
-        response.PutCStringAsRawHex8 (description.c_str ());
-        response.PutChar (';');
-    }
-    else if ((tid_stop_info.reason == eStopReasonException) && tid_stop_info.details.exception.type)
-    {
-        response.PutCString ("metype:");
-        response.PutHex64 (tid_stop_info.details.exception.type);
-        response.PutCString (";mecount:");
-        response.PutHex32 (tid_stop_info.details.exception.data_count);
-        response.PutChar (';');
-
-        for (uint32_t i = 0; i < tid_stop_info.details.exception.data_count; ++i)
-        {
-            response.PutCString ("medata:");
-            response.PutHex64 (tid_stop_info.details.exception.data[i]);
-            response.PutChar (';');
-        }
-    }
+  Error error = m_debugged_process_sp->Kill();
+  if (error.Fail() && log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged "
+                "process %" PRIu64 ": %s",
+                __FUNCTION__, m_debugged_process_sp->GetID(),
+                error.AsCString());
 
-    return SendPacketNoLock (response.GetString());
+  // No OK response for kill packet.
+  // return SendOKResponse ();
+  return PacketResult::Success;
 }
 
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetDisableASLR:"));
+  if (packet.GetU32(0))
+    m_process_launch_info.GetFlags().Set(eLaunchFlagDisableASLR);
+  else
+    m_process_launch_info.GetFlags().Clear(eLaunchFlagDisableASLR);
+  return SendOKResponse();
+}
 
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetWorkingDir:"));
+  std::string path;
+  packet.GetHexByteString(path);
+  m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
+  return SendOKResponse();
+}
 
-    PacketResult result = SendStopReasonForState(StateType::eStateExited);
-    if (result != PacketResult::Success)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
-    }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir(
+    StringExtractorGDBRemote &packet) {
+  FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
+  if (working_dir) {
+    StreamString response;
+    response.PutCStringAsRawHex8(working_dir.GetCString());
+    return SendPacketNoLock(response.GetString());
+  }
 
-    // Close the pipe to the inferior terminal i/o if we launched it
-    // and set one up.
-    MaybeCloseInferiorTerminalConnection ();
-
-    // We are ready to exit the debug monitor.
-    m_exit_now = true;
-}
-
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
-
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
-    // Send the stop reason unless this is the stop after the
-    // launch or attach.
-    switch (m_inferior_prev_state)
-    {
-        case eStateLaunching:
-        case eStateAttaching:
-            // Don't send anything per debugserver behavior.
-            break;
-        default:
-            // In all other cases, send the stop reason.
-            PacketResult result = SendStopReasonForState(StateType::eStateStopped);
-            if (result != PacketResult::Success)
-            {
-                if (log)
-                    log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send stop notification for PID %" PRIu64 ", state: eStateExited", __FUNCTION__, process->GetID ());
-            }
-            break;
-    }
+  return SendErrorResponse(14);
 }
 
-void
-GDBRemoteCommunicationServerLLGS::ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state)
-{
-    assert (process && "process cannot be NULL");
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    if (log)
-    {
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", state: %s",
-                __FUNCTION__,
-                process->GetID (),
-                StateAsCString (state));
-    }
-
-    switch (state)
-    {
-    case StateType::eStateRunning:
-        StartSTDIOForwarding();
-        break;
-
-    case StateType::eStateStopped:
-        // Make sure we get all of the pending stdout/stderr from the inferior
-        // and send it to the lldb host before we send the state change
-        // notification
-        SendProcessOutput();
-        // Then stop the forwarding, so that any late output (see llvm.org/pr25652) does not
-        // interfere with our protocol.
-        StopSTDIOForwarding();
-        HandleInferiorState_Stopped (process);
-        break;
-
-    case StateType::eStateExited:
-        // Same as above
-        SendProcessOutput();
-        StopSTDIOForwarding();
-        HandleInferiorState_Exited (process);
-        break;
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+
+  // Ensure we have a native process.
+  if (!m_debugged_process_sp) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+                  "shared pointer",
+                  __FUNCTION__);
+    return SendErrorResponse(0x36);
+  }
+
+  // Pull out the signal number.
+  packet.SetFilePos(::strlen("C"));
+  if (packet.GetBytesLeft() < 1) {
+    // Shouldn't be using a C without a signal.
+    return SendIllFormedResponse(packet, "C packet specified without signal.");
+  }
+  const uint32_t signo =
+      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+  if (signo == std::numeric_limits<uint32_t>::max())
+    return SendIllFormedResponse(packet, "failed to parse signal number");
+
+  // Handle optional continue address.
+  if (packet.GetBytesLeft() > 0) {
+    // FIXME add continue at address support for $C{signo}[;{continue-address}].
+    if (*packet.Peek() == ';')
+      return SendUnimplementedResponse(packet.GetStringRef().c_str());
+    else
+      return SendIllFormedResponse(
+          packet, "unexpected content after $C{signal-number}");
+  }
+
+  ResumeActionList resume_actions(StateType::eStateRunning, 0);
+  Error error;
+
+  // We have two branches: what to do if a continue thread is specified (in
+  // which case we target
+  // sending the signal to that thread), or when we don't have a continue thread
+  // set (in which
+  // case we send a signal to the process).
+
+  // TODO discuss with Greg Clayton, make sure this makes sense.
+
+  lldb::tid_t signal_tid = GetContinueThreadID();
+  if (signal_tid != LLDB_INVALID_THREAD_ID) {
+    // The resume action for the continue thread (or all threads if a continue
+    // thread is not set).
+    ResumeAction action = {GetContinueThreadID(), StateType::eStateRunning,
+                           static_cast<int>(signo)};
+
+    // Add the action for the continue thread (or all threads when the continue
+    // thread isn't present).
+    resume_actions.Append(action);
+  } else {
+    // Send the signal to the process since we weren't targeting a specific
+    // continue thread with the signal.
+    error = m_debugged_process_sp->Signal(signo);
+    if (error.Fail()) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send "
+                    "signal for process %" PRIu64 ": %s",
+                    __FUNCTION__, m_debugged_process_sp->GetID(),
+                    error.AsCString());
+
+      return SendErrorResponse(0x52);
+    }
+  }
+
+  // Resume the threads.
+  error = m_debugged_process_sp->Resume(resume_actions);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to resume "
+                  "threads for process %" PRIu64 ": %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+
+    return SendErrorResponse(0x38);
+  }
+
+  // Don't send an "OK" packet; response is the stopped/exited message.
+  return PacketResult::Success;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_c(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
+
+  packet.SetFilePos(packet.GetFilePos() + ::strlen("c"));
+
+  // For now just support all continue.
+  const bool has_continue_address = (packet.GetBytesLeft() > 0);
+  if (has_continue_address) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s not implemented for "
+                  "c{address} variant [%s remains]",
+                  __FUNCTION__, packet.Peek());
+    return SendUnimplementedResponse(packet.GetStringRef().c_str());
+  }
+
+  // Ensure we have a native process.
+  if (!m_debugged_process_sp) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+                  "shared pointer",
+                  __FUNCTION__);
+    return SendErrorResponse(0x36);
+  }
+
+  // Build the ResumeActionList
+  ResumeActionList actions(StateType::eStateRunning, 0);
+
+  Error error = m_debugged_process_sp->Resume(actions);
+  if (error.Fail()) {
+    if (log) {
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64
+          ": %s",
+          __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+    }
+    return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+  }
+
+  if (log)
+    log->Printf(
+        "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64,
+        __FUNCTION__, m_debugged_process_sp->GetID());
+
+  // No response required from continue.
+  return PacketResult::Success;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vCont_actions(
+    StringExtractorGDBRemote &packet) {
+  StreamString response;
+  response.Printf("vCont;c;C;s;S");
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vCont(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s handling vCont packet",
+                __FUNCTION__);
+
+  packet.SetFilePos(::strlen("vCont"));
+
+  if (packet.GetBytesLeft() == 0) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s missing action from "
+                  "vCont package",
+                  __FUNCTION__);
+    return SendIllFormedResponse(packet, "Missing action from vCont package");
+  }
+
+  // Check if this is all continue (no options or ";c").
+  if (::strcmp(packet.Peek(), ";c") == 0) {
+    // Move past the ';', then do a simple 'c'.
+    packet.SetFilePos(packet.GetFilePos() + 1);
+    return Handle_c(packet);
+  } else if (::strcmp(packet.Peek(), ";s") == 0) {
+    // Move past the ';', then do a simple 's'.
+    packet.SetFilePos(packet.GetFilePos() + 1);
+    return Handle_s(packet);
+  }
+
+  // Ensure we have a native process.
+  if (!m_debugged_process_sp) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s no debugged process "
+                  "shared pointer",
+                  __FUNCTION__);
+    return SendErrorResponse(0x36);
+  }
+
+  ResumeActionList thread_actions;
+
+  while (packet.GetBytesLeft() && *packet.Peek() == ';') {
+    // Skip the semi-colon.
+    packet.GetChar();
+
+    // Build up the thread action.
+    ResumeAction thread_action;
+    thread_action.tid = LLDB_INVALID_THREAD_ID;
+    thread_action.state = eStateInvalid;
+    thread_action.signal = 0;
+
+    const char action = packet.GetChar();
+    switch (action) {
+    case 'C':
+      thread_action.signal = packet.GetHexMaxU32(false, 0);
+      if (thread_action.signal == 0)
+        return SendIllFormedResponse(
+            packet, "Could not parse signal in vCont packet C action");
+      LLVM_FALLTHROUGH;
+
+    case 'c':
+      // Continue
+      thread_action.state = eStateRunning;
+      break;
+
+    case 'S':
+      thread_action.signal = packet.GetHexMaxU32(false, 0);
+      if (thread_action.signal == 0)
+        return SendIllFormedResponse(
+            packet, "Could not parse signal in vCont packet S action");
+      LLVM_FALLTHROUGH;
+
+    case 's':
+      // Step
+      thread_action.state = eStateStepping;
+      break;
 
     default:
-        if (log)
-        {
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s didn't handle state change for pid %" PRIu64 ", new state: %s",
-                    __FUNCTION__,
-                    process->GetID (),
-                    StateAsCString (state));
-        }
-        break;
+      return SendIllFormedResponse(packet, "Unsupported vCont action");
+      break;
     }
 
-    // Remember the previous state reported to us.
-    m_inferior_prev_state = state;
-}
+    // Parse out optional :{thread-id} value.
+    if (packet.GetBytesLeft() && (*packet.Peek() == ':')) {
+      // Consume the separator.
+      packet.GetChar();
 
-void
-GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process)
-{
-    ClearProcessSpecificData ();
-}
+      thread_action.tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+      if (thread_action.tid == LLDB_INVALID_THREAD_ID)
+        return SendIllFormedResponse(
+            packet, "Could not parse thread number in vCont packet");
+    }
 
-void
-GDBRemoteCommunicationServerLLGS::DataAvailableCallback ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM));
+    thread_actions.Append(thread_action);
+  }
 
-    if (! m_handshake_completed)
-    {
-        if (! HandshakeWithClient())
-        {
-            if(log)
-                log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting",
-                        __FUNCTION__);
-            m_mainloop.RequestTermination();
-            return;
-        }
-        m_handshake_completed = true;
+  Error error = m_debugged_process_sp->Resume(thread_actions);
+  if (error.Fail()) {
+    if (log) {
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s vCont failed for "
+                  "process %" PRIu64 ": %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
     }
+    return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+  }
 
-    bool interrupt = false;
-    bool done = false;
-    Error error;
-    while (true)
-    {
-        const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done);
-        if (result == PacketResult::ErrorReplyTimeout)
-            break; // No more packets in the queue
-
-        if ((result != PacketResult::Success))
-        {
-            if(log)
-                log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s",
-                        __FUNCTION__, error.AsCString());
-            m_mainloop.RequestTermination();
-            break;
-        }
-    }
+  if (log)
+    log->Printf(
+        "GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64,
+        __FUNCTION__, m_debugged_process_sp->GetID());
+
+  // No response required from vCont.
+  return PacketResult::Success;
 }
 
-Error
-GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection)
-{
-    IOObjectSP read_object_sp = connection->GetReadObject();
-    GDBRemoteCommunicationServer::SetConnection(connection.release());
+void GDBRemoteCommunicationServerLLGS::SetCurrentThreadID(lldb::tid_t tid) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s setting current thread "
+                "id to %" PRIu64,
+                __FUNCTION__, tid);
 
-    Error error;
-    m_network_handle_up = m_mainloop.RegisterReadObject(read_object_sp,
-            [this] (MainLoopBase &) { DataAvailableCallback(); }, error);
-    return error;
+  m_current_tid = tid;
+  if (m_debugged_process_sp)
+    m_debugged_process_sp->SetCurrentThreadID(m_current_tid);
 }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len)
-{
-    if ((buffer == nullptr) || (len == 0))
-    {
-        // Nothing to send.
-        return PacketResult::Success;
-    }
-
-    StreamString response;
-    response.PutChar ('O');
-    response.PutBytesAsRawHex8 (buffer, len);
+void GDBRemoteCommunicationServerLLGS::SetContinueThreadID(lldb::tid_t tid) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s setting continue thread "
+                "id to %" PRIu64,
+                __FUNCTION__, tid);
 
-    return SendPacketNoLock (response.GetString());
+  m_continue_tid = tid;
 }
 
-Error
-GDBRemoteCommunicationServerLLGS::SetSTDIOFileDescriptor (int fd)
-{
-    Error error;
-
-    // Set up the reading/handling of process I/O
-    std::unique_ptr<ConnectionFileDescriptor> conn_up (new ConnectionFileDescriptor (fd, true));
-    if (!conn_up)
-    {
-        error.SetErrorString ("failed to create ConnectionFileDescriptor");
-        return error;
-    }
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
+    StringExtractorGDBRemote &packet) {
+  // Handle the $? gdbremote command.
 
-    m_stdio_communication.SetCloseOnEOF (false);
-    m_stdio_communication.SetConnection (conn_up.release());
-    if (!m_stdio_communication.IsConnected ())
-    {
-        error.SetErrorString ("failed to set connection for inferior I/O communication");
-        return error;
-    }
+  // If no process, indicate error
+  if (!m_debugged_process_sp)
+    return SendErrorResponse(02);
 
-    return Error();
+  return SendStopReasonForState(m_debugged_process_sp->GetState());
 }
 
-void
-GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding()
-{
-    // Don't forward if not connected (e.g. when attaching).
-    if (! m_stdio_communication.IsConnected())
-        return;
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
+    lldb::StateType process_state) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    Error error;
-    lldbassert(! m_stdio_handle_up);
-    m_stdio_handle_up = m_mainloop.RegisterReadObject(
-            m_stdio_communication.GetConnection()->GetReadObject(),
-            [this] (MainLoopBase &) { SendProcessOutput(); }, error);
-
-    if (! m_stdio_handle_up)
-    {
-        // Not much we can do about the failure. Log it and continue without forwarding.
-        if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
-            log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio forwarding: %s",
-                        __FUNCTION__, error.AsCString());
-    }
-}
+  switch (process_state) {
+  case eStateAttaching:
+  case eStateLaunching:
+  case eStateRunning:
+  case eStateStepping:
+  case eStateDetached:
+    // NOTE: gdb protocol doc looks like it should return $OK
+    // when everything is running (i.e. no stopped result).
+    return PacketResult::Success; // Ignore
+
+  case eStateSuspended:
+  case eStateStopped:
+  case eStateCrashed: {
+    lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID();
+    // Make sure we set the current thread so g and p packets return
+    // the data the gdb will expect.
+    SetCurrentThreadID(tid);
+    return SendStopReplyPacketForThread(tid);
+  }
+
+  case eStateInvalid:
+  case eStateUnloaded:
+  case eStateExited:
+    return SendWResponse(m_debugged_process_sp.get());
+
+  default:
+    if (log) {
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  ", current state reporting not handled: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  StateAsCString(process_state));
+    }
+    break;
+  }
+
+  return SendErrorResponse(0);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
+    StringExtractorGDBRemote &packet) {
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(68);
+
+  // Ensure we have a thread.
+  NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadAtIndex(0));
+  if (!thread_sp)
+    return SendErrorResponse(69);
+
+  // Get the register context for the first thread.
+  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+  if (!reg_context_sp)
+    return SendErrorResponse(69);
+
+  // Parse out the register number from the request.
+  packet.SetFilePos(strlen("qRegisterInfo"));
+  const uint32_t reg_index =
+      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+  if (reg_index == std::numeric_limits<uint32_t>::max())
+    return SendErrorResponse(69);
+
+  // Return the end of registers response if we've iterated one past the end of
+  // the register set.
+  if (reg_index >= reg_context_sp->GetUserRegisterCount())
+    return SendErrorResponse(69);
+
+  const RegisterInfo *reg_info =
+      reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+  if (!reg_info)
+    return SendErrorResponse(69);
+
+  // Build the reginfos response.
+  StreamGDBRemote response;
+
+  response.PutCString("name:");
+  response.PutCString(reg_info->name);
+  response.PutChar(';');
+
+  if (reg_info->alt_name && reg_info->alt_name[0]) {
+    response.PutCString("alt-name:");
+    response.PutCString(reg_info->alt_name);
+    response.PutChar(';');
+  }
+
+  response.Printf("bitsize:%" PRIu32 ";offset:%" PRIu32 ";",
+                  reg_info->byte_size * 8, reg_info->byte_offset);
+
+  switch (reg_info->encoding) {
+  case eEncodingUint:
+    response.PutCString("encoding:uint;");
+    break;
+  case eEncodingSint:
+    response.PutCString("encoding:sint;");
+    break;
+  case eEncodingIEEE754:
+    response.PutCString("encoding:ieee754;");
+    break;
+  case eEncodingVector:
+    response.PutCString("encoding:vector;");
+    break;
+  default:
+    break;
+  }
+
+  switch (reg_info->format) {
+  case eFormatBinary:
+    response.PutCString("format:binary;");
+    break;
+  case eFormatDecimal:
+    response.PutCString("format:decimal;");
+    break;
+  case eFormatHex:
+    response.PutCString("format:hex;");
+    break;
+  case eFormatFloat:
+    response.PutCString("format:float;");
+    break;
+  case eFormatVectorOfSInt8:
+    response.PutCString("format:vector-sint8;");
+    break;
+  case eFormatVectorOfUInt8:
+    response.PutCString("format:vector-uint8;");
+    break;
+  case eFormatVectorOfSInt16:
+    response.PutCString("format:vector-sint16;");
+    break;
+  case eFormatVectorOfUInt16:
+    response.PutCString("format:vector-uint16;");
+    break;
+  case eFormatVectorOfSInt32:
+    response.PutCString("format:vector-sint32;");
+    break;
+  case eFormatVectorOfUInt32:
+    response.PutCString("format:vector-uint32;");
+    break;
+  case eFormatVectorOfFloat32:
+    response.PutCString("format:vector-float32;");
+    break;
+  case eFormatVectorOfUInt128:
+    response.PutCString("format:vector-uint128;");
+    break;
+  default:
+    break;
+  };
+
+  const char *const register_set_name =
+      reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
+  if (register_set_name) {
+    response.PutCString("set:");
+    response.PutCString(register_set_name);
+    response.PutChar(';');
+  }
+
+  if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] !=
+      LLDB_INVALID_REGNUM)
+    response.Printf("ehframe:%" PRIu32 ";",
+                    reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
+
+  if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
+    response.Printf("dwarf:%" PRIu32 ";",
+                    reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
+
+  switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric]) {
+  case LLDB_REGNUM_GENERIC_PC:
+    response.PutCString("generic:pc;");
+    break;
+  case LLDB_REGNUM_GENERIC_SP:
+    response.PutCString("generic:sp;");
+    break;
+  case LLDB_REGNUM_GENERIC_FP:
+    response.PutCString("generic:fp;");
+    break;
+  case LLDB_REGNUM_GENERIC_RA:
+    response.PutCString("generic:ra;");
+    break;
+  case LLDB_REGNUM_GENERIC_FLAGS:
+    response.PutCString("generic:flags;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG1:
+    response.PutCString("generic:arg1;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG2:
+    response.PutCString("generic:arg2;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG3:
+    response.PutCString("generic:arg3;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG4:
+    response.PutCString("generic:arg4;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG5:
+    response.PutCString("generic:arg5;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG6:
+    response.PutCString("generic:arg6;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG7:
+    response.PutCString("generic:arg7;");
+    break;
+  case LLDB_REGNUM_GENERIC_ARG8:
+    response.PutCString("generic:arg8;");
+    break;
+  default:
+    break;
+  }
+
+  if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM) {
+    response.PutCString("container-regs:");
+    int i = 0;
+    for (const uint32_t *reg_num = reg_info->value_regs;
+         *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+      if (i > 0)
+        response.PutChar(',');
+      response.Printf("%" PRIx32, *reg_num);
+    }
+    response.PutChar(';');
+  }
+
+  if (reg_info->invalidate_regs && reg_info->invalidate_regs[0]) {
+    response.PutCString("invalidate-regs:");
+    int i = 0;
+    for (const uint32_t *reg_num = reg_info->invalidate_regs;
+         *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i) {
+      if (i > 0)
+        response.PutChar(',');
+      response.Printf("%" PRIx32, *reg_num);
+    }
+    response.PutChar(';');
+  }
+
+  if (reg_info->dynamic_size_dwarf_expr_bytes) {
+    const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
+    response.PutCString("dynamic_size_dwarf_expr_bytes:");
+    for (uint32_t i = 0; i < dwarf_opcode_len; ++i)
+      response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]);
+    response.PutChar(';');
+  }
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s() no process (%s), "
+                  "returning OK",
+                  __FUNCTION__,
+                  m_debugged_process_sp ? "invalid process id"
+                                        : "null m_debugged_process_sp");
+    return SendOKResponse();
+  }
+
+  StreamGDBRemote response;
+  response.PutChar('m');
 
-void
-GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding()
-{
-    m_stdio_handle_up.reset();
-}
-
-void
-GDBRemoteCommunicationServerLLGS::SendProcessOutput()
-{
-    char buffer[1024];
+  if (log)
+    log->Printf(
+        "GDBRemoteCommunicationServerLLGS::%s() starting thread iteration",
+        __FUNCTION__);
+
+  NativeThreadProtocolSP thread_sp;
+  uint32_t thread_index;
+  for (thread_index = 0,
+      thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index);
+       thread_sp; ++thread_index,
+      thread_sp = m_debugged_process_sp->GetThreadAtIndex(thread_index)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32
+          "(%s, tid=0x%" PRIx64 ")",
+          __FUNCTION__, thread_index, thread_sp ? "is not null" : "null",
+          thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID);
+    if (thread_index > 0)
+      response.PutChar(',');
+    response.Printf("%" PRIx64, thread_sp->GetID());
+  }
+
+  if (log)
+    log->Printf(
+        "GDBRemoteCommunicationServerLLGS::%s() finished thread iteration",
+        __FUNCTION__);
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo(
+    StringExtractorGDBRemote &packet) {
+  // FIXME for now we return the full thread list in the initial packet and
+  // always do nothing here.
+  return SendPacketNoLock("l");
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Parse out the register number from the request.
+  packet.SetFilePos(strlen("p"));
+  const uint32_t reg_index =
+      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+  if (reg_index == std::numeric_limits<uint32_t>::max()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+                  "parse register number from request \"%s\"",
+                  __FUNCTION__, packet.GetStringRef().c_str());
+    return SendErrorResponse(0x15);
+  }
+
+  // Get the thread to use.
+  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+  if (!thread_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no thread available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Get the thread's register context.
+  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+  if (!reg_context_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+          " failed, no register context available for the thread",
+          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+    return SendErrorResponse(0x15);
+  }
+
+  // Return the end of registers response if we've iterated one past the end of
+  // the register set.
+  if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+                  "register %" PRIu32 " beyond register count %" PRIu32,
+                  __FUNCTION__, reg_index,
+                  reg_context_sp->GetUserRegisterCount());
+    return SendErrorResponse(0x15);
+  }
+
+  const RegisterInfo *reg_info =
+      reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+  if (!reg_info) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+                  "register %" PRIu32 " returned NULL",
+                  __FUNCTION__, reg_index);
+    return SendErrorResponse(0x15);
+  }
+
+  // Build the reginfos response.
+  StreamGDBRemote response;
+
+  // Retrieve the value
+  RegisterValue reg_value;
+  Error error = reg_context_sp->ReadRegister(reg_info, reg_value);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of "
+                  "requested register %" PRIu32 " (%s) failed: %s",
+                  __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+    return SendErrorResponse(0x15);
+  }
+
+  const uint8_t *const data =
+      reinterpret_cast<const uint8_t *>(reg_value.GetBytes());
+  if (!data) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get data "
+                  "bytes from requested register %" PRIu32,
+                  __FUNCTION__, reg_index);
+    return SendErrorResponse(0x15);
+  }
+
+  // FIXME flip as needed to get data in big/little endian format for this host.
+  for (uint32_t i = 0; i < reg_value.GetByteSize(); ++i)
+    response.PutHex8(data[i]);
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Ensure there is more content.
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Empty P packet");
+
+  // Parse out the register number from the request.
+  packet.SetFilePos(strlen("P"));
+  const uint32_t reg_index =
+      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+  if (reg_index == std::numeric_limits<uint32_t>::max()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+                  "parse register number from request \"%s\"",
+                  __FUNCTION__, packet.GetStringRef().c_str());
+    return SendErrorResponse(0x29);
+  }
+
+  // Note debugserver would send an E30 here.
+  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != '='))
+    return SendIllFormedResponse(
+        packet, "P packet missing '=' char after register number");
+
+  // Get process architecture.
+  ArchSpec process_arch;
+  if (!m_debugged_process_sp ||
+      !m_debugged_process_sp->GetArchitecture(process_arch)) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve "
+                  "inferior architecture",
+                  __FUNCTION__);
+    return SendErrorResponse(0x49);
+  }
+
+  // Parse out the value.
+  uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
+  size_t reg_size = packet.GetHexBytesAvail(reg_bytes);
+
+  // Get the thread to use.
+  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+  if (!thread_sp) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread "
+                  "available (thread index 0)",
+                  __FUNCTION__);
+    return SendErrorResponse(0x28);
+  }
+
+  // Get the thread's register context.
+  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+  if (!reg_context_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+          " failed, no register context available for the thread",
+          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+    return SendErrorResponse(0x15);
+  }
+
+  const RegisterInfo *reg_info =
+      reg_context_sp->GetRegisterInfoAtIndex(reg_index);
+  if (!reg_info) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+                  "register %" PRIu32 " returned NULL",
+                  __FUNCTION__, reg_index);
+    return SendErrorResponse(0x48);
+  }
+
+  // Return the end of registers response if we've iterated one past the end of
+  // the register set.
+  if (reg_index >= reg_context_sp->GetUserRegisterCount()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested "
+                  "register %" PRIu32 " beyond register count %" PRIu32,
+                  __FUNCTION__, reg_index,
+                  reg_context_sp->GetUserRegisterCount());
+    return SendErrorResponse(0x47);
+  }
+
+  // The dwarf expression are evaluate on host site
+  // which may cause register size to change
+  // Hence the reg_size may not be same as reg_info->bytes_size
+  if ((reg_size != reg_info->byte_size) &&
+      !(reg_info->dynamic_size_dwarf_expr_bytes)) {
+    return SendIllFormedResponse(packet, "P packet register size is incorrect");
+  }
+
+  // Build the reginfos response.
+  StreamGDBRemote response;
+
+  RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder());
+  Error error = reg_context_sp->WriteRegister(reg_info, reg_value);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of "
+                  "requested register %" PRIu32 " (%s) failed: %s",
+                  __FUNCTION__, reg_index, reg_info->name, error.AsCString());
+    return SendErrorResponse(0x32);
+  }
+
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Parse out which variant of $H is requested.
+  packet.SetFilePos(strlen("H"));
+  if (packet.GetBytesLeft() < 1) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, H command "
+                  "missing {g,c} variant",
+                  __FUNCTION__);
+    return SendIllFormedResponse(packet, "H command missing {g,c} variant");
+  }
+
+  const char h_variant = packet.GetChar();
+  switch (h_variant) {
+  case 'g':
+    break;
+
+  case 'c':
+    break;
+
+  default:
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c",
+          __FUNCTION__, h_variant);
+    return SendIllFormedResponse(packet,
+                                 "H variant unsupported, should be c or g");
+  }
+
+  // Parse out the thread number.
+  // FIXME return a parse success/fail value.  All values are valid here.
+  const lldb::tid_t tid =
+      packet.GetHexMaxU64(false, std::numeric_limits<lldb::tid_t>::max());
+
+  // Ensure we have the given thread when not specifying -1 (all threads) or 0
+  // (any thread).
+  if (tid != LLDB_INVALID_THREAD_ID && tid != 0) {
+    NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadByID(tid));
+    if (!thread_sp) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64
+                    " not found",
+                    __FUNCTION__, tid);
+      return SendErrorResponse(0x15);
+    }
+  }
+
+  // Now switch the given thread type.
+  switch (h_variant) {
+  case 'g':
+    SetCurrentThreadID(tid);
+    break;
+
+  case 'c':
+    SetContinueThreadID(tid);
+    break;
+
+  default:
+    assert(false && "unsupported $H variant - shouldn't get here");
+    return SendIllFormedResponse(packet,
+                                 "H variant unsupported, should be c or g");
+  }
+
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_I(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  packet.SetFilePos(::strlen("I"));
+  uint8_t tmp[4096];
+  for (;;) {
+    size_t read = packet.GetHexBytesAvail(tmp);
+    if (read == 0) {
+      break;
+    }
+    // write directly to stdin *this might block if stdin buffer is full*
+    // TODO: enqueue this block in circular buffer and send window size to
+    // remote host
     ConnectionStatus status;
     Error error;
-    while (true)
-    {
-        size_t bytes_read = m_stdio_communication.Read(buffer, sizeof buffer, 0, status, &error);
-        switch (status)
-        {
-        case eConnectionStatusSuccess:
-            SendONotification(buffer, bytes_read);
-            break;
-        case eConnectionStatusLostConnection:
-        case eConnectionStatusEndOfFile:
-        case eConnectionStatusError:
-        case eConnectionStatusNoConnection:
-            if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS))
-                log->Printf("GDBRemoteCommunicationServerLLGS::%s Stopping stdio forwarding as communication returned status %d (error: %s)", __FUNCTION__, status, error.AsCString());
-            m_stdio_handle_up.reset();
-            return;
-
-        case eConnectionStatusInterrupted:
-        case eConnectionStatusTimedOut:
-            return;
-        }
+    m_stdio_communication.Write(tmp, read, status, &error);
+    if (error.Fail()) {
+      return SendErrorResponse(0x15);
     }
+  }
+
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
-{
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (68);
+GDBRemoteCommunicationServerLLGS::Handle_interrupt(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
-    lldb::pid_t pid = m_debugged_process_sp->GetID ();
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
 
-    if (pid == LLDB_INVALID_PROCESS_ID)
-        return SendErrorResponse (1);
+  // Interrupt the process.
+  Error error = m_debugged_process_sp->Interrupt();
+  if (error.Fail()) {
+    if (log) {
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64
+          ": %s",
+          __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+    }
+    return SendErrorResponse(GDBRemoteServerError::eErrorResume);
+  }
 
-    ProcessInstanceInfo proc_info;
-    if (!Host::GetProcessInfo (pid, proc_info))
-        return SendErrorResponse (1);
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64,
+                __FUNCTION__, m_debugged_process_sp->GetID());
 
-    StreamString response;
-    CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
-    return SendPacketNoLock (response.GetString());
+  // No response required from stop all.
+  return PacketResult::Success;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qC (StringExtractorGDBRemote &packet)
-{
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (68);
+GDBRemoteCommunicationServerLLGS::Handle_memory_read(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    // Make sure we set the current thread so g and p packets return
-    // the data the gdb will expect.
-    lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
-    SetCurrentThreadID (tid);
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
 
-    NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread ();
-    if (!thread_sp)
-        return SendErrorResponse (69);
+  // Parse out the memory address.
+  packet.SetFilePos(strlen("m"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Too short m packet");
 
-    StreamString response;
-    response.Printf ("QC%" PRIx64, thread_sp->GetID ());
+  // Read the address.  Punting on validation.
+  // FIXME replace with Hex U64 read with no default value that fails on failed
+  // read.
+  const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
 
-    return SendPacketNoLock (response.GetString());
-}
+  // Validate comma.
+  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
+    return SendIllFormedResponse(packet, "Comma sep missing in m packet");
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  // Get # bytes to read.
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Length missing in m packet");
 
-    StopSTDIOForwarding();
+  const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
+  if (byte_count == 0) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: "
+                  "zero-length packet",
+                  __FUNCTION__);
+    return SendOKResponse();
+  }
 
-    if (! m_debugged_process_sp)
-    {
-        if (log)
-            log->Printf("GDBRemoteCommunicationServerLLGS::%s No debugged process found.", __FUNCTION__);
-        return PacketResult::Success;
-    }
+  // Allocate the response buffer.
+  std::string buf(byte_count, '\0');
+  if (buf.empty())
+    return SendErrorResponse(0x78);
+
+  // Retrieve the process memory.
+  size_t bytes_read = 0;
+  Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(
+      read_addr, &buf[0], byte_count, bytes_read);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " mem 0x%" PRIx64 ": failed to read. Error: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(), read_addr,
+                  error.AsCString());
+    return SendErrorResponse(0x08);
+  }
+
+  if (bytes_read == 0) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes",
+                  __FUNCTION__, m_debugged_process_sp->GetID(), read_addr,
+                  byte_count);
+    return SendErrorResponse(0x08);
+  }
+
+  StreamGDBRemote response;
+  packet.SetFilePos(0);
+  char kind = packet.GetChar('?');
+  if (kind == 'x')
+    response.PutEscapedBytes(buf.data(), byte_count);
+  else {
+    assert(kind == 'm');
+    for (size_t i = 0; i < bytes_read; ++i)
+      response.PutHex8(buf[i]);
+  }
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_M(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Parse out the memory address.
+  packet.SetFilePos(strlen("M"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Too short M packet");
+
+  // Read the address.  Punting on validation.
+  // FIXME replace with Hex U64 read with no default value that fails on failed
+  // read.
+  const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
+
+  // Validate comma.
+  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
+    return SendIllFormedResponse(packet, "Comma sep missing in M packet");
+
+  // Get # bytes to read.
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Length missing in M packet");
+
+  const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
+  if (byte_count == 0) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to write: "
+                  "zero-length packet",
+                  __FUNCTION__);
+    return PacketResult::Success;
+  }
 
-    Error error = m_debugged_process_sp->Kill();
-    if (error.Fail() && log)
-        log->Printf("GDBRemoteCommunicationServerLLGS::%s Failed to kill debugged process %" PRIu64 ": %s",
-                __FUNCTION__, m_debugged_process_sp->GetID(), error.AsCString());
+  // Validate colon.
+  if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
+    return SendIllFormedResponse(
+        packet, "Comma sep missing in M packet after byte length");
+
+  // Allocate the conversion buffer.
+  std::vector<uint8_t> buf(byte_count, 0);
+  if (buf.empty())
+    return SendErrorResponse(0x78);
+
+  // Convert the hex memory write contents to bytes.
+  StreamGDBRemote response;
+  const uint64_t convert_count = packet.GetHexBytes(buf, 0);
+  if (convert_count != byte_count) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " mem 0x%" PRIx64 ": asked to write %" PRIu64
+                  " bytes, but only found %" PRIu64 " to convert.",
+                  __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+                  byte_count, convert_count);
+    return SendIllFormedResponse(packet, "M content byte length specified did "
+                                         "not match hex-encoded content "
+                                         "length");
+  }
+
+  // Write the process memory.
+  size_t bytes_written = 0;
+  Error error = m_debugged_process_sp->WriteMemory(write_addr, &buf[0],
+                                                   byte_count, bytes_written);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " mem 0x%" PRIx64 ": failed to write. Error: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+                  error.AsCString());
+    return SendErrorResponse(0x09);
+  }
+
+  if (bytes_written == 0) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes",
+                  __FUNCTION__, m_debugged_process_sp->GetID(), write_addr,
+                  byte_count);
+    return SendErrorResponse(0x09);
+  }
+
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  // Currently only the NativeProcessProtocol knows if it can handle a
+  // qMemoryRegionInfoSupported
+  // request, but we're not guaranteed to be attached to a process.  For now
+  // we'll assume the
+  // client only asks this when a process is being debugged.
+
+  // Ensure we have a process running; otherwise, we can't figure this out
+  // since we won't have a NativeProcessProtocol.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Test if we can get any region back when asking for the region around NULL.
+  MemoryRegionInfo region_info;
+  const Error error =
+      m_debugged_process_sp->GetMemoryRegionInfo(0, region_info);
+  if (error.Fail()) {
+    // We don't support memory region info collection for this
+    // NativeProcessProtocol.
+    return SendUnimplementedResponse("");
+  }
+
+  return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  // Ensure we have a process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Parse out the memory address.
+  packet.SetFilePos(strlen("qMemoryRegionInfo:"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
+
+  // Read the address.  Punting on validation.
+  const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+
+  StreamGDBRemote response;
+
+  // Get the memory region info for the target address.
+  MemoryRegionInfo region_info;
+  const Error error =
+      m_debugged_process_sp->GetMemoryRegionInfo(read_addr, region_info);
+  if (error.Fail()) {
+    // Return the error message.
+
+    response.PutCString("error:");
+    response.PutCStringAsRawHex8(error.AsCString());
+    response.PutChar(';');
+  } else {
+    // Range start and size.
+    response.Printf("start:%" PRIx64 ";size:%" PRIx64 ";",
+                    region_info.GetRange().GetRangeBase(),
+                    region_info.GetRange().GetByteSize());
+
+    // Permissions.
+    if (region_info.GetReadable() || region_info.GetWritable() ||
+        region_info.GetExecutable()) {
+      // Write permissions info.
+      response.PutCString("permissions:");
+
+      if (region_info.GetReadable())
+        response.PutChar('r');
+      if (region_info.GetWritable())
+        response.PutChar('w');
+      if (region_info.GetExecutable())
+        response.PutChar('x');
+
+      response.PutChar(';');
+    }
+
+    // Name
+    ConstString name = region_info.GetName();
+    if (name) {
+      response.PutCString("name:");
+      response.PutCStringAsRawHex8(name.AsCString());
+      response.PutChar(';');
+    }
+  }
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_Z(StringExtractorGDBRemote &packet) {
+  // Ensure we have a process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Parse out software or hardware breakpoint or watchpoint requested.
+  packet.SetFilePos(strlen("Z"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(
+        packet, "Too short Z packet, missing software/hardware specifier");
+
+  bool want_breakpoint = true;
+  bool want_hardware = false;
+  uint32_t watch_flags = 0;
+
+  const GDBStoppointType stoppoint_type =
+      GDBStoppointType(packet.GetS32(eStoppointInvalid));
+  switch (stoppoint_type) {
+  case eBreakpointSoftware:
+    want_hardware = false;
+    want_breakpoint = true;
+    break;
+  case eBreakpointHardware:
+    want_hardware = true;
+    want_breakpoint = true;
+    break;
+  case eWatchpointWrite:
+    watch_flags = 1;
+    want_hardware = true;
+    want_breakpoint = false;
+    break;
+  case eWatchpointRead:
+    watch_flags = 2;
+    want_hardware = true;
+    want_breakpoint = false;
+    break;
+  case eWatchpointReadWrite:
+    watch_flags = 3;
+    want_hardware = true;
+    want_breakpoint = false;
+    break;
+  case eStoppointInvalid:
+    return SendIllFormedResponse(
+        packet, "Z packet had invalid software/hardware specifier");
+  }
+
+  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "Malformed Z packet, expecting comma after stoppoint type");
+
+  // Parse out the stoppoint address.
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Too short Z packet, missing address");
+  const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
+
+  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "Malformed Z packet, expecting comma after address");
+
+  // Parse out the stoppoint size (i.e. size hint for opcode size).
+  const uint32_t size =
+      packet.GetHexMaxU32(false, std::numeric_limits<uint32_t>::max());
+  if (size == std::numeric_limits<uint32_t>::max())
+    return SendIllFormedResponse(
+        packet, "Malformed Z packet, failed to parse size argument");
+
+  if (want_breakpoint) {
+    // Try to set the breakpoint.
+    const Error error =
+        m_debugged_process_sp->SetBreakpoint(addr, size, want_hardware);
+    if (error.Success())
+      return SendOKResponse();
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " failed to set breakpoint: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x09);
+  } else {
+    // Try to set the watchpoint.
+    const Error error = m_debugged_process_sp->SetWatchpoint(
+        addr, size, watch_flags, want_hardware);
+    if (error.Success())
+      return SendOKResponse();
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " failed to set watchpoint: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x09);
+  }
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
+  // Ensure we have a process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
+
+  // Parse out software or hardware breakpoint or watchpoint requested.
+  packet.SetFilePos(strlen("z"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(
+        packet, "Too short z packet, missing software/hardware specifier");
+
+  bool want_breakpoint = true;
+
+  const GDBStoppointType stoppoint_type =
+      GDBStoppointType(packet.GetS32(eStoppointInvalid));
+  switch (stoppoint_type) {
+  case eBreakpointHardware:
+    want_breakpoint = true;
+    break;
+  case eBreakpointSoftware:
+    want_breakpoint = true;
+    break;
+  case eWatchpointWrite:
+    want_breakpoint = false;
+    break;
+  case eWatchpointRead:
+    want_breakpoint = false;
+    break;
+  case eWatchpointReadWrite:
+    want_breakpoint = false;
+    break;
+  default:
+    return SendIllFormedResponse(
+        packet, "z packet had invalid software/hardware specifier");
+  }
+
+  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "Malformed z packet, expecting comma after stoppoint type");
+
+  // Parse out the stoppoint address.
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Too short z packet, missing address");
+  const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
+
+  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "Malformed z packet, expecting comma after address");
+
+  /*
+  // Parse out the stoppoint size (i.e. size hint for opcode size).
+  const uint32_t size = packet.GetHexMaxU32 (false,
+  std::numeric_limits<uint32_t>::max ());
+  if (size == std::numeric_limits<uint32_t>::max ())
+      return SendIllFormedResponse(packet, "Malformed z packet, failed to parse
+  size argument");
+  */
+
+  if (want_breakpoint) {
+    // Try to clear the breakpoint.
+    const Error error = m_debugged_process_sp->RemoveBreakpoint(addr);
+    if (error.Success())
+      return SendOKResponse();
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " failed to remove breakpoint: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x09);
+  } else {
+    // Try to clear the watchpoint.
+    const Error error = m_debugged_process_sp->RemoveWatchpoint(addr);
+    if (error.Success())
+      return SendOKResponse();
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " failed to remove watchpoint: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x09);
+  }
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+
+  // Ensure we have a process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x32);
+  }
+
+  // We first try to use a continue thread id.  If any one or any all set, use
+  // the current thread.
+  // Bail out if we don't have a thread id.
+  lldb::tid_t tid = GetContinueThreadID();
+  if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
+    tid = GetCurrentThreadID();
+  if (tid == LLDB_INVALID_THREAD_ID)
+    return SendErrorResponse(0x33);
+
+  // Double check that we have such a thread.
+  // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
+  NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID(tid);
+  if (!thread_sp || thread_sp->GetID() != tid)
+    return SendErrorResponse(0x33);
+
+  // Create the step action for the given thread.
+  ResumeAction action = {tid, eStateStepping, 0};
+
+  // Setup the actions list.
+  ResumeActionList actions;
+  actions.Append(action);
+
+  // All other threads stop while we're single stepping a thread.
+  actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
+  Error error = m_debugged_process_sp->Resume(actions);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " tid %" PRIu64 " Resume() failed with error: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(), tid,
+                  error.AsCString());
+    return SendErrorResponse(0x49);
+  }
+
+  // No response here - the stop or exit will come from the resulting action.
+  return PacketResult::Success;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read(
+    StringExtractorGDBRemote &packet) {
+// *BSD impls should be able to do this too.
+#if defined(__linux__)
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    // No OK response for kill packet.
-    // return SendOKResponse ();
-    return PacketResult::Success;
+  // Parse out the offset.
+  packet.SetFilePos(strlen("qXfer:auxv:read::"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet,
+                                 "qXfer:auxv:read:: packet missing offset");
+
+  const uint64_t auxv_offset =
+      packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+  if (auxv_offset == std::numeric_limits<uint64_t>::max())
+    return SendIllFormedResponse(packet,
+                                 "qXfer:auxv:read:: packet missing offset");
+
+  // Parse out comma.
+  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "qXfer:auxv:read:: packet missing comma after offset");
+
+  // Parse out the length.
+  const uint64_t auxv_length =
+      packet.GetHexMaxU64(false, std::numeric_limits<uint64_t>::max());
+  if (auxv_length == std::numeric_limits<uint64_t>::max())
+    return SendIllFormedResponse(packet,
+                                 "qXfer:auxv:read:: packet missing length");
+
+  // Grab the auxv data if we need it.
+  if (!m_active_auxv_buffer_sp) {
+    // Make sure we have a valid process.
+    if (!m_debugged_process_sp ||
+        (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+      if (log)
+        log->Printf(
+            "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+            __FUNCTION__);
+      return SendErrorResponse(0x10);
+    }
+
+    // Grab the auxv data.
+    m_active_auxv_buffer_sp = Host::GetAuxvData(m_debugged_process_sp->GetID());
+    if (!m_active_auxv_buffer_sp ||
+        m_active_auxv_buffer_sp->GetByteSize() == 0) {
+      // Hmm, no auxv data, call that an error.
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data "
+                    "retrieved",
+                    __FUNCTION__);
+      m_active_auxv_buffer_sp.reset();
+      return SendErrorResponse(0x11);
+    }
+  }
+
+  // FIXME find out if/how I lock the stream here.
+
+  StreamGDBRemote response;
+  bool done_with_buffer = false;
+
+  if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize()) {
+    // We have nothing left to send.  Mark the buffer as complete.
+    response.PutChar('l');
+    done_with_buffer = true;
+  } else {
+    // Figure out how many bytes are available starting at the given offset.
+    const uint64_t bytes_remaining =
+        m_active_auxv_buffer_sp->GetByteSize() - auxv_offset;
+
+    // Figure out how many bytes we're going to read.
+    const uint64_t bytes_to_read =
+        (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length;
+
+    // Mark the response type according to whether we're reading the remainder
+    // of the auxv data.
+    if (bytes_to_read >= bytes_remaining) {
+      // There will be nothing left to read after this
+      response.PutChar('l');
+      done_with_buffer = true;
+    } else {
+      // There will still be bytes to read after this request.
+      response.PutChar('m');
+    }
+
+    // Now write the data in encoded binary form.
+    response.PutEscapedBytes(m_active_auxv_buffer_sp->GetBytes() + auxv_offset,
+                             bytes_to_read);
+  }
+
+  if (done_with_buffer)
+    m_active_auxv_buffer_sp.reset();
+
+  return SendPacketNoLock(response.GetString());
+#else
+  return SendUnimplementedResponse("not implemented on this platform");
+#endif
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QSetDisableASLR:"));
-    if (packet.GetU32(0))
-        m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
+GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Move past packet name.
+  packet.SetFilePos(strlen("QSaveRegisterState"));
+
+  // Get the thread to use.
+  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+  if (!thread_sp) {
+    if (m_thread_suffix_supported)
+      return SendIllFormedResponse(
+          packet, "No thread specified in QSaveRegisterState packet");
     else
-        m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR);
-    return SendOKResponse ();
-}
+      return SendIllFormedResponse(packet,
+                                   "No thread was is set with the Hg packet");
+  }
+
+  // Grab the register context for the thread.
+  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+  if (!reg_context_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+          " failed, no register context available for the thread",
+          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+    return SendErrorResponse(0x15);
+  }
+
+  // Save registers to a buffer.
+  DataBufferSP register_data_sp;
+  Error error = reg_context_sp->ReadAllRegisterValues(register_data_sp);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " failed to save all register values: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x75);
+  }
+
+  // Allocate a new save id.
+  const uint32_t save_id = GetNextSavedRegistersID();
+  assert((m_saved_registers_map.find(save_id) == m_saved_registers_map.end()) &&
+         "GetNextRegisterSaveID() returned an existing register save id");
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos (::strlen ("QSetWorkingDir:"));
-    std::string path;
-    packet.GetHexByteString (path);
-    m_process_launch_info.SetWorkingDirectory(FileSpec{path, true});
-    return SendOKResponse ();
+  // Save the register data buffer under the save id.
+  {
+    std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+    m_saved_registers_map[save_id] = register_data_sp;
+  }
+
+  // Write the response.
+  StreamGDBRemote response;
+  response.Printf("%" PRIu32, save_id);
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
-{
-    FileSpec working_dir{m_process_launch_info.GetWorkingDirectory()};
-    if (working_dir)
-    {
-        StreamString response;
-        response.PutCStringAsRawHex8(working_dir.GetCString());
-        return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Parse out save id.
+  packet.SetFilePos(strlen("QRestoreRegisterState:"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(
+        packet, "QRestoreRegisterState packet missing register save id");
+
+  const uint32_t save_id = packet.GetU32(0);
+  if (save_id == 0) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState "
+                  "packet has malformed save id, expecting decimal uint32_t",
+                  __FUNCTION__);
+    return SendErrorResponse(0x76);
+  }
+
+  // Get the thread to use.
+  NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet);
+  if (!thread_sp) {
+    if (m_thread_suffix_supported)
+      return SendIllFormedResponse(
+          packet, "No thread specified in QRestoreRegisterState packet");
+    else
+      return SendIllFormedResponse(packet,
+                                   "No thread was is set with the Hg packet");
+  }
+
+  // Grab the register context for the thread.
+  NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext());
+  if (!reg_context_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64
+          " failed, no register context available for the thread",
+          __FUNCTION__, m_debugged_process_sp->GetID(), thread_sp->GetID());
+    return SendErrorResponse(0x15);
+  }
+
+  // Retrieve register state buffer, then remove from the list.
+  DataBufferSP register_data_sp;
+  {
+    std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+
+    // Find the register set buffer for the given save id.
+    auto it = m_saved_registers_map.find(save_id);
+    if (it == m_saved_registers_map.end()) {
+      if (log)
+        log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                    " does not have a register set save buffer for id %" PRIu32,
+                    __FUNCTION__, m_debugged_process_sp->GetID(), save_id);
+      return SendErrorResponse(0x77);
     }
+    register_data_sp = it->second;
 
-    return SendErrorResponse(14);
-}
+    // Remove it from the map.
+    m_saved_registers_map.erase(it);
+  }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_C (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
+  Error error = reg_context_sp->WriteAllRegisterValues(register_data_sp);
+  if (error.Fail()) {
     if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
-    // Ensure we have a native process.
-    if (!m_debugged_process_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
-        return SendErrorResponse (0x36);
-    }
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+                  " failed to restore all register values: %s",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x77);
+  }
 
-    // Pull out the signal number.
-    packet.SetFilePos (::strlen ("C"));
-    if (packet.GetBytesLeft () < 1)
-    {
-        // Shouldn't be using a C without a signal.
-        return SendIllFormedResponse (packet, "C packet specified without signal.");
-    }
-    const uint32_t signo = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
-    if (signo == std::numeric_limits<uint32_t>::max ())
-        return SendIllFormedResponse (packet, "failed to parse signal number");
-
-    // Handle optional continue address.
-    if (packet.GetBytesLeft () > 0)
-    {
-        // FIXME add continue at address support for $C{signo}[;{continue-address}].
-        if (*packet.Peek () == ';')
-            return SendUnimplementedResponse (packet.GetStringRef().c_str());
-        else
-            return SendIllFormedResponse (packet, "unexpected content after $C{signal-number}");
-    }
+  return SendOKResponse();
+}
 
-    ResumeActionList resume_actions (StateType::eStateRunning, 0);
-    Error error;
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_vAttach(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    // We have two branches: what to do if a continue thread is specified (in which case we target
-    // sending the signal to that thread), or when we don't have a continue thread set (in which
-    // case we send a signal to the process).
-
-    // TODO discuss with Greg Clayton, make sure this makes sense.
-
-    lldb::tid_t signal_tid = GetContinueThreadID ();
-    if (signal_tid != LLDB_INVALID_THREAD_ID)
-    {
-        // The resume action for the continue thread (or all threads if a continue thread is not set).
-        ResumeAction action = { GetContinueThreadID (), StateType::eStateRunning, static_cast<int> (signo) };
+  // Consume the ';' after vAttach.
+  packet.SetFilePos(strlen("vAttach"));
+  if (!packet.GetBytesLeft() || packet.GetChar() != ';')
+    return SendIllFormedResponse(packet, "vAttach missing expected ';'");
 
-        // Add the action for the continue thread (or all threads when the continue thread isn't present).
-        resume_actions.Append (action);
-    }
-    else
-    {
-        // Send the signal to the process since we weren't targeting a specific continue thread with the signal.
-        error = m_debugged_process_sp->Signal (signo);
-        if (error.Fail ())
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to send signal for process %" PRIu64 ": %s",
-                             __FUNCTION__,
-                             m_debugged_process_sp->GetID (),
-                             error.AsCString ());
+  // Grab the PID to which we will attach (assume hex encoding).
+  lldb::pid_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return SendIllFormedResponse(packet,
+                                 "vAttach failed to parse the process id");
 
-            return SendErrorResponse (0x52);
-        }
-    }
+  // Attempt to attach.
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s attempting to attach to "
+                "pid %" PRIu64,
+                __FUNCTION__, pid);
 
-    // Resume the threads.
-    error = m_debugged_process_sp->Resume (resume_actions);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to resume threads for process %" PRIu64 ": %s",
-                         __FUNCTION__,
-                         m_debugged_process_sp->GetID (),
-                         error.AsCString ());
+  Error error = AttachToProcess(pid);
 
-        return SendErrorResponse (0x38);
-    }
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to "
+                  "pid %" PRIu64 ": %s\n",
+                  __FUNCTION__, pid, error.AsCString());
+    return SendErrorResponse(0x01);
+  }
 
-    // Don't send an "OK" packet; response is the stopped/exited message.
-    return PacketResult::Success;
+  // Notify we attached by sending a stop packet.
+  return SendStopReasonForState(m_debugged_process_sp->GetState());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_c (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__);
-
-    packet.SetFilePos (packet.GetFilePos() + ::strlen ("c"));
-
-    // For now just support all continue.
-    const bool has_continue_address = (packet.GetBytesLeft () > 0);
-    if (has_continue_address)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s not implemented for c{address} variant [%s remains]", __FUNCTION__, packet.Peek ());
-        return SendUnimplementedResponse (packet.GetStringRef().c_str());
-    }
+GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    // Ensure we have a native process.
-    if (!m_debugged_process_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
-        return SendErrorResponse (0x36);
-    }
+  StopSTDIOForwarding();
+
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
 
-    // Build the ResumeActionList
-    ResumeActionList actions (StateType::eStateRunning, 0);
+  lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
 
-    Error error = m_debugged_process_sp->Resume (actions);
-    if (error.Fail ())
-    {
-        if (log)
-        {
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s c failed for process %" PRIu64 ": %s",
-                         __FUNCTION__,
-                         m_debugged_process_sp->GetID (),
-                         error.AsCString ());
-        }
-        return SendErrorResponse (GDBRemoteServerError::eErrorResume);
-    }
+  // Consume the ';' after D.
+  packet.SetFilePos(1);
+  if (packet.GetBytesLeft()) {
+    if (packet.GetChar() != ';')
+      return SendIllFormedResponse(packet, "D missing expected ';'");
 
+    // Grab the PID from which we will detach (assume hex encoding).
+    pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
+    if (pid == LLDB_INVALID_PROCESS_ID)
+      return SendIllFormedResponse(packet, "D failed to parse the process id");
+  }
+
+  if (pid != LLDB_INVALID_PROCESS_ID && m_debugged_process_sp->GetID() != pid) {
+    return SendIllFormedResponse(packet, "Invalid pid");
+  }
+
+  const Error error = m_debugged_process_sp->Detach();
+  if (error.Fail()) {
     if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from "
+                  "pid %" PRIu64 ": %s\n",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x01);
+  }
 
-    // No response required from continue.
-    return PacketResult::Success;
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont_actions (StringExtractorGDBRemote &packet)
-{
-    StreamString response;
-    response.Printf("vCont;c;C;s;S");
+GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-    return SendPacketNoLock(response.GetString());
+  packet.SetFilePos(strlen("qThreadStopInfo"));
+  const lldb::tid_t tid = packet.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+  if (tid == LLDB_INVALID_THREAD_ID) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, could not "
+                  "parse thread id from request \"%s\"",
+                  __FUNCTION__, packet.GetStringRef().c_str());
+    return SendErrorResponse(0x15);
+  }
+  return SendStopReplyPacketForThread(tid);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s handling vCont packet", __FUNCTION__);
+GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo(
+    StringExtractorGDBRemote &) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
-    packet.SetFilePos (::strlen ("vCont"));
+  // Ensure we have a debugged process.
+  if (!m_debugged_process_sp ||
+      (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+    return SendErrorResponse(50);
 
-    if (packet.GetBytesLeft() == 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s missing action from vCont package", __FUNCTION__);
-        return SendIllFormedResponse (packet, "Missing action from vCont package");
-    }
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid "
+                "%" PRIu64,
+                __FUNCTION__, m_debugged_process_sp->GetID());
 
-    // Check if this is all continue (no options or ";c").
-    if (::strcmp (packet.Peek (), ";c") == 0)
-    {
-        // Move past the ';', then do a simple 'c'.
-        packet.SetFilePos (packet.GetFilePos () + 1);
-        return Handle_c (packet);
-    }
-    else if (::strcmp (packet.Peek (), ";s") == 0)
-    {
-        // Move past the ';', then do a simple 's'.
-        packet.SetFilePos (packet.GetFilePos () + 1);
-        return Handle_s (packet);
-    }
-
-    // Ensure we have a native process.
-    if (!m_debugged_process_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s no debugged process shared pointer", __FUNCTION__);
-        return SendErrorResponse (0x36);
-    }
-
-    ResumeActionList thread_actions;
-
-    while (packet.GetBytesLeft () && *packet.Peek () == ';')
-    {
-        // Skip the semi-colon.
-        packet.GetChar ();
-
-        // Build up the thread action.
-        ResumeAction thread_action;
-        thread_action.tid = LLDB_INVALID_THREAD_ID;
-        thread_action.state = eStateInvalid;
-        thread_action.signal = 0;
-
-        const char action = packet.GetChar ();
-        switch (action)
-        {
-            case 'C':
-                thread_action.signal = packet.GetHexMaxU32 (false, 0);
-                if (thread_action.signal == 0)
-                    return SendIllFormedResponse (packet, "Could not parse signal in vCont packet C action");
-                LLVM_FALLTHROUGH;
-
-            case 'c':
-                // Continue
-                thread_action.state = eStateRunning;
-                break;
-
-            case 'S':
-                thread_action.signal = packet.GetHexMaxU32 (false, 0);
-                if (thread_action.signal == 0)
-                    return SendIllFormedResponse (packet, "Could not parse signal in vCont packet S action");
-                LLVM_FALLTHROUGH;
-
-            case 's':
-                // Step
-                thread_action.state = eStateStepping;
-                break;
-
-            default:
-                return SendIllFormedResponse (packet, "Unsupported vCont action");
-                break;
-        }
-
-        // Parse out optional :{thread-id} value.
-        if (packet.GetBytesLeft () && (*packet.Peek () == ':'))
-        {
-            // Consume the separator.
-            packet.GetChar ();
-
-            thread_action.tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID);
-            if (thread_action.tid == LLDB_INVALID_THREAD_ID)
-                return SendIllFormedResponse (packet, "Could not parse thread number in vCont packet");
-        }
-
-        thread_actions.Append (thread_action);
-    }
-
-    Error error = m_debugged_process_sp->Resume (thread_actions);
-    if (error.Fail ())
-    {
-        if (log)
-        {
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s vCont failed for process %" PRIu64 ": %s",
-                         __FUNCTION__,
-                         m_debugged_process_sp->GetID (),
-                         error.AsCString ());
-        }
-        return SendErrorResponse (GDBRemoteServerError::eErrorResume);
-    }
-
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
-
-    // No response required from vCont.
-    return PacketResult::Success;
-}
-
-void
-GDBRemoteCommunicationServerLLGS::SetCurrentThreadID (lldb::tid_t tid)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting current thread id to %" PRIu64, __FUNCTION__, tid);
-
-    m_current_tid = tid;
-    if (m_debugged_process_sp)
-        m_debugged_process_sp->SetCurrentThreadID (m_current_tid);
-}
-
-void
-GDBRemoteCommunicationServerLLGS::SetContinueThreadID (lldb::tid_t tid)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_THREAD));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s setting continue thread id to %" PRIu64, __FUNCTION__, tid);
-
-    m_continue_tid = tid;
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_stop_reason (StringExtractorGDBRemote &packet)
-{
-    // Handle the $? gdbremote command.
-
-    // If no process, indicate error
-    if (!m_debugged_process_sp)
-        return SendErrorResponse (02);
-
-    return SendStopReasonForState (m_debugged_process_sp->GetState());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReasonForState (lldb::StateType process_state)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    switch (process_state)
-    {
-        case eStateAttaching:
-        case eStateLaunching:
-        case eStateRunning:
-        case eStateStepping:
-        case eStateDetached:
-            // NOTE: gdb protocol doc looks like it should return $OK
-            // when everything is running (i.e. no stopped result).
-            return PacketResult::Success;  // Ignore
-
-        case eStateSuspended:
-        case eStateStopped:
-        case eStateCrashed:
-        {
-            lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
-            // Make sure we set the current thread so g and p packets return
-            // the data the gdb will expect.
-            SetCurrentThreadID (tid);
-            return SendStopReplyPacketForThread (tid);
-        }
-
-        case eStateInvalid:
-        case eStateUnloaded:
-        case eStateExited:
-            return SendWResponse(m_debugged_process_sp.get());
-
-        default:
-            if (log)
-            {
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 ", current state reporting not handled: %s",
-                             __FUNCTION__,
-                             m_debugged_process_sp->GetID (),
-                             StateAsCString (process_state));
-            }
-            break;
-    }
-    
-    return SendErrorResponse (0);
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo (StringExtractorGDBRemote &packet)
-{
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (68);
-
-    // Ensure we have a thread.
-    NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadAtIndex (0));
-    if (!thread_sp)
-        return SendErrorResponse (69);
-
-    // Get the register context for the first thread.
-    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
-    if (!reg_context_sp)
-        return SendErrorResponse (69);
-
-    // Parse out the register number from the request.
-    packet.SetFilePos (strlen("qRegisterInfo"));
-    const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
-    if (reg_index == std::numeric_limits<uint32_t>::max ())
-        return SendErrorResponse (69);
-
-    // Return the end of registers response if we've iterated one past the end of the register set.
-    if (reg_index >= reg_context_sp->GetUserRegisterCount ())
-        return SendErrorResponse (69);
-
-    const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
-    if (!reg_info)
-        return SendErrorResponse (69);
-
-    // Build the reginfos response.
-    StreamGDBRemote response;
-
-    response.PutCString ("name:");
-    response.PutCString (reg_info->name);
-    response.PutChar (';');
-
-    if (reg_info->alt_name && reg_info->alt_name[0])
-    {
-        response.PutCString ("alt-name:");
-        response.PutCString (reg_info->alt_name);
-        response.PutChar (';');
-    }
-
-    response.Printf ("bitsize:%" PRIu32 ";offset:%" PRIu32 ";", reg_info->byte_size * 8, reg_info->byte_offset);
-
-    switch (reg_info->encoding)
-    {
-        case eEncodingUint:    response.PutCString ("encoding:uint;"); break;
-        case eEncodingSint:    response.PutCString ("encoding:sint;"); break;
-        case eEncodingIEEE754: response.PutCString ("encoding:ieee754;"); break;
-        case eEncodingVector:  response.PutCString ("encoding:vector;"); break;
-        default: break;
-    }
-
-    switch (reg_info->format)
-    {
-        case eFormatBinary:          response.PutCString ("format:binary;"); break;
-        case eFormatDecimal:         response.PutCString ("format:decimal;"); break;
-        case eFormatHex:             response.PutCString ("format:hex;"); break;
-        case eFormatFloat:           response.PutCString ("format:float;"); break;
-        case eFormatVectorOfSInt8:   response.PutCString ("format:vector-sint8;"); break;
-        case eFormatVectorOfUInt8:   response.PutCString ("format:vector-uint8;"); break;
-        case eFormatVectorOfSInt16:  response.PutCString ("format:vector-sint16;"); break;
-        case eFormatVectorOfUInt16:  response.PutCString ("format:vector-uint16;"); break;
-        case eFormatVectorOfSInt32:  response.PutCString ("format:vector-sint32;"); break;
-        case eFormatVectorOfUInt32:  response.PutCString ("format:vector-uint32;"); break;
-        case eFormatVectorOfFloat32: response.PutCString ("format:vector-float32;"); break;
-        case eFormatVectorOfUInt128: response.PutCString ("format:vector-uint128;"); break;
-        default: break;
-    };
-
-    const char *const register_set_name = reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index);
-    if (register_set_name)
-    {
-        response.PutCString ("set:");
-        response.PutCString (register_set_name);
-        response.PutChar (';');
-    }
-
-    if (reg_info->kinds[RegisterKind::eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
-        response.Printf ("ehframe:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindEHFrame]);
-
-    if (reg_info->kinds[RegisterKind::eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
-        response.Printf ("dwarf:%" PRIu32 ";", reg_info->kinds[RegisterKind::eRegisterKindDWARF]);
-
-    switch (reg_info->kinds[RegisterKind::eRegisterKindGeneric])
-    {
-        case LLDB_REGNUM_GENERIC_PC:     response.PutCString("generic:pc;"); break;
-        case LLDB_REGNUM_GENERIC_SP:     response.PutCString("generic:sp;"); break;
-        case LLDB_REGNUM_GENERIC_FP:     response.PutCString("generic:fp;"); break;
-        case LLDB_REGNUM_GENERIC_RA:     response.PutCString("generic:ra;"); break;
-        case LLDB_REGNUM_GENERIC_FLAGS:  response.PutCString("generic:flags;"); break;
-        case LLDB_REGNUM_GENERIC_ARG1:   response.PutCString("generic:arg1;"); break;
-        case LLDB_REGNUM_GENERIC_ARG2:   response.PutCString("generic:arg2;"); break;
-        case LLDB_REGNUM_GENERIC_ARG3:   response.PutCString("generic:arg3;"); break;
-        case LLDB_REGNUM_GENERIC_ARG4:   response.PutCString("generic:arg4;"); break;
-        case LLDB_REGNUM_GENERIC_ARG5:   response.PutCString("generic:arg5;"); break;
-        case LLDB_REGNUM_GENERIC_ARG6:   response.PutCString("generic:arg6;"); break;
-        case LLDB_REGNUM_GENERIC_ARG7:   response.PutCString("generic:arg7;"); break;
-        case LLDB_REGNUM_GENERIC_ARG8:   response.PutCString("generic:arg8;"); break;
-        default: break;
-    }
-
-    if (reg_info->value_regs && reg_info->value_regs[0] != LLDB_INVALID_REGNUM)
-    {
-        response.PutCString ("container-regs:");
-        int i = 0;
-        for (const uint32_t *reg_num = reg_info->value_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i)
-        {
-            if (i > 0)
-                response.PutChar (',');
-            response.Printf ("%" PRIx32, *reg_num);
-        }
-        response.PutChar (';');
-    }
-
-    if (reg_info->invalidate_regs && reg_info->invalidate_regs[0])
-    {
-        response.PutCString ("invalidate-regs:");
-        int i = 0;
-        for (const uint32_t *reg_num = reg_info->invalidate_regs; *reg_num != LLDB_INVALID_REGNUM; ++reg_num, ++i)
-        {
-            if (i > 0)
-                response.PutChar (',');
-            response.Printf ("%" PRIx32, *reg_num);
-        }
-        response.PutChar (';');
-    }
-
-    if (reg_info->dynamic_size_dwarf_expr_bytes)
-    {
-       const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
-       response.PutCString("dynamic_size_dwarf_expr_bytes:");
-       for(uint32_t i = 0; i < dwarf_opcode_len; ++i)
-           response.PutHex8 (reg_info->dynamic_size_dwarf_expr_bytes[i]);
-       response.PutChar(';');
-    }
-    return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s() no process (%s), returning OK", __FUNCTION__, m_debugged_process_sp ? "invalid process id" : "null m_debugged_process_sp");
-        return SendOKResponse ();
-    }
-
-    StreamGDBRemote response;
-    response.PutChar ('m');
-
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s() starting thread iteration", __FUNCTION__);
-
-    NativeThreadProtocolSP thread_sp;
-    uint32_t thread_index;
-    for (thread_index = 0, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index);
-         thread_sp;
-         ++thread_index, thread_sp = m_debugged_process_sp->GetThreadAtIndex (thread_index))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s() iterated thread %" PRIu32 "(%s, tid=0x%" PRIx64 ")", __FUNCTION__, thread_index, thread_sp ? "is not null" : "null", thread_sp ? thread_sp->GetID () : LLDB_INVALID_THREAD_ID);
-        if (thread_index > 0)
-            response.PutChar(',');
-        response.Printf ("%" PRIx64, thread_sp->GetID ());
-    }
-
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s() finished thread iteration", __FUNCTION__);
-
-    return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo (StringExtractorGDBRemote &packet)
-{
-    // FIXME for now we return the full thread list in the initial packet and always do nothing here.
-    return SendPacketNoLock ("l");
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_p (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Parse out the register number from the request.
-    packet.SetFilePos (strlen("p"));
-    const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
-    if (reg_index == std::numeric_limits<uint32_t>::max ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
-        return SendErrorResponse (0x15);
-    }
-
-    // Get the thread to use.
-    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
-    if (!thread_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Get the thread's register context.
-    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
-    if (!reg_context_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
-        return SendErrorResponse (0x15);
-    }
-
-    // Return the end of registers response if we've iterated one past the end of the register set.
-    if (reg_index >= reg_context_sp->GetUserRegisterCount ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
-        return SendErrorResponse (0x15);
-    }
-
-    const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex(reg_index);
-    if (!reg_info)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index);
-        return SendErrorResponse (0x15);
-    }
-
-    // Build the reginfos response.
-    StreamGDBRemote response;
-
-    // Retrieve the value
-    RegisterValue reg_value;
-    Error error = reg_context_sp->ReadRegister (reg_info, reg_value);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, read of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ());
-        return SendErrorResponse (0x15);
-    }
-
-    const uint8_t *const data = reinterpret_cast<const uint8_t*> (reg_value.GetBytes ());
-    if (!data)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to get data bytes from requested register %" PRIu32, __FUNCTION__, reg_index);
-        return SendErrorResponse (0x15);
-    }
-
-    // FIXME flip as needed to get data in big/little endian format for this host.
-    for (uint32_t i = 0; i < reg_value.GetByteSize (); ++i)
-        response.PutHex8 (data[i]);
-
-    return SendPacketNoLock (response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_P (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Ensure there is more content.
-    if (packet.GetBytesLeft () < 1)
-        return SendIllFormedResponse (packet, "Empty P packet");
-
-    // Parse out the register number from the request.
-    packet.SetFilePos (strlen("P"));
-    const uint32_t reg_index = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
-    if (reg_index == std::numeric_limits<uint32_t>::max ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse register number from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
-        return SendErrorResponse (0x29);
-    }
-
-    // Note debugserver would send an E30 here.
-    if ((packet.GetBytesLeft () < 1) || (packet.GetChar () != '='))
-        return SendIllFormedResponse (packet, "P packet missing '=' char after register number");
-
-    // Get process architecture.
-    ArchSpec process_arch;
-    if (!m_debugged_process_sp || !m_debugged_process_sp->GetArchitecture (process_arch))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to retrieve inferior architecture", __FUNCTION__);
-        return SendErrorResponse (0x49);
-    }
-
-    // Parse out the value.
-    uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register
-    size_t reg_size = packet.GetHexBytesAvail (reg_bytes);
-
-    // Get the thread to use.
-    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
-    if (!thread_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no thread available (thread index 0)", __FUNCTION__);
-        return SendErrorResponse (0x28);
-    }
-
-    // Get the thread's register context.
-    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
-    if (!reg_context_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
-        return SendErrorResponse (0x15);
-    }
-
-    const RegisterInfo *reg_info = reg_context_sp->GetRegisterInfoAtIndex (reg_index);
-    if (!reg_info)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " returned NULL", __FUNCTION__, reg_index);
-        return SendErrorResponse (0x48);
-    }
-
-    // Return the end of registers response if we've iterated one past the end of the register set.
-    if (reg_index >= reg_context_sp->GetUserRegisterCount ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, requested register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, reg_context_sp->GetUserRegisterCount ());
-        return SendErrorResponse (0x47);
-    }
-
-    // The dwarf expression are evaluate on host site
-    // which may cause register size to change
-    // Hence the reg_size may not be same as reg_info->bytes_size
-    if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes))
-    {
-        return SendIllFormedResponse (packet, "P packet register size is incorrect");
-    }
-
-    // Build the reginfos response.
-    StreamGDBRemote response;
-
-    RegisterValue reg_value (reg_bytes, reg_size, process_arch.GetByteOrder ());
-    Error error = reg_context_sp->WriteRegister (reg_info, reg_value);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, write of requested register %" PRIu32 " (%s) failed: %s", __FUNCTION__, reg_index, reg_info->name, error.AsCString ());
-        return SendErrorResponse (0x32);
-    }
-
-    return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_H (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Parse out which variant of $H is requested.
-    packet.SetFilePos (strlen("H"));
-    if (packet.GetBytesLeft () < 1)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, H command missing {g,c} variant", __FUNCTION__);
-        return SendIllFormedResponse (packet, "H command missing {g,c} variant");
-    }
-
-    const char h_variant = packet.GetChar ();
-    switch (h_variant)
-    {
-        case 'g':
-            break;
-
-        case 'c':
-            break;
-
-        default:
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, invalid $H variant %c", __FUNCTION__, h_variant);
-            return SendIllFormedResponse (packet, "H variant unsupported, should be c or g");
-    }
-
-    // Parse out the thread number.
-    // FIXME return a parse success/fail value.  All values are valid here.
-    const lldb::tid_t tid = packet.GetHexMaxU64 (false, std::numeric_limits<lldb::tid_t>::max ());
-
-    // Ensure we have the given thread when not specifying -1 (all threads) or 0 (any thread).
-    if (tid != LLDB_INVALID_THREAD_ID && tid != 0)
-    {
-        NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
-        if (!thread_sp)
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 " not found", __FUNCTION__, tid);
-            return SendErrorResponse (0x15);
-        }
-    }
-
-    // Now switch the given thread type.
-    switch (h_variant)
-    {
-        case 'g':
-            SetCurrentThreadID (tid);
-            break;
-
-        case 'c':
-            SetContinueThreadID (tid);
-            break;
-
-        default:
-            assert (false && "unsupported $H variant - shouldn't get here");
-            return SendIllFormedResponse (packet, "H variant unsupported, should be c or g");
-    }
-
-    return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_I (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    packet.SetFilePos (::strlen("I"));
-    uint8_t tmp[4096];
-    for (;;)
-    {
-        size_t read = packet.GetHexBytesAvail(tmp);
-        if (read == 0)
-        {
-            break;
-        }
-        // write directly to stdin *this might block if stdin buffer is full*
-        // TODO: enqueue this block in circular buffer and send window size to remote host
-        ConnectionStatus status;
-        Error error;
-        m_stdio_communication.Write(tmp, read, status, &error);
-        if (error.Fail())
-        {
-            return SendErrorResponse (0x15);
-        }
-    }
-
-    return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_interrupt (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
-
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Interrupt the process.
-    Error error = m_debugged_process_sp->Interrupt ();
-    if (error.Fail ())
-    {
-        if (log)
-        {
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed for process %" PRIu64 ": %s",
-                         __FUNCTION__,
-                         m_debugged_process_sp->GetID (),
-                         error.AsCString ());
-        }
-        return SendErrorResponse (GDBRemoteServerError::eErrorResume);
-    }
-
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
-
-    // No response required from stop all.
-    return PacketResult::Success;
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_memory_read(StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Parse out the memory address.
-    packet.SetFilePos (strlen("m"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short m packet");
-
-    // Read the address.  Punting on validation.
-    // FIXME replace with Hex U64 read with no default value that fails on failed read.
-    const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
-
-    // Validate comma.
-    if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
-        return SendIllFormedResponse(packet, "Comma sep missing in m packet");
-
-    // Get # bytes to read.
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Length missing in m packet");
-
-    const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
-    if (byte_count == 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to read: zero-length packet", __FUNCTION__);
-        return SendOKResponse();
-    }
-
-    // Allocate the response buffer.
-    std::string buf(byte_count, '\0');
-    if (buf.empty())
-        return SendErrorResponse (0x78);
-
-
-    // Retrieve the process memory.
-    size_t bytes_read = 0;
-    Error error = m_debugged_process_sp->ReadMemoryWithoutTrap(read_addr, &buf[0], byte_count, bytes_read);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to read. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, error.AsCString ());
-        return SendErrorResponse (0x08);
-    }
-
-    if (bytes_read == 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": read 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), read_addr, byte_count);
-        return SendErrorResponse (0x08);
-    }
-
-    StreamGDBRemote response;
-    packet.SetFilePos(0);
-    char kind = packet.GetChar('?');
-    if (kind == 'x')
-        response.PutEscapedBytes(buf.data(), byte_count);
-    else
-    {
-        assert(kind == 'm');
-        for (size_t i = 0; i < bytes_read; ++i)
-            response.PutHex8(buf[i]);
-    }
-
-    return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_M (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Parse out the memory address.
-    packet.SetFilePos (strlen("M"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short M packet");
-
-    // Read the address.  Punting on validation.
-    // FIXME replace with Hex U64 read with no default value that fails on failed read.
-    const lldb::addr_t write_addr = packet.GetHexMaxU64(false, 0);
-
-    // Validate comma.
-    if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ','))
-        return SendIllFormedResponse(packet, "Comma sep missing in M packet");
-
-    // Get # bytes to read.
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Length missing in M packet");
-
-    const uint64_t byte_count = packet.GetHexMaxU64(false, 0);
-    if (byte_count == 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s nothing to write: zero-length packet", __FUNCTION__);
-        return PacketResult::Success;
-    }
-
-    // Validate colon.
-    if ((packet.GetBytesLeft() < 1) || (packet.GetChar() != ':'))
-        return SendIllFormedResponse(packet, "Comma sep missing in M packet after byte length");
-
-    // Allocate the conversion buffer.
-    std::vector<uint8_t> buf(byte_count, 0);
-    if (buf.empty())
-        return SendErrorResponse (0x78);
-
-    // Convert the hex memory write contents to bytes.
-    StreamGDBRemote response;
-    const uint64_t convert_count = packet.GetHexBytes(buf, 0);
-    if (convert_count != byte_count)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": asked to write %" PRIu64 " bytes, but only found %" PRIu64 " to convert.", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count, convert_count);
-        return SendIllFormedResponse (packet, "M content byte length specified did not match hex-encoded content length");
-    }
-
-    // Write the process memory.
-    size_t bytes_written = 0;
-    Error error = m_debugged_process_sp->WriteMemory (write_addr, &buf[0], byte_count, bytes_written);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": failed to write. Error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, error.AsCString ());
-        return SendErrorResponse (0x09);
-    }
-
-    if (bytes_written == 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " mem 0x%" PRIx64 ": wrote 0 of %" PRIu64 " requested bytes", __FUNCTION__, m_debugged_process_sp->GetID (), write_addr, byte_count);
-        return SendErrorResponse (0x09);
-    }
-
-    return SendOKResponse ();
-}
+  StreamString response;
+  const bool threads_with_valid_stop_info_only = false;
+  JSONArray::SP threads_array_sp = GetJSONThreadsInfo(
+      *m_debugged_process_sp, threads_with_valid_stop_info_only);
+  if (!threads_array_sp) {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to prepare a "
+                  "packet for pid %" PRIu64,
+                  __FUNCTION__, m_debugged_process_sp->GetID());
+    return SendErrorResponse(52);
+  }
+
+  threads_array_sp->Write(response);
+  StreamGDBRemote escaped_response;
+  escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
+  return SendPacketNoLock(escaped_response.GetString());
+}
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    // Currently only the NativeProcessProtocol knows if it can handle a qMemoryRegionInfoSupported
-    // request, but we're not guaranteed to be attached to a process.  For now we'll assume the
-    // client only asks this when a process is being debugged.
-
-    // Ensure we have a process running; otherwise, we can't figure this out
-    // since we won't have a NativeProcessProtocol.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Test if we can get any region back when asking for the region around NULL.
-    MemoryRegionInfo region_info;
-    const Error error = m_debugged_process_sp->GetMemoryRegionInfo (0, region_info);
-    if (error.Fail ())
-    {
-        // We don't support memory region info collection for this NativeProcessProtocol.
-        return SendUnimplementedResponse ("");
-    }
+GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo(
+    StringExtractorGDBRemote &packet) {
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(68);
 
+  packet.SetFilePos(strlen("qWatchpointSupportInfo"));
+  if (packet.GetBytesLeft() == 0)
     return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    // Ensure we have a process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
+  if (packet.GetChar() != ':')
+    return SendErrorResponse(67);
 
-    // Parse out the memory address.
-    packet.SetFilePos (strlen("qMemoryRegionInfo:"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
-
-    // Read the address.  Punting on validation.
-    const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
-
-    StreamGDBRemote response;
-
-    // Get the memory region info for the target address.
-    MemoryRegionInfo region_info;
-    const Error error = m_debugged_process_sp->GetMemoryRegionInfo (read_addr, region_info);
-    if (error.Fail ())
-    {
-        // Return the error message.
-
-        response.PutCString ("error:");
-        response.PutCStringAsRawHex8 (error.AsCString ());
-        response.PutChar (';');
-    }
-    else
-    {
-        // Range start and size.
-        response.Printf ("start:%" PRIx64 ";size:%" PRIx64 ";", region_info.GetRange ().GetRangeBase (), region_info.GetRange ().GetByteSize ());
-
-        // Permissions.
-        if (region_info.GetReadable () ||
-            region_info.GetWritable () ||
-            region_info.GetExecutable ())
-        {
-            // Write permissions info.
-            response.PutCString ("permissions:");
-
-            if (region_info.GetReadable ())
-                response.PutChar ('r');
-            if (region_info.GetWritable ())
-                response.PutChar('w');
-            if (region_info.GetExecutable())
-                response.PutChar ('x');
-
-            response.PutChar (';');
-        }
-
-        // Name
-        ConstString name = region_info.GetName();
-        if (name)
-        {
-            response.PutCString("name:");
-            response.PutCStringAsRawHex8(name.AsCString());
-            response.PutChar(';');
-        }
-    }
-
-    return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_Z (StringExtractorGDBRemote &packet)
-{
-    // Ensure we have a process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    // Parse out software or hardware breakpoint or watchpoint requested.
-    packet.SetFilePos (strlen("Z"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short Z packet, missing software/hardware specifier");
-
-    bool want_breakpoint = true;
-    bool want_hardware = false;
-    uint32_t watch_flags = 0;
-
-    const GDBStoppointType stoppoint_type =
-        GDBStoppointType(packet.GetS32 (eStoppointInvalid));
-    switch (stoppoint_type)
-    {
-        case eBreakpointSoftware:
-            want_hardware = false; want_breakpoint = true;  break;
-        case eBreakpointHardware:
-            want_hardware = true;  want_breakpoint = true;  break;
-        case eWatchpointWrite:
-            watch_flags = 1;
-            want_hardware = true;  want_breakpoint = false; break;
-        case eWatchpointRead:
-            watch_flags = 2;
-            want_hardware = true;  want_breakpoint = false; break;
-        case eWatchpointReadWrite:
-            watch_flags = 3;
-            want_hardware = true;  want_breakpoint = false; break;
-        case eStoppointInvalid:
-            return SendIllFormedResponse(packet, "Z packet had invalid software/hardware specifier");
-
-    }
-
-    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
-        return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type");
-
-    // Parse out the stoppoint address.
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short Z packet, missing address");
-    const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
-
-    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
-        return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after address");
-
-    // Parse out the stoppoint size (i.e. size hint for opcode size).
-    const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
-    if (size == std::numeric_limits<uint32_t>::max ())
-        return SendIllFormedResponse(packet, "Malformed Z packet, failed to parse size argument");
-
-    if (want_breakpoint)
-    {
-        // Try to set the breakpoint.
-        const Error error = m_debugged_process_sp->SetBreakpoint (addr, size, want_hardware);
-        if (error.Success ())
-            return SendOKResponse ();
-        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-                    " failed to set breakpoint: %s",
-                    __FUNCTION__,
-                    m_debugged_process_sp->GetID (),
-                    error.AsCString ());
-        return SendErrorResponse (0x09);
-    }
-    else
-    {
-        // Try to set the watchpoint.
-        const Error error = m_debugged_process_sp->SetWatchpoint (
-                addr, size, watch_flags, want_hardware);
-        if (error.Success ())
-            return SendOKResponse ();
-        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-                    " failed to set watchpoint: %s",
-                    __FUNCTION__,
-                    m_debugged_process_sp->GetID (),
-                    error.AsCString ());
-        return SendErrorResponse (0x09);
-    }
+  uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
+  StreamGDBRemote response;
+  response.Printf("num:%d;", num);
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_z (StringExtractorGDBRemote &packet)
-{
-    // Ensure we have a process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
+GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress(
+    StringExtractorGDBRemote &packet) {
+  // Fail if we don't have a current process.
+  if (!m_debugged_process_sp ||
+      m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(67);
 
-    // Parse out software or hardware breakpoint or watchpoint requested.
-    packet.SetFilePos (strlen("z"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short z packet, missing software/hardware specifier");
-
-    bool want_breakpoint = true;
-
-    const GDBStoppointType stoppoint_type =
-        GDBStoppointType(packet.GetS32 (eStoppointInvalid));
-    switch (stoppoint_type)
-    {
-        case eBreakpointHardware:  want_breakpoint = true;  break;
-        case eBreakpointSoftware:  want_breakpoint = true;  break;
-        case eWatchpointWrite:     want_breakpoint = false; break;
-        case eWatchpointRead:      want_breakpoint = false; break;
-        case eWatchpointReadWrite: want_breakpoint = false; break;
-        default:
-            return SendIllFormedResponse(packet, "z packet had invalid software/hardware specifier");
+  packet.SetFilePos(strlen("qFileLoadAddress:"));
+  if (packet.GetBytesLeft() == 0)
+    return SendErrorResponse(68);
 
-    }
-
-    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
-        return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after stoppoint type");
-
-    // Parse out the stoppoint address.
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short z packet, missing address");
-    const lldb::addr_t addr = packet.GetHexMaxU64(false, 0);
-
-    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
-        return SendIllFormedResponse(packet, "Malformed z packet, expecting comma after address");
-
-    /*
-    // Parse out the stoppoint size (i.e. size hint for opcode size).
-    const uint32_t size = packet.GetHexMaxU32 (false, std::numeric_limits<uint32_t>::max ());
-    if (size == std::numeric_limits<uint32_t>::max ())
-        return SendIllFormedResponse(packet, "Malformed z packet, failed to parse size argument");
-    */
-
-    if (want_breakpoint)
-    {
-        // Try to clear the breakpoint.
-        const Error error = m_debugged_process_sp->RemoveBreakpoint (addr);
-        if (error.Success ())
-            return SendOKResponse ();
-        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-                    " failed to remove breakpoint: %s",
-                    __FUNCTION__,
-                    m_debugged_process_sp->GetID (),
-                    error.AsCString ());
-        return SendErrorResponse (0x09);
-    }
-    else
-    {
-        // Try to clear the watchpoint.
-        const Error error = m_debugged_process_sp->RemoveWatchpoint (addr);
-        if (error.Success ())
-            return SendOKResponse ();
-        Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
-                    " failed to remove watchpoint: %s",
-                    __FUNCTION__,
-                    m_debugged_process_sp->GetID (),
-                    error.AsCString ());
-        return SendErrorResponse (0x09);
-    }
-}
+  std::string file_name;
+  packet.GetHexByteString(file_name);
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_s (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
+  lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
+  Error error =
+      m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
+  if (error.Fail())
+    return SendErrorResponse(69);
 
-    // Ensure we have a process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x32);
-    }
+  if (file_load_address == LLDB_INVALID_ADDRESS)
+    return SendErrorResponse(1); // File not loaded
 
-    // We first try to use a continue thread id.  If any one or any all set, use the current thread.
-    // Bail out if we don't have a thread id.
-    lldb::tid_t tid = GetContinueThreadID ();
-    if (tid == 0 || tid == LLDB_INVALID_THREAD_ID)
-        tid = GetCurrentThreadID ();
-    if (tid == LLDB_INVALID_THREAD_ID)
-        return SendErrorResponse (0x33);
-
-    // Double check that we have such a thread.
-    // TODO investigate: on MacOSX we might need to do an UpdateThreads () here.
-    NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetThreadByID (tid);
-    if (!thread_sp || thread_sp->GetID () != tid)
-        return SendErrorResponse (0x33);
-
-    // Create the step action for the given thread.
-    ResumeAction action = { tid, eStateStepping, 0 };
-
-    // Setup the actions list.
-    ResumeActionList actions;
-    actions.Append (action);
-
-    // All other threads stop while we're single stepping a thread.
-    actions.SetDefaultThreadActionIfNeeded(eStateStopped, 0);
-    Error error = m_debugged_process_sp->Resume (actions);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " Resume() failed with error: %s", __FUNCTION__, m_debugged_process_sp->GetID (), tid, error.AsCString ());
-        return SendErrorResponse(0x49);
-    }
-
-    // No response here - the stop or exit will come from the resulting action.
-    return PacketResult::Success;
+  StreamGDBRemote response;
+  response.PutHex64(file_load_address);
+  return SendPacketNoLock(response.GetString());
 }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet)
-{
-    // *BSD impls should be able to do this too.
-#if defined(__linux__)
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    // Parse out the offset.
-    packet.SetFilePos (strlen("qXfer:auxv:read::"));
-    if (packet.GetBytesLeft () < 1)
-        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset");
-
-    const uint64_t auxv_offset = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ());
-    if (auxv_offset == std::numeric_limits<uint64_t>::max ())
-        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing offset");
-
-    // Parse out comma.
-    if (packet.GetBytesLeft () < 1 || packet.GetChar () != ',')
-        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing comma after offset");
-
-    // Parse out the length.
-    const uint64_t auxv_length = packet.GetHexMaxU64 (false, std::numeric_limits<uint64_t>::max ());
-    if (auxv_length == std::numeric_limits<uint64_t>::max ())
-        return SendIllFormedResponse (packet, "qXfer:auxv:read:: packet missing length");
-
-    // Grab the auxv data if we need it.
-    if (!m_active_auxv_buffer_sp)
-    {
-        // Make sure we have a valid process.
-        if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-            return SendErrorResponse (0x10);
-        }
+  // Tell the stdio connection to shut down.
+  if (m_stdio_communication.IsConnected()) {
+    auto connection = m_stdio_communication.GetConnection();
+    if (connection) {
+      Error error;
+      connection->Disconnect(&error);
 
-        // Grab the auxv data.
-        m_active_auxv_buffer_sp = Host::GetAuxvData (m_debugged_process_sp->GetID ());
-        if (!m_active_auxv_buffer_sp || m_active_auxv_buffer_sp->GetByteSize () ==  0)
-        {
-            // Hmm, no auxv data, call that an error.
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no auxv data retrieved", __FUNCTION__);
-            m_active_auxv_buffer_sp.reset ();
-            return SendErrorResponse (0x11);
-        }
-    }
-
-    // FIXME find out if/how I lock the stream here.
-
-    StreamGDBRemote response;
-    bool done_with_buffer = false;
-
-    if (auxv_offset >= m_active_auxv_buffer_sp->GetByteSize ())
-    {
-        // We have nothing left to send.  Mark the buffer as complete.
-        response.PutChar ('l');
-        done_with_buffer = true;
-    }
-    else
-    {
-        // Figure out how many bytes are available starting at the given offset.
-        const uint64_t bytes_remaining = m_active_auxv_buffer_sp->GetByteSize () - auxv_offset;
-
-        // Figure out how many bytes we're going to read.
-        const uint64_t bytes_to_read = (auxv_length > bytes_remaining) ? bytes_remaining : auxv_length;
-
-        // Mark the response type according to whether we're reading the remainder of the auxv data.
-        if (bytes_to_read >= bytes_remaining)
-        {
-            // There will be nothing left to read after this
-            response.PutChar ('l');
-            done_with_buffer = true;
-        }
-        else
-        {
-            // There will still be bytes to read after this request.
-            response.PutChar ('m');
-        }
-
-        // Now write the data in encoded binary form.
-        response.PutEscapedBytes (m_active_auxv_buffer_sp->GetBytes () + auxv_offset, bytes_to_read);
-    }
-
-    if (done_with_buffer)
-        m_active_auxv_buffer_sp.reset ();
-
-    return SendPacketNoLock(response.GetString());
-#else
-    return SendUnimplementedResponse ("not implemented on this platform");
-#endif
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Move past packet name.
-    packet.SetFilePos (strlen ("QSaveRegisterState"));
-
-    // Get the thread to use.
-    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
-    if (!thread_sp)
-    {
-        if (m_thread_suffix_supported)
-            return SendIllFormedResponse (packet, "No thread specified in QSaveRegisterState packet");
-        else
-            return SendIllFormedResponse (packet, "No thread was is set with the Hg packet");
-    }
-
-    // Grab the register context for the thread.
-    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
-    if (!reg_context_sp)
-    {
+      if (error.Success()) {
         if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
-        return SendErrorResponse (0x15);
-    }
-
-    // Save registers to a buffer.
-    DataBufferSP register_data_sp;
-    Error error = reg_context_sp->ReadAllRegisterValues (register_data_sp);
-    if (error.Fail ())
-    {
+          log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
+                      "terminal stdio - SUCCESS",
+                      __FUNCTION__);
+      } else {
         if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to save all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
-        return SendErrorResponse (0x75);
-    }
-
-    // Allocate a new save id.
-    const uint32_t save_id = GetNextSavedRegistersID ();
-    assert ((m_saved_registers_map.find (save_id) == m_saved_registers_map.end ()) && "GetNextRegisterSaveID() returned an existing register save id");
-
-    // Save the register data buffer under the save id.
-    {
-        std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
-        m_saved_registers_map[save_id] = register_data_sp;
+          log->Printf("GDBRemoteCommunicationServerLLGS::%s disconnect process "
+                      "terminal stdio - FAIL: %s",
+                      __FUNCTION__, error.AsCString());
+      }
     }
-
-    // Write the response.
-    StreamGDBRemote response;
-    response.Printf ("%" PRIu32, save_id);
-    return SendPacketNoLock(response.GetString());
+  }
 }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Parse out save id.
-    packet.SetFilePos (strlen ("QRestoreRegisterState:"));
-    if (packet.GetBytesLeft () < 1)
-        return SendIllFormedResponse (packet, "QRestoreRegisterState packet missing register save id");
-
-    const uint32_t save_id = packet.GetU32 (0);
-    if (save_id == 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s QRestoreRegisterState packet has malformed save id, expecting decimal uint32_t", __FUNCTION__);
-        return SendErrorResponse (0x76);
-    }
+NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+    StringExtractorGDBRemote &packet) {
+  NativeThreadProtocolSP thread_sp;
 
-    // Get the thread to use.
-    NativeThreadProtocolSP thread_sp = GetThreadFromSuffix (packet);
-    if (!thread_sp)
-    {
-        if (m_thread_suffix_supported)
-            return SendIllFormedResponse (packet, "No thread specified in QRestoreRegisterState packet");
-        else
-            return SendIllFormedResponse (packet, "No thread was is set with the Hg packet");
-    }
-
-    // Grab the register context for the thread.
-    NativeRegisterContextSP reg_context_sp (thread_sp->GetRegisterContext ());
-    if (!reg_context_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 " failed, no register context available for the thread", __FUNCTION__, m_debugged_process_sp->GetID (), thread_sp->GetID ());
-        return SendErrorResponse (0x15);
-    }
-
-    // Retrieve register state buffer, then remove from the list.
-    DataBufferSP register_data_sp;
-    {
-        std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
-
-        // Find the register set buffer for the given save id.
-        auto it = m_saved_registers_map.find (save_id);
-        if (it == m_saved_registers_map.end ())
-        {
-            if (log)
-                log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " does not have a register set save buffer for id %" PRIu32, __FUNCTION__, m_debugged_process_sp->GetID (), save_id);
-            return SendErrorResponse (0x77);
-        }
-        register_data_sp = it->second;
-
-        // Remove it from the map.
-        m_saved_registers_map.erase (it);
-    }
-
-    Error error = reg_context_sp->WriteAllRegisterValues (register_data_sp);
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " failed to restore all register values: %s", __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
-        return SendErrorResponse (0x77);
-    }
-
-    return SendOKResponse();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vAttach (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    // Consume the ';' after vAttach.
-    packet.SetFilePos (strlen ("vAttach"));
-    if (!packet.GetBytesLeft () || packet.GetChar () != ';')
-        return SendIllFormedResponse (packet, "vAttach missing expected ';'");
-
-    // Grab the PID to which we will attach (assume hex encoding).
-    lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16);
-    if (pid == LLDB_INVALID_PROCESS_ID)
-        return SendIllFormedResponse (packet, "vAttach failed to parse the process id");
-
-    // Attempt to attach.
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s attempting to attach to pid %" PRIu64, __FUNCTION__, pid);
-
-    Error error = AttachToProcess (pid);
-
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to attach to pid %" PRIu64 ": %s\n", __FUNCTION__, pid, error.AsCString());
-        return SendErrorResponse (0x01);
-    }
-
-    // Notify we attached by sending a stop packet.
-    return SendStopReasonForState (m_debugged_process_sp->GetState ());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
-
-    StopSTDIOForwarding();
-
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, no process available", __FUNCTION__);
-        return SendErrorResponse (0x15);
-    }
-
-    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-
-    // Consume the ';' after D.
-    packet.SetFilePos (1);
-    if (packet.GetBytesLeft ())
-    {
-        if (packet.GetChar () != ';')
-            return SendIllFormedResponse (packet, "D missing expected ';'");
-
-        // Grab the PID from which we will detach (assume hex encoding).
-        pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID, 16);
-        if (pid == LLDB_INVALID_PROCESS_ID)
-            return SendIllFormedResponse (packet, "D failed to parse the process id");
-    }
-
-    if (pid != LLDB_INVALID_PROCESS_ID &&
-        m_debugged_process_sp->GetID () != pid)
-    {
-        return SendIllFormedResponse (packet, "Invalid pid");
-    }
-
-    const Error error = m_debugged_process_sp->Detach ();
-    if (error.Fail ())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to detach from pid %" PRIu64 ": %s\n",
-                         __FUNCTION__, m_debugged_process_sp->GetID (), error.AsCString ());
-        return SendErrorResponse (0x01);
-    }
-
-    return SendOKResponse ();
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    packet.SetFilePos (strlen("qThreadStopInfo"));
-    const lldb::tid_t tid = packet.GetHexMaxU32 (false, LLDB_INVALID_THREAD_ID);
-    if (tid == LLDB_INVALID_THREAD_ID)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed, could not parse thread id from request \"%s\"", __FUNCTION__, packet.GetStringRef ().c_str ());
-        return SendErrorResponse (0x15);
-    }
-    return SendStopReplyPacketForThread (tid);
-}
+  // We have no thread if we don't have a process.
+  if (!m_debugged_process_sp ||
+      m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID)
+    return thread_sp;
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo (StringExtractorGDBRemote &)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+  // If the client hasn't asked for thread suffix support, there will not be a
+  // thread suffix.
+  // Use the current thread in that case.
+  if (!m_thread_suffix_supported) {
+    const lldb::tid_t current_tid = GetCurrentThreadID();
+    if (current_tid == LLDB_INVALID_THREAD_ID)
+      return thread_sp;
+    else if (current_tid == 0) {
+      // Pick a thread.
+      return m_debugged_process_sp->GetThreadAtIndex(0);
+    } else
+      return m_debugged_process_sp->GetThreadByID(current_tid);
+  }
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Parse out the ';'.
+  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
+    if (log)
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+                  "error: expected ';' prior to start of thread suffix: packet "
+                  "contents = '%s'",
+                  __FUNCTION__, packet.GetStringRef().c_str());
+    return thread_sp;
+  }
 
-    // Ensure we have a debugged process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (50);
+  if (!packet.GetBytesLeft())
+    return thread_sp;
 
+  // Parse out thread: portion.
+  if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) {
     if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64,
-                __FUNCTION__, m_debugged_process_sp->GetID());
-
-
-    StreamString response;
-    const bool threads_with_valid_stop_info_only = false;
-    JSONArray::SP threads_array_sp = GetJSONThreadsInfo(*m_debugged_process_sp,
-                                                        threads_with_valid_stop_info_only);
-    if (! threads_array_sp)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s failed to prepare a packet for pid %" PRIu64,
-                    __FUNCTION__, m_debugged_process_sp->GetID());
-        return SendErrorResponse(52);
-    }
-
-    threads_array_sp->Write(response);
-    StreamGDBRemote escaped_response;
-    escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
-    return SendPacketNoLock (escaped_response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet)
-{
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp ||
-            m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
-        return SendErrorResponse (68);
-
-    packet.SetFilePos(strlen("qWatchpointSupportInfo"));
-    if (packet.GetBytesLeft() == 0)
-        return SendOKResponse();
-    if (packet.GetChar() != ':')
-        return SendErrorResponse(67);
-
-    uint32_t num = m_debugged_process_sp->GetMaxWatchpoints();
-    StreamGDBRemote response;
-    response.Printf ("num:%d;", num);
-    return SendPacketNoLock(response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress (StringExtractorGDBRemote &packet)
-{
-    // Fail if we don't have a current process.
-    if (!m_debugged_process_sp ||
-            m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
-        return SendErrorResponse(67);
-
-    packet.SetFilePos(strlen("qFileLoadAddress:"));
-    if (packet.GetBytesLeft() == 0)
-        return SendErrorResponse(68);
-
-    std::string file_name;
-    packet.GetHexByteString(file_name);
-
-    lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
-    Error error = m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
-    if (error.Fail())
-        return SendErrorResponse(69);
-
-    if (file_load_address == LLDB_INVALID_ADDRESS)
-        return SendErrorResponse(1); // File not loaded
-
-    StreamGDBRemote response;
-    response.PutHex64(file_load_address);
-    return SendPacketNoLock(response.GetString());
-}
-
-void
-GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    // Tell the stdio connection to shut down.
-    if (m_stdio_communication.IsConnected())
-    {
-        auto connection = m_stdio_communication.GetConnection();
-        if (connection)
-        {
-            Error error;
-            connection->Disconnect (&error);
-
-            if (error.Success ())
-            {
-                if (log)
-                    log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - SUCCESS", __FUNCTION__);
-            }
-            else
-            {
-                if (log)
-                    log->Printf ("GDBRemoteCommunicationServerLLGS::%s disconnect process terminal stdio - FAIL: %s", __FUNCTION__, error.AsCString ());
-            }
-        }
-    }
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse "
+                  "error: expected 'thread:' but not found, packet contents = "
+                  "'%s'",
+                  __FUNCTION__, packet.GetStringRef().c_str());
+    return thread_sp;
+  }
+  packet.SetFilePos(packet.GetFilePos() + strlen("thread:"));
+  const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
+  if (tid != 0)
+    return m_debugged_process_sp->GetThreadByID(tid);
+
+  return thread_sp;
 }
 
-
-NativeThreadProtocolSP
-GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix (StringExtractorGDBRemote &packet)
-{
-    NativeThreadProtocolSP thread_sp;
-
-    // We have no thread if we don't have a process.
-    if (!m_debugged_process_sp || m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
-        return thread_sp;
-
-    // If the client hasn't asked for thread suffix support, there will not be a thread suffix.
-    // Use the current thread in that case.
-    if (!m_thread_suffix_supported)
-    {
-        const lldb::tid_t current_tid = GetCurrentThreadID ();
-        if (current_tid == LLDB_INVALID_THREAD_ID)
-            return thread_sp;
-        else if (current_tid == 0)
-        {
-            // Pick a thread.
-            return m_debugged_process_sp->GetThreadAtIndex (0);
-        }
-        else
-            return m_debugged_process_sp->GetThreadByID (current_tid);
-    }
-
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-
-    // Parse out the ';'.
-    if (packet.GetBytesLeft () < 1 || packet.GetChar () != ';')
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected ';' prior to start of thread suffix: packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
-        return thread_sp;
-    }
-
-    if (!packet.GetBytesLeft ())
-        return thread_sp;
-
-    // Parse out thread: portion.
-    if (strncmp (packet.Peek (), "thread:", strlen("thread:")) != 0)
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunicationServerLLGS::%s gdb-remote parse error: expected 'thread:' but not found, packet contents = '%s'", __FUNCTION__, packet.GetStringRef ().c_str ());
-        return thread_sp;
-    }
-    packet.SetFilePos (packet.GetFilePos () + strlen("thread:"));
-    const lldb::tid_t tid = packet.GetHexMaxU64(false, 0);
-    if (tid != 0)
-        return m_debugged_process_sp->GetThreadByID (tid);
-
-    return thread_sp;
+lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const {
+  if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) {
+    // Use whatever the debug process says is the current thread id
+    // since the protocol either didn't specify or specified we want
+    // any/all threads marked as the current thread.
+    if (!m_debugged_process_sp)
+      return LLDB_INVALID_THREAD_ID;
+    return m_debugged_process_sp->GetCurrentThreadID();
+  }
+  // Use the specific current thread id set by the gdb remote protocol.
+  return m_current_tid;
 }
 
-lldb::tid_t
-GDBRemoteCommunicationServerLLGS::GetCurrentThreadID () const
-{
-    if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID)
-    {
-        // Use whatever the debug process says is the current thread id
-        // since the protocol either didn't specify or specified we want
-        // any/all threads marked as the current thread.
-        if (!m_debugged_process_sp)
-            return LLDB_INVALID_THREAD_ID;
-        return m_debugged_process_sp->GetCurrentThreadID ();
-    }
-    // Use the specific current thread id set by the gdb remote protocol.
-    return m_current_tid;
-}
-
-uint32_t
-GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID ()
-{
-    std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
-    return m_next_saved_registers_id++;
+uint32_t GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID() {
+  std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
+  return m_next_saved_registers_id++;
 }
 
-void
-GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
+void GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData() {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
 
-    // Clear any auxv cached data.
-    // *BSD impls should be able to do this too.
+// Clear any auxv cached data.
+// *BSD impls should be able to do this too.
 #if defined(__linux__)
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer (previously %s)",
-                     __FUNCTION__,
-                     m_active_auxv_buffer_sp ? "was set" : "was not set");
-    m_active_auxv_buffer_sp.reset ();
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s clearing auxv buffer "
+                "(previously %s)",
+                __FUNCTION__,
+                m_active_auxv_buffer_sp ? "was set" : "was not set");
+  m_active_auxv_buffer_sp.reset();
 #endif
 }
 
 FileSpec
-GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string& module_path,
-                                                 const ArchSpec& arch)
-{
-    if (m_debugged_process_sp)
-    {
-        FileSpec file_spec;
-        if (m_debugged_process_sp->GetLoadedModuleFileSpec(module_path.c_str(), file_spec).Success())
-        {
-            if (file_spec.Exists())
-                return file_spec;
-        }
+GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path,
+                                                 const ArchSpec &arch) {
+  if (m_debugged_process_sp) {
+    FileSpec file_spec;
+    if (m_debugged_process_sp
+            ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec)
+            .Success()) {
+      if (file_spec.Exists())
+        return file_spec;
     }
+  }
 
-    return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
+  return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h Tue Sep  6 15:57:50 2016
@@ -16,10 +16,10 @@
 #include <unordered_map>
 
 // Other libraries and framework includes
-#include "lldb/lldb-private-forward.h"
 #include "lldb/Core/Communication.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
 #include "lldb/Host/MainLoop.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
+#include "lldb/lldb-private-forward.h"
 
 // Project includes
 #include "GDBRemoteCommunicationServerCommon.h"
@@ -32,282 +32,220 @@ namespace process_gdb_remote {
 
 class ProcessGDBRemote;
 
-class GDBRemoteCommunicationServerLLGS :
-    public GDBRemoteCommunicationServerCommon,
-    public NativeProcessProtocol::NativeDelegate
-{
+class GDBRemoteCommunicationServerLLGS
+    : public GDBRemoteCommunicationServerCommon,
+      public NativeProcessProtocol::NativeDelegate {
 public:
-    //------------------------------------------------------------------
-    // Constructors and Destructors
-    //------------------------------------------------------------------
-    GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
-
-    //------------------------------------------------------------------
-    /// Specify the program to launch and its arguments.
-    ///
-    /// @param[in] args
-    ///     The command line to launch.
-    ///
-    /// @param[in] argc
-    ///     The number of elements in the args array of cstring pointers.
-    ///
-    /// @return
-    ///     An Error object indicating the success or failure of making
-    ///     the setting.
-    //------------------------------------------------------------------
-    Error
-    SetLaunchArguments (const char *const args[], int argc);
-
-    //------------------------------------------------------------------
-    /// Specify the launch flags for the process.
-    ///
-    /// @param[in] launch_flags
-    ///     The launch flags to use when launching this process.
-    ///
-    /// @return
-    ///     An Error object indicating the success or failure of making
-    ///     the setting.
-    //------------------------------------------------------------------
-    Error
-    SetLaunchFlags (unsigned int launch_flags);
-
-    //------------------------------------------------------------------
-    /// Launch a process with the current launch settings.
-    ///
-    /// This method supports running an lldb-gdbserver or similar
-    /// server in a situation where the startup code has been provided
-    /// with all the information for a child process to be launched.
-    ///
-    /// @return
-    ///     An Error object indicating the success or failure of the
-    ///     launch.
-    //------------------------------------------------------------------
-    Error
-    LaunchProcess () override;
-
-    //------------------------------------------------------------------
-    /// Attach to a process.
-    ///
-    /// This method supports attaching llgs to a process accessible via the
-    /// configured Platform.
-    ///
-    /// @return
-    ///     An Error object indicating the success or failure of the
-    ///     attach operation.
-    //------------------------------------------------------------------
-    Error
-    AttachToProcess (lldb::pid_t pid);
-
-    //------------------------------------------------------------------
-    // NativeProcessProtocol::NativeDelegate overrides
-    //------------------------------------------------------------------
-    void
-    InitializeDelegate (NativeProcessProtocol *process) override;
+  //------------------------------------------------------------------
+  // Constructors and Destructors
+  //------------------------------------------------------------------
+  GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
+
+  //------------------------------------------------------------------
+  /// Specify the program to launch and its arguments.
+  ///
+  /// @param[in] args
+  ///     The command line to launch.
+  ///
+  /// @param[in] argc
+  ///     The number of elements in the args array of cstring pointers.
+  ///
+  /// @return
+  ///     An Error object indicating the success or failure of making
+  ///     the setting.
+  //------------------------------------------------------------------
+  Error SetLaunchArguments(const char *const args[], int argc);
+
+  //------------------------------------------------------------------
+  /// Specify the launch flags for the process.
+  ///
+  /// @param[in] launch_flags
+  ///     The launch flags to use when launching this process.
+  ///
+  /// @return
+  ///     An Error object indicating the success or failure of making
+  ///     the setting.
+  //------------------------------------------------------------------
+  Error SetLaunchFlags(unsigned int launch_flags);
+
+  //------------------------------------------------------------------
+  /// Launch a process with the current launch settings.
+  ///
+  /// This method supports running an lldb-gdbserver or similar
+  /// server in a situation where the startup code has been provided
+  /// with all the information for a child process to be launched.
+  ///
+  /// @return
+  ///     An Error object indicating the success or failure of the
+  ///     launch.
+  //------------------------------------------------------------------
+  Error LaunchProcess() override;
+
+  //------------------------------------------------------------------
+  /// Attach to a process.
+  ///
+  /// This method supports attaching llgs to a process accessible via the
+  /// configured Platform.
+  ///
+  /// @return
+  ///     An Error object indicating the success or failure of the
+  ///     attach operation.
+  //------------------------------------------------------------------
+  Error AttachToProcess(lldb::pid_t pid);
+
+  //------------------------------------------------------------------
+  // NativeProcessProtocol::NativeDelegate overrides
+  //------------------------------------------------------------------
+  void InitializeDelegate(NativeProcessProtocol *process) override;
 
-    void
-    ProcessStateChanged (NativeProcessProtocol *process, lldb::StateType state) override;
+  void ProcessStateChanged(NativeProcessProtocol *process,
+                           lldb::StateType state) override;
 
-    void
-    DidExec (NativeProcessProtocol *process) override;
+  void DidExec(NativeProcessProtocol *process) override;
 
-    Error
-    InitializeConnection (std::unique_ptr<Connection> &&connection);
+  Error InitializeConnection(std::unique_ptr<Connection> &&connection);
 
 protected:
-    MainLoop &m_mainloop;
-    MainLoop::ReadHandleUP m_network_handle_up;
-    lldb::tid_t m_current_tid;
-    lldb::tid_t m_continue_tid;
-    std::recursive_mutex m_debugged_process_mutex;
-    NativeProcessProtocolSP m_debugged_process_sp;
+  MainLoop &m_mainloop;
+  MainLoop::ReadHandleUP m_network_handle_up;
+  lldb::tid_t m_current_tid;
+  lldb::tid_t m_continue_tid;
+  std::recursive_mutex m_debugged_process_mutex;
+  NativeProcessProtocolSP m_debugged_process_sp;
 
-    Communication m_stdio_communication;
-    MainLoop::ReadHandleUP m_stdio_handle_up;
+  Communication m_stdio_communication;
+  MainLoop::ReadHandleUP m_stdio_handle_up;
 
-    lldb::StateType m_inferior_prev_state;
-    lldb::DataBufferSP m_active_auxv_buffer_sp;
-    std::mutex m_saved_registers_mutex;
-    std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
-    uint32_t m_next_saved_registers_id;
-    bool m_handshake_completed : 1;
+  lldb::StateType m_inferior_prev_state;
+  lldb::DataBufferSP m_active_auxv_buffer_sp;
+  std::mutex m_saved_registers_mutex;
+  std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
+  uint32_t m_next_saved_registers_id;
+  bool m_handshake_completed : 1;
 
-    PacketResult
-    SendONotification (const char *buffer, uint32_t len);
+  PacketResult SendONotification(const char *buffer, uint32_t len);
 
-    PacketResult
-    SendWResponse (NativeProcessProtocol *process);
+  PacketResult SendWResponse(NativeProcessProtocol *process);
 
-    PacketResult
-    SendStopReplyPacketForThread (lldb::tid_t tid);
+  PacketResult SendStopReplyPacketForThread(lldb::tid_t tid);
 
-    PacketResult
-    SendStopReasonForState (lldb::StateType process_state);
+  PacketResult SendStopReasonForState(lldb::StateType process_state);
 
-    PacketResult
-    Handle_k (StringExtractorGDBRemote &packet);
+  PacketResult Handle_k(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qProcessInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qC (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qC(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetDisableASLR(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_C (StringExtractorGDBRemote &packet);
+  PacketResult Handle_C(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_c (StringExtractorGDBRemote &packet);
+  PacketResult Handle_c(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vCont (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vCont(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vCont_actions (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vCont_actions(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_stop_reason (StringExtractorGDBRemote &packet);
+  PacketResult Handle_stop_reason(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qRegisterInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qfThreadInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qsThreadInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_p (StringExtractorGDBRemote &packet);
+  PacketResult Handle_p(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_P (StringExtractorGDBRemote &packet);
+  PacketResult Handle_P(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_H (StringExtractorGDBRemote &packet);
+  PacketResult Handle_H(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_I (StringExtractorGDBRemote &packet);
+  PacketResult Handle_I(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_interrupt (StringExtractorGDBRemote &packet);
+  PacketResult Handle_interrupt(StringExtractorGDBRemote &packet);
 
-    // Handles $m and $x packets.
-    PacketResult
-    Handle_memory_read (StringExtractorGDBRemote &packet);
+  // Handles $m and $x packets.
+  PacketResult Handle_memory_read(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_M (StringExtractorGDBRemote &packet);
+  PacketResult Handle_M(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet);
+  PacketResult
+  Handle_qMemoryRegionInfoSupported(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qMemoryRegionInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qMemoryRegionInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_Z (StringExtractorGDBRemote &packet);
+  PacketResult Handle_Z(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_z (StringExtractorGDBRemote &packet);
+  PacketResult Handle_z(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_s (StringExtractorGDBRemote &packet);
+  PacketResult Handle_s(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qXfer_auxv_read (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qXfer_auxv_read(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSaveRegisterState (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QRestoreRegisterState (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_vAttach (StringExtractorGDBRemote &packet);
+  PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_D (StringExtractorGDBRemote &packet);
+  PacketResult Handle_D(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qThreadStopInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_jThreadsInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_jThreadsInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qWatchpointSupportInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qFileLoadAddress (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qFileLoadAddress(StringExtractorGDBRemote &packet);
 
-    void
-    SetCurrentThreadID (lldb::tid_t tid);
+  void SetCurrentThreadID(lldb::tid_t tid);
 
-    lldb::tid_t
-    GetCurrentThreadID () const;
+  lldb::tid_t GetCurrentThreadID() const;
 
-    void
-    SetContinueThreadID (lldb::tid_t tid);
+  void SetContinueThreadID(lldb::tid_t tid);
 
-    lldb::tid_t
-    GetContinueThreadID () const { return m_continue_tid; }
+  lldb::tid_t GetContinueThreadID() const { return m_continue_tid; }
 
-    Error
-    SetSTDIOFileDescriptor (int fd);
+  Error SetSTDIOFileDescriptor(int fd);
 
-    FileSpec
-    FindModuleFile (const std::string& module_path, const ArchSpec& arch) override;
+  FileSpec FindModuleFile(const std::string &module_path,
+                          const ArchSpec &arch) override;
 
 private:
-    void
-    HandleInferiorState_Exited (NativeProcessProtocol *process);
+  void HandleInferiorState_Exited(NativeProcessProtocol *process);
 
-    void
-    HandleInferiorState_Stopped (NativeProcessProtocol *process);
+  void HandleInferiorState_Stopped(NativeProcessProtocol *process);
 
-    NativeThreadProtocolSP
-    GetThreadFromSuffix (StringExtractorGDBRemote &packet);
+  NativeThreadProtocolSP GetThreadFromSuffix(StringExtractorGDBRemote &packet);
 
-    uint32_t
-    GetNextSavedRegistersID ();
+  uint32_t GetNextSavedRegistersID();
 
-    void
-    MaybeCloseInferiorTerminalConnection ();
+  void MaybeCloseInferiorTerminalConnection();
 
-    void
-    ClearProcessSpecificData ();
+  void ClearProcessSpecificData();
 
-    void
-    RegisterPacketHandlers ();
+  void RegisterPacketHandlers();
 
-    void
-    DataAvailableCallback ();
+  void DataAvailableCallback();
 
-    void
-    SendProcessOutput ();
+  void SendProcessOutput();
 
-    void
-    StartSTDIOForwarding();
+  void StartSTDIOForwarding();
 
-    void
-    StopSTDIOForwarding();
+  void StopSTDIOForwarding();
 
-    //------------------------------------------------------------------
-    // For GDBRemoteCommunicationServerLLGS only
-    //------------------------------------------------------------------
-    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerLLGS);
+  //------------------------------------------------------------------
+  // For GDBRemoteCommunicationServerLLGS only
+  //------------------------------------------------------------------
+  DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerLLGS);
 };
 
 } // namespace process_gdb_remote
 } // namespace lldb_private
 
-#endif  // liblldb_GDBRemoteCommunicationServerLLGS_h_
+#endif // liblldb_GDBRemoteCommunicationServerLLGS_h_

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp Tue Sep  6 15:57:50 2016
@@ -13,8 +13,8 @@
 
 // C Includes
 // C++ Includes
-#include <cstring>
 #include <chrono>
+#include <cstring>
 #include <mutex>
 #include <sstream>
 
@@ -47,550 +47,524 @@ using namespace lldb_private::process_gd
 //----------------------------------------------------------------------
 // GDBRemoteCommunicationServerPlatform constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
-                                                                           const char *socket_scheme)
-    : GDBRemoteCommunicationServerCommon("gdb-remote.server", "gdb-remote.server.rx_packet"),
-      m_socket_protocol(socket_protocol),
-      m_socket_scheme(socket_scheme),
-      m_spawned_pids_mutex(),
-      m_port_map(),
-      m_port_offset(0)
-{
-    m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
-    m_pending_gdb_server.port = 0;
-
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_qC);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
-    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
-                                  &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
-
-    RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
-                          [this](StringExtractorGDBRemote packet, Error &error, bool &interrupt, bool &quit) {
-                              error.SetErrorString("interrupt received");
-                              interrupt = true;
-                              return PacketResult::Success;
-                          });
+GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform(
+    const Socket::SocketProtocol socket_protocol, const char *socket_scheme)
+    : GDBRemoteCommunicationServerCommon("gdb-remote.server",
+                                         "gdb-remote.server.rx_packet"),
+      m_socket_protocol(socket_protocol), m_socket_scheme(socket_scheme),
+      m_spawned_pids_mutex(), m_port_map(), m_port_offset(0) {
+  m_pending_gdb_server.pid = LLDB_INVALID_PROCESS_ID;
+  m_pending_gdb_server.port = 0;
+
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qC,
+      &GDBRemoteCommunicationServerPlatform::Handle_qC);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
+      &GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer,
+      &GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qQueryGDBServer,
+      &GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess,
+      &GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_qProcessInfo,
+      &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
+      &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
+  RegisterMemberFunctionHandler(
+      StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
+      &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
+
+  RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
+                        [this](StringExtractorGDBRemote packet, Error &error,
+                               bool &interrupt, bool &quit) {
+                          error.SetErrorString("interrupt received");
+                          interrupt = true;
+                          return PacketResult::Success;
+                        });
 }
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform()
-{
-}
-
-Error
-GDBRemoteCommunicationServerPlatform::LaunchGDBServer(const lldb_private::Args& args,
-                                                      std::string hostname,
-                                                      lldb::pid_t& pid,
-                                                      uint16_t& port,
-                                                      std::string& socket_name)
-{
-    if (port == UINT16_MAX)
-        port = GetNextAvailablePort();
-    
-    // Spawn a new thread to accept the port that gets bound after
-    // binding to port 0 (zero).
-
-    // ignore the hostname send from the remote end, just use the ip address
-    // that we're currently communicating with as the hostname
-
-    // Spawn a debugserver and try to get the port it listens to.
-    ProcessLaunchInfo debugserver_launch_info;
-    if (hostname.empty())
-        hostname = "127.0.0.1";
-
-    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-    if (log)
-        log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+GDBRemoteCommunicationServerPlatform::~GDBRemoteCommunicationServerPlatform() {}
 
-    // Do not run in a new session so that it can not linger after the
-    // platform closes.
-    debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
-    debugserver_launch_info.SetMonitorProcessCallback(
-        std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1), false);
-
-    std::string platform_scheme;
-    std::string platform_ip;
-    int platform_port;
-    std::string platform_path;
-    bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme, platform_ip, platform_port, platform_path);
-    UNUSED_IF_ASSERT_DISABLED(ok);
-    assert(ok);
+Error GDBRemoteCommunicationServerPlatform::LaunchGDBServer(
+    const lldb_private::Args &args, std::string hostname, lldb::pid_t &pid,
+    uint16_t &port, std::string &socket_name) {
+  if (port == UINT16_MAX)
+    port = GetNextAvailablePort();
+
+  // Spawn a new thread to accept the port that gets bound after
+  // binding to port 0 (zero).
+
+  // ignore the hostname send from the remote end, just use the ip address
+  // that we're currently communicating with as the hostname
+
+  // Spawn a debugserver and try to get the port it listens to.
+  ProcessLaunchInfo debugserver_launch_info;
+  if (hostname.empty())
+    hostname = "127.0.0.1";
+
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+  if (log)
+    log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+
+  // Do not run in a new session so that it can not linger after the
+  // platform closes.
+  debugserver_launch_info.SetLaunchInSeparateProcessGroup(false);
+  debugserver_launch_info.SetMonitorProcessCallback(
+      std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
+                this, std::placeholders::_1),
+      false);
+
+  std::string platform_scheme;
+  std::string platform_ip;
+  int platform_port;
+  std::string platform_path;
+  bool ok = UriParser::Parse(GetConnection()->GetURI().c_str(), platform_scheme,
+                             platform_ip, platform_port, platform_path);
+  UNUSED_IF_ASSERT_DISABLED(ok);
+  assert(ok);
 
-    std::ostringstream url;
-    // debugserver does not accept the URL scheme prefix.
+  std::ostringstream url;
+// debugserver does not accept the URL scheme prefix.
 #if !defined(__APPLE__)
-    url << m_socket_scheme << "://";
+  url << m_socket_scheme << "://";
 #endif
-    uint16_t* port_ptr = &port;
-    if (m_socket_protocol == Socket::ProtocolTcp)
-        url << platform_ip << ":" << port;
-    else
-    {
-        socket_name = GetDomainSocketPath("gdbserver").GetPath();
-        url << socket_name;
-        port_ptr = nullptr;
-    }
+  uint16_t *port_ptr = &port;
+  if (m_socket_protocol == Socket::ProtocolTcp)
+    url << platform_ip << ":" << port;
+  else {
+    socket_name = GetDomainSocketPath("gdbserver").GetPath();
+    url << socket_name;
+    port_ptr = nullptr;
+  }
 
-    Error error = StartDebugserverProcess (url.str().c_str(),
-                                           nullptr,
-                                           debugserver_launch_info,
-                                           port_ptr,
-                                           &args,
-                                           -1);
+  Error error = StartDebugserverProcess(
+      url.str().c_str(), nullptr, debugserver_launch_info, port_ptr, &args, -1);
 
-    pid = debugserver_launch_info.GetProcessID();
-    if (pid != LLDB_INVALID_PROCESS_ID)
-    {
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        m_spawned_pids.insert(pid);
-        if (port > 0)
-            AssociatePortWithProcess(port, pid);
-    }
-    else
-    {
-        if (port > 0)
-            FreePort(port);
-    }
-    return error;
+  pid = debugserver_launch_info.GetProcessID();
+  if (pid != LLDB_INVALID_PROCESS_ID) {
+    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+    m_spawned_pids.insert(pid);
+    if (port > 0)
+      AssociatePortWithProcess(port, pid);
+  } else {
+    if (port > 0)
+      FreePort(port);
+  }
+  return error;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
-{
+GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
+    StringExtractorGDBRemote &packet) {
 #ifdef _WIN32
-    return SendErrorResponse(9);
+  return SendErrorResponse(9);
 #else
-    // Spawn a local debugserver as a platform so we can then attach or launch
-    // a process...
+  // Spawn a local debugserver as a platform so we can then attach or launch
+  // a process...
 
-    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
+                __FUNCTION__);
+
+  ConnectionFileDescriptor file_conn;
+  std::string hostname;
+  packet.SetFilePos(::strlen("qLaunchGDBServer;"));
+  llvm::StringRef name;
+  llvm::StringRef value;
+  uint16_t port = UINT16_MAX;
+  while (packet.GetNameColonValue(name, value)) {
+    if (name.equals("host"))
+      hostname = value;
+    else if (name.equals("port"))
+      value.getAsInteger(0, port);
+  }
+
+  lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
+  std::string socket_name;
+  Error error =
+      LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
+  if (error.Fail()) {
     if (log)
-        log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__);
-
-    ConnectionFileDescriptor file_conn;
-    std::string hostname;
-    packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
-    llvm::StringRef name;
-    llvm::StringRef value;
-    uint16_t port = UINT16_MAX;
-    while (packet.GetNameColonValue(name, value))
-    {
-        if (name.equals("host"))
-            hostname = value;
-        else if (name.equals("port"))
-            value.getAsInteger(0, port);
-    }
-
-    lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
-    std::string socket_name;
-    Error error = LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
-    if (error.Fail())
-    {
-        if (log)
-            log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
-        return SendErrorResponse(9);
-    }
-
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);
-
-    StreamGDBRemote response;
-    response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
-    if (!socket_name.empty())
-    {
-        response.PutCString("socket_name:");
-        response.PutCStringAsRawHex8(socket_name.c_str());
-        response.PutChar(';');
-    }
+      log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
+                  "launch failed: %s",
+                  __FUNCTION__, error.AsCString());
+    return SendErrorResponse(9);
+  }
 
-    PacketResult packet_result = SendPacketNoLock(response.GetString());
-    if (packet_result != PacketResult::Success)
-    {
-        if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
-            ::kill (debugserver_pid, SIGINT);
-    }
-    return packet_result;
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver "
+                "launched successfully as pid %" PRIu64,
+                __FUNCTION__, debugserver_pid);
+
+  StreamGDBRemote response;
+  response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid,
+                  port + m_port_offset);
+  if (!socket_name.empty()) {
+    response.PutCString("socket_name:");
+    response.PutCStringAsRawHex8(socket_name.c_str());
+    response.PutChar(';');
+  }
+
+  PacketResult packet_result = SendPacketNoLock(response.GetString());
+  if (packet_result != PacketResult::Success) {
+    if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
+      ::kill(debugserver_pid, SIGINT);
+  }
+  return packet_result;
 #endif
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer (StringExtractorGDBRemote &packet)
-{
-    if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
-        return SendErrorResponse(4);
-
-    JSONObject::SP server_sp = std::make_shared<JSONObject>();
-    server_sp->SetObject("port", std::make_shared<JSONNumber>(m_pending_gdb_server.port));
-    if (!m_pending_gdb_server.socket_name.empty())
-        server_sp->SetObject("socket_name",
-                             std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
-
-    JSONArray server_list;
-    server_list.AppendObject(server_sp);
-
-    StreamGDBRemote response;
-    server_list.Write(response);
-
-    StreamGDBRemote escaped_response;
-    escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
-    return SendPacketNoLock(escaped_response.GetString());
+GDBRemoteCommunicationServerPlatform::Handle_qQueryGDBServer(
+    StringExtractorGDBRemote &packet) {
+  if (m_pending_gdb_server.pid == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(4);
+
+  JSONObject::SP server_sp = std::make_shared<JSONObject>();
+  server_sp->SetObject("port",
+                       std::make_shared<JSONNumber>(m_pending_gdb_server.port));
+  if (!m_pending_gdb_server.socket_name.empty())
+    server_sp->SetObject(
+        "socket_name",
+        std::make_shared<JSONString>(m_pending_gdb_server.socket_name.c_str()));
+
+  JSONArray server_list;
+  server_list.AppendObject(server_sp);
+
+  StreamGDBRemote response;
+  server_list.Write(response);
+
+  StreamGDBRemote escaped_response;
+  escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
+  return SendPacketNoLock(escaped_response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
-
-    lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
-
-    // verify that we know anything about this pid.
-    // Scope for locker
-    {
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        if (m_spawned_pids.find(pid) == m_spawned_pids.end())
-        {
-            // not a pid we know about
-            return SendErrorResponse (10);
-        }
-    }
-
-    // go ahead and attempt to kill the spawned process
-    if (KillSpawnedProcess (pid))
-        return SendOKResponse ();
-    else
-        return SendErrorResponse (11);
-}
-
-bool
-GDBRemoteCommunicationServerPlatform::KillSpawnedProcess (lldb::pid_t pid)
-{
-    // make sure we know about this process
-    {
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        if (m_spawned_pids.find(pid) == m_spawned_pids.end())
-            return false;
-    }
-
-    // first try a SIGTERM (standard kill)
-    Host::Kill (pid, SIGTERM);
-
-    // check if that worked
-    for (size_t i=0; i<10; ++i)
-    {
-        {
-            std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-            if (m_spawned_pids.find(pid) == m_spawned_pids.end())
-            {
-                // it is now killed
-                return true;
-            }
-        }
-        usleep (10000);
-    }
-
-    // check one more time after the final usleep
-    {
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        if (m_spawned_pids.find(pid) == m_spawned_pids.end())
-            return true;
+GDBRemoteCommunicationServerPlatform::Handle_qKillSpawnedProcess(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("qKillSpawnedProcess:"));
+
+  lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
+
+  // verify that we know anything about this pid.
+  // Scope for locker
+  {
+    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+    if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+      // not a pid we know about
+      return SendErrorResponse(10);
+    }
+  }
+
+  // go ahead and attempt to kill the spawned process
+  if (KillSpawnedProcess(pid))
+    return SendOKResponse();
+  else
+    return SendErrorResponse(11);
+}
+
+bool GDBRemoteCommunicationServerPlatform::KillSpawnedProcess(lldb::pid_t pid) {
+  // make sure we know about this process
+  {
+    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+    if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+      return false;
+  }
+
+  // first try a SIGTERM (standard kill)
+  Host::Kill(pid, SIGTERM);
+
+  // check if that worked
+  for (size_t i = 0; i < 10; ++i) {
+    {
+      std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+      if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+        // it is now killed
+        return true;
+      }
     }
+    usleep(10000);
+  }
 
-    // the launched process still lives.  Now try killing it again,
-    // this time with an unblockable signal.
-    Host::Kill (pid, SIGKILL);
-
-    for (size_t i=0; i<10; ++i)
-    {
-        {
-            std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-            if (m_spawned_pids.find(pid) == m_spawned_pids.end())
-            {
-                // it is now killed
-                return true;
-            }
-        }
-        usleep (10000);
+  // check one more time after the final usleep
+  {
+    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+    if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+      return true;
+  }
+
+  // the launched process still lives.  Now try killing it again,
+  // this time with an unblockable signal.
+  Host::Kill(pid, SIGKILL);
+
+  for (size_t i = 0; i < 10; ++i) {
+    {
+      std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+      if (m_spawned_pids.find(pid) == m_spawned_pids.end()) {
+        // it is now killed
+        return true;
+      }
     }
+    usleep(10000);
+  }
 
-    // check one more time after the final usleep
-    // Scope for locker
-    {
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        if (m_spawned_pids.find(pid) == m_spawned_pids.end())
-            return true;
-    }
+  // check one more time after the final usleep
+  // Scope for locker
+  {
+    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+    if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+      return true;
+  }
 
-    // no luck - the process still lives
-    return false;
+  // no luck - the process still lives
+  return false;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo (StringExtractorGDBRemote &packet)
-{
-    lldb::pid_t pid = m_process_launch_info.GetProcessID ();
-    m_process_launch_info.Clear ();
-
-    if (pid == LLDB_INVALID_PROCESS_ID)
-        return SendErrorResponse (1);
-
-    ProcessInstanceInfo proc_info;
-    if (!Host::GetProcessInfo (pid, proc_info))
-        return SendErrorResponse (1);
-
-    StreamString response;
-    CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
-    return SendPacketNoLock (response.GetString());
+GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo(
+    StringExtractorGDBRemote &packet) {
+  lldb::pid_t pid = m_process_launch_info.GetProcessID();
+  m_process_launch_info.Clear();
+
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(1);
+
+  ProcessInstanceInfo proc_info;
+  if (!Host::GetProcessInfo(pid, proc_info))
+    return SendErrorResponse(1);
+
+  StreamString response;
+  CreateProcessInfoResponse_DebugServerStyle(proc_info, response);
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
-{
-    // If this packet is sent to a platform, then change the current working directory
-
-    char cwd[PATH_MAX];
-    if (getcwd(cwd, sizeof(cwd)) == NULL)
-        return SendErrorResponse(errno);
-
-    StreamString response;
-    response.PutBytesAsRawHex8(cwd, strlen(cwd));
-    return SendPacketNoLock(response.GetString());
+GDBRemoteCommunicationServerPlatform::Handle_qGetWorkingDir(
+    StringExtractorGDBRemote &packet) {
+  // If this packet is sent to a platform, then change the current working
+  // directory
+
+  char cwd[PATH_MAX];
+  if (getcwd(cwd, sizeof(cwd)) == NULL)
+    return SendErrorResponse(errno);
+
+  StreamString response;
+  response.PutBytesAsRawHex8(cwd, strlen(cwd));
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos (::strlen ("QSetWorkingDir:"));
-    std::string path;
-    packet.GetHexByteString (path);
-
-    // If this packet is sent to a platform, then change the current working directory
-    if (::chdir(path.c_str()) != 0)
-        return SendErrorResponse (errno);
-    return SendOKResponse ();
+GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir(
+    StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(::strlen("QSetWorkingDir:"));
+  std::string path;
+  packet.GetHexByteString(path);
+
+  // If this packet is sent to a platform, then change the current working
+  // directory
+  if (::chdir(path.c_str()) != 0)
+    return SendErrorResponse(errno);
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packet)
-{
-    // NOTE: lldb should now be using qProcessInfo for process IDs.  This path here
-    // should not be used.  It is reporting process id instead of thread id.  The
-    // correct answer doesn't seem to make much sense for lldb-platform.
-    // CONSIDER: flip to "unsupported".
-    lldb::pid_t pid = m_process_launch_info.GetProcessID();
-
-    StreamString response;
-    response.Printf("QC%" PRIx64, pid);
-
-    // If we launch a process and this GDB server is acting as a platform,
-    // then we need to clear the process launch state so we can start
-    // launching another process. In order to launch a process a bunch or
-    // packets need to be sent: environment packets, working directory,
-    // disable ASLR, and many more settings. When we launch a process we
-    // then need to know when to clear this information. Currently we are
-    // selecting the 'qC' packet as that packet which seems to make the most
-    // sense.
-    if (pid != LLDB_INVALID_PROCESS_ID)
-    {
-        m_process_launch_info.Clear();
-    }
+GDBRemoteCommunicationServerPlatform::Handle_qC(
+    StringExtractorGDBRemote &packet) {
+  // NOTE: lldb should now be using qProcessInfo for process IDs.  This path
+  // here
+  // should not be used.  It is reporting process id instead of thread id.  The
+  // correct answer doesn't seem to make much sense for lldb-platform.
+  // CONSIDER: flip to "unsupported".
+  lldb::pid_t pid = m_process_launch_info.GetProcessID();
+
+  StreamString response;
+  response.Printf("QC%" PRIx64, pid);
+
+  // If we launch a process and this GDB server is acting as a platform,
+  // then we need to clear the process launch state so we can start
+  // launching another process. In order to launch a process a bunch or
+  // packets need to be sent: environment packets, working directory,
+  // disable ASLR, and many more settings. When we launch a process we
+  // then need to know when to clear this information. Currently we are
+  // selecting the 'qC' packet as that packet which seems to make the most
+  // sense.
+  if (pid != LLDB_INVALID_PROCESS_ID) {
+    m_process_launch_info.Clear();
+  }
 
-    return SendPacketNoLock (response.GetString());
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet)
-{
-    StructuredData::Array signal_array;
-
-    const auto &signals = Host::GetUnixSignals();
-    for (auto signo = signals->GetFirstSignalNumber();
-         signo != LLDB_INVALID_SIGNAL_NUMBER;
-         signo = signals->GetNextSignalNumber(signo))
-    {
-        auto dictionary = std::make_shared<StructuredData::Dictionary>();
-
-        dictionary->AddIntegerItem("signo", signo);
-        dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
-
-        bool suppress, stop, notify;
-        signals->GetSignalInfo(signo, suppress, stop, notify);
-        dictionary->AddBooleanItem("suppress", suppress);
-        dictionary->AddBooleanItem("stop", stop);
-        dictionary->AddBooleanItem("notify", notify);
+GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(
+    StringExtractorGDBRemote &packet) {
+  StructuredData::Array signal_array;
+
+  const auto &signals = Host::GetUnixSignals();
+  for (auto signo = signals->GetFirstSignalNumber();
+       signo != LLDB_INVALID_SIGNAL_NUMBER;
+       signo = signals->GetNextSignalNumber(signo)) {
+    auto dictionary = std::make_shared<StructuredData::Dictionary>();
+
+    dictionary->AddIntegerItem("signo", signo);
+    dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
+
+    bool suppress, stop, notify;
+    signals->GetSignalInfo(signo, suppress, stop, notify);
+    dictionary->AddBooleanItem("suppress", suppress);
+    dictionary->AddBooleanItem("stop", stop);
+    dictionary->AddBooleanItem("notify", notify);
+
+    signal_array.Push(dictionary);
+  }
+
+  StreamString response;
+  signal_array.Dump(response);
+  return SendPacketNoLock(response.GetString());
+}
+
+bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped(
+    lldb::pid_t pid) {
+  std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+  FreePortForProcess(pid);
+  m_spawned_pids.erase(pid);
+  return true;
+}
+
+Error GDBRemoteCommunicationServerPlatform::LaunchProcess() {
+  if (!m_process_launch_info.GetArguments().GetArgumentCount())
+    return Error("%s: no process command line specified to launch",
+                 __FUNCTION__);
+
+  // specify the process monitor if not already set.  This should
+  // generally be what happens since we need to reap started
+  // processes.
+  if (!m_process_launch_info.GetMonitorProcessCallback())
+    m_process_launch_info.SetMonitorProcessCallback(
+        std::bind(
+            &GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped,
+            this, std::placeholders::_1),
+        false);
+
+  Error error = Host::LaunchProcess(m_process_launch_info);
+  if (!error.Success()) {
+    fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+            m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
+    return error;
+  }
 
-        signal_array.Push(dictionary);
-    }
+  printf("Launched '%s' as process %" PRIu64 "...\n",
+         m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+         m_process_launch_info.GetProcessID());
+
+  // add to list of spawned processes.  On an lldb-gdbserver, we
+  // would expect there to be only one.
+  const auto pid = m_process_launch_info.GetProcessID();
+  if (pid != LLDB_INVALID_PROCESS_ID) {
+    // add to spawned pids
+    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
+    m_spawned_pids.insert(pid);
+  }
 
-    StreamString response;
-    signal_array.Dump(response);
-    return SendPacketNoLock(response.GetString());
+  return error;
 }
 
-bool
-GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
-{
-    std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-    FreePortForProcess(pid);
-    m_spawned_pids.erase(pid);
-    return true;
+void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
+  m_port_map = port_map;
 }
 
-Error
-GDBRemoteCommunicationServerPlatform::LaunchProcess ()
-{
-    if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
-        return Error ("%s: no process command line specified to launch", __FUNCTION__);
-
-    // specify the process monitor if not already set.  This should
-    // generally be what happens since we need to reap started
-    // processes.
-    if (!m_process_launch_info.GetMonitorProcessCallback ())
-        m_process_launch_info.SetMonitorProcessCallback(
-            std::bind(&GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped, this, std::placeholders::_1),
-            false);
-
-    Error error = Host::LaunchProcess(m_process_launch_info);
-    if (!error.Success ())
-    {
-        fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
-        return error;
-    }
-
-    printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
+uint16_t GDBRemoteCommunicationServerPlatform::GetNextAvailablePort() {
+  if (m_port_map.empty())
+    return 0; // Bind to port zero and get a port, we didn't have any
+              // limitations
 
-    // add to list of spawned processes.  On an lldb-gdbserver, we
-    // would expect there to be only one.
-    const auto pid = m_process_launch_info.GetProcessID();
-    if (pid != LLDB_INVALID_PROCESS_ID)
-    {
-        // add to spawned pids
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        m_spawned_pids.insert(pid);
+  for (auto &pair : m_port_map) {
+    if (pair.second == LLDB_INVALID_PROCESS_ID) {
+      pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
+      return pair.first;
     }
-
-    return error;
+  }
+  return UINT16_MAX;
 }
 
-void
-GDBRemoteCommunicationServerPlatform::SetPortMap (PortMap &&port_map)
-{
-    m_port_map = port_map;
+bool GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess(
+    uint16_t port, lldb::pid_t pid) {
+  PortMap::iterator pos = m_port_map.find(port);
+  if (pos != m_port_map.end()) {
+    pos->second = pid;
+    return true;
+  }
+  return false;
 }
 
-uint16_t
-GDBRemoteCommunicationServerPlatform::GetNextAvailablePort ()
-{
-    if (m_port_map.empty())
-        return 0; // Bind to port zero and get a port, we didn't have any limitations
-
-    for (auto &pair : m_port_map)
-    {
-        if (pair.second == LLDB_INVALID_PROCESS_ID)
-        {
-            pair.second = ~(lldb::pid_t)LLDB_INVALID_PROCESS_ID;
-            return pair.first;
-        }
-    }
-    return UINT16_MAX;
+bool GDBRemoteCommunicationServerPlatform::FreePort(uint16_t port) {
+  PortMap::iterator pos = m_port_map.find(port);
+  if (pos != m_port_map.end()) {
+    pos->second = LLDB_INVALID_PROCESS_ID;
+    return true;
+  }
+  return false;
 }
 
-bool
-GDBRemoteCommunicationServerPlatform::AssociatePortWithProcess (uint16_t port, lldb::pid_t pid)
-{
-    PortMap::iterator pos = m_port_map.find(port);
-    if (pos != m_port_map.end())
-    {
-        pos->second = pid;
+bool GDBRemoteCommunicationServerPlatform::FreePortForProcess(lldb::pid_t pid) {
+  if (!m_port_map.empty()) {
+    for (auto &pair : m_port_map) {
+      if (pair.second == pid) {
+        pair.second = LLDB_INVALID_PROCESS_ID;
         return true;
+      }
     }
-    return false;
+  }
+  return false;
 }
 
-bool
-GDBRemoteCommunicationServerPlatform::FreePort (uint16_t port)
-{
-    PortMap::iterator pos = m_port_map.find(port);
-    if (pos != m_port_map.end())
-    {
-        pos->second = LLDB_INVALID_PROCESS_ID;
-        return true;
-    }
-    return false;
-}
+const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() {
+  static FileSpec g_domainsocket_dir;
+  static std::once_flag g_once_flag;
 
-bool
-GDBRemoteCommunicationServerPlatform::FreePortForProcess (lldb::pid_t pid)
-{
-    if (!m_port_map.empty())
-    {
-        for (auto &pair : m_port_map)
-        {
-            if (pair.second == pid)
-            {
-                pair.second = LLDB_INVALID_PROCESS_ID;
-                return true;
-            }
-        }
-    }
-    return false;
+  std::call_once(g_once_flag, []() {
+    const char *domainsocket_dir_env =
+        ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
+    if (domainsocket_dir_env != nullptr)
+      g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
+    else
+      HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
+  });
+
+  return g_domainsocket_dir;
 }
 
-const FileSpec&
-GDBRemoteCommunicationServerPlatform::GetDomainSocketDir()
-{
-    static FileSpec g_domainsocket_dir;
-    static std::once_flag g_once_flag;
-
-    std::call_once(g_once_flag, []() {
-        const char* domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
-        if (domainsocket_dir_env != nullptr)
-            g_domainsocket_dir = FileSpec(domainsocket_dir_env, false);
-        else
-            HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, g_domainsocket_dir);
-    });
+FileSpec
+GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) {
+  llvm::SmallString<PATH_MAX> socket_path;
+  llvm::SmallString<PATH_MAX> socket_name(
+      (llvm::StringRef(prefix) + ".%%%%%%").str());
+
+  FileSpec socket_path_spec(GetDomainSocketDir());
+  socket_path_spec.AppendPathComponent(socket_name.c_str());
 
-    return g_domainsocket_dir;
+  llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
+  return FileSpec(socket_path.c_str(), false);
 }
 
-FileSpec
-GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char* prefix)
-{
-    llvm::SmallString<PATH_MAX> socket_path;
-    llvm::SmallString<PATH_MAX> socket_name((llvm::StringRef(prefix) + ".%%%%%%").str());
-
-    FileSpec socket_path_spec(GetDomainSocketDir());
-    socket_path_spec.AppendPathComponent(socket_name.c_str());
-
-    llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path);
-    return FileSpec(socket_path.c_str(), false);
-}
-
-void
-GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset)
-{
-    m_port_offset = port_offset;
-}
-
-void
-GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(lldb::pid_t pid,
-                                                          uint16_t port,
-                                                          const std::string& socket_name)
-{
-    m_pending_gdb_server.pid = pid;
-    m_pending_gdb_server.port = port;
-    m_pending_gdb_server.socket_name = socket_name;
+void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) {
+  m_port_offset = port_offset;
+}
+
+void GDBRemoteCommunicationServerPlatform::SetPendingGdbServer(
+    lldb::pid_t pid, uint16_t port, const std::string &socket_name) {
+  m_pending_gdb_server.pid = pid;
+  m_pending_gdb_server.port = port;
+  m_pending_gdb_server.socket_name = socket_name;
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h Tue Sep  6 15:57:50 2016
@@ -24,110 +24,90 @@
 namespace lldb_private {
 namespace process_gdb_remote {
 
-class GDBRemoteCommunicationServerPlatform :
-    public GDBRemoteCommunicationServerCommon
-{
+class GDBRemoteCommunicationServerPlatform
+    : public GDBRemoteCommunicationServerCommon {
 public:
-    typedef std::map<uint16_t, lldb::pid_t> PortMap;
+  typedef std::map<uint16_t, lldb::pid_t> PortMap;
 
-    GDBRemoteCommunicationServerPlatform(const Socket::SocketProtocol socket_protocol,
-                                         const char* socket_scheme);
+  GDBRemoteCommunicationServerPlatform(
+      const Socket::SocketProtocol socket_protocol, const char *socket_scheme);
 
-    ~GDBRemoteCommunicationServerPlatform() override;
+  ~GDBRemoteCommunicationServerPlatform() override;
 
-    Error
-    LaunchProcess () override;
-
-    // Set both ports to zero to let the platform automatically bind to 
-    // a port chosen by the OS.
-    void
-    SetPortMap (PortMap &&port_map);
-
-    //----------------------------------------------------------------------
-    // If we are using a port map where we can only use certain ports,
-    // get the next available port.
-    //
-    // If we are using a port map and we are out of ports, return UINT16_MAX
-    //
-    // If we aren't using a port map, return 0 to indicate we should bind to
-    // port 0 and then figure out which port we used.
-    //----------------------------------------------------------------------
-    uint16_t
-    GetNextAvailablePort ();
-
-    bool
-    AssociatePortWithProcess (uint16_t port, lldb::pid_t pid);
-
-    bool
-    FreePort (uint16_t port);
-
-    bool
-    FreePortForProcess (lldb::pid_t pid);
-
-    void
-    SetPortOffset (uint16_t port_offset);
-
-    void
-    SetInferiorArguments (const lldb_private::Args& args);
-
-    Error
-    LaunchGDBServer(const lldb_private::Args& args,
-                    std::string hostname,
-                    lldb::pid_t& pid,
-                    uint16_t& port,
-                    std::string& socket_name);
+  Error LaunchProcess() override;
 
-    void
-    SetPendingGdbServer(lldb::pid_t pid, uint16_t port, const std::string& socket_name);
+  // Set both ports to zero to let the platform automatically bind to
+  // a port chosen by the OS.
+  void SetPortMap(PortMap &&port_map);
+
+  //----------------------------------------------------------------------
+  // If we are using a port map where we can only use certain ports,
+  // get the next available port.
+  //
+  // If we are using a port map and we are out of ports, return UINT16_MAX
+  //
+  // If we aren't using a port map, return 0 to indicate we should bind to
+  // port 0 and then figure out which port we used.
+  //----------------------------------------------------------------------
+  uint16_t GetNextAvailablePort();
+
+  bool AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
+
+  bool FreePort(uint16_t port);
+
+  bool FreePortForProcess(lldb::pid_t pid);
+
+  void SetPortOffset(uint16_t port_offset);
+
+  void SetInferiorArguments(const lldb_private::Args &args);
+
+  Error LaunchGDBServer(const lldb_private::Args &args, std::string hostname,
+                        lldb::pid_t &pid, uint16_t &port,
+                        std::string &socket_name);
+
+  void SetPendingGdbServer(lldb::pid_t pid, uint16_t port,
+                           const std::string &socket_name);
 
 protected:
-    const Socket::SocketProtocol m_socket_protocol;
-    const std::string m_socket_scheme;
-    std::recursive_mutex m_spawned_pids_mutex;
-    std::set<lldb::pid_t> m_spawned_pids;
+  const Socket::SocketProtocol m_socket_protocol;
+  const std::string m_socket_scheme;
+  std::recursive_mutex m_spawned_pids_mutex;
+  std::set<lldb::pid_t> m_spawned_pids;
 
-    PortMap m_port_map;
-    uint16_t m_port_offset;
-    struct { lldb::pid_t pid; uint16_t port; std::string socket_name; } m_pending_gdb_server;
+  PortMap m_port_map;
+  uint16_t m_port_offset;
+  struct {
+    lldb::pid_t pid;
+    uint16_t port;
+    std::string socket_name;
+  } m_pending_gdb_server;
 
-    PacketResult
-    Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qLaunchGDBServer(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qQueryGDBServer (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qQueryGDBServer(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qKillSpawnedProcess(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qProcessInfo (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qProcessInfo(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qGetWorkingDir(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
+  PacketResult Handle_QSetWorkingDir(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_qC (StringExtractorGDBRemote &packet);
+  PacketResult Handle_qC(StringExtractorGDBRemote &packet);
 
-    PacketResult
-    Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
+  PacketResult Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
 
 private:
-    bool
-    KillSpawnedProcess (lldb::pid_t pid);
+  bool KillSpawnedProcess(lldb::pid_t pid);
 
-    bool
-    DebugserverProcessReaped (lldb::pid_t pid);
+  bool DebugserverProcessReaped(lldb::pid_t pid);
 
-    static const FileSpec&
-    GetDomainSocketDir();
+  static const FileSpec &GetDomainSocketDir();
 
-    static FileSpec
-    GetDomainSocketPath(const char* prefix);
+  static FileSpec GetDomainSocketPath(const char *prefix);
 
-    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServerPlatform);
+  DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationServerPlatform);
 };
 
 } // namespace process_gdb_remote

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Tue Sep  6 15:57:50 2016
@@ -21,12 +21,12 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/Utils.h"
 // Project includes
-#include "Utility/StringExtractorGDBRemote.h"
 #include "ProcessGDBRemote.h"
 #include "ProcessGDBRemoteLog.h"
 #include "ThreadGDBRemote.h"
 #include "Utility/ARM_DWARF_Registers.h"
 #include "Utility/ARM_ehframe_Registers.h"
+#include "Utility/StringExtractorGDBRemote.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -35,762 +35,735 @@ using namespace lldb_private::process_gd
 //----------------------------------------------------------------------
 // GDBRemoteRegisterContext constructor
 //----------------------------------------------------------------------
-GDBRemoteRegisterContext::GDBRemoteRegisterContext
-(
-    ThreadGDBRemote &thread,
-    uint32_t concrete_frame_idx,
-    GDBRemoteDynamicRegisterInfo &reg_info,
-    bool read_all_at_once
-) :
-    RegisterContext (thread, concrete_frame_idx),
-    m_reg_info (reg_info),
-    m_reg_valid (),
-    m_reg_data (),
-    m_read_all_at_once (read_all_at_once)
-{
-    // Resize our vector of bools to contain one bool for every register.
-    // We will use these boolean values to know when a register value
-    // is valid in m_reg_data.
-    m_reg_valid.resize (reg_info.GetNumRegisters());
-
-    // Make a heap based buffer that is big enough to store all registers
-    DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0));
-    m_reg_data.SetData (reg_data_sp);
-    m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
+GDBRemoteRegisterContext::GDBRemoteRegisterContext(
+    ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
+    GDBRemoteDynamicRegisterInfo &reg_info, bool read_all_at_once)
+    : RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info),
+      m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) {
+  // Resize our vector of bools to contain one bool for every register.
+  // We will use these boolean values to know when a register value
+  // is valid in m_reg_data.
+  m_reg_valid.resize(reg_info.GetNumRegisters());
+
+  // Make a heap based buffer that is big enough to store all registers
+  DataBufferSP reg_data_sp(
+      new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0));
+  m_reg_data.SetData(reg_data_sp);
+  m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder());
 }
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-GDBRemoteRegisterContext::~GDBRemoteRegisterContext()
-{
-}
+GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {}
 
-void
-GDBRemoteRegisterContext::InvalidateAllRegisters ()
-{
-    SetAllRegisterValid (false);
+void GDBRemoteRegisterContext::InvalidateAllRegisters() {
+  SetAllRegisterValid(false);
 }
 
-void
-GDBRemoteRegisterContext::SetAllRegisterValid (bool b)
-{
-    std::vector<bool>::iterator pos, end = m_reg_valid.end();
-    for (pos = m_reg_valid.begin(); pos != end; ++pos)
-        *pos = b;
+void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) {
+  std::vector<bool>::iterator pos, end = m_reg_valid.end();
+  for (pos = m_reg_valid.begin(); pos != end; ++pos)
+    *pos = b;
 }
 
-size_t
-GDBRemoteRegisterContext::GetRegisterCount ()
-{
-    return m_reg_info.GetNumRegisters ();
+size_t GDBRemoteRegisterContext::GetRegisterCount() {
+  return m_reg_info.GetNumRegisters();
 }
 
 const RegisterInfo *
-GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg)
-{
-    RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg);
+GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) {
+  RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg);
 
-    if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes)
-    {
-        const ArchSpec &arch = m_thread.GetProcess ()->GetTarget ().GetArchitecture ();
-        uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info);
-        reg_info->byte_size = reg_size;
-    }
-    return reg_info;
+  if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) {
+    const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
+    uint8_t reg_size = UpdateDynamicRegisterSize(arch, reg_info);
+    reg_info->byte_size = reg_size;
+  }
+  return reg_info;
 }
 
-size_t
-GDBRemoteRegisterContext::GetRegisterSetCount ()
-{
-    return m_reg_info.GetNumRegisterSets ();
+size_t GDBRemoteRegisterContext::GetRegisterSetCount() {
+  return m_reg_info.GetNumRegisterSets();
 }
 
-
-
-const RegisterSet *
-GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set)
-{
-    return m_reg_info.GetRegisterSet (reg_set);
+const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) {
+  return m_reg_info.GetRegisterSet(reg_set);
 }
 
-
-
-bool
-GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
-{
-    // Read the register
-    if (ReadRegisterBytes (reg_info, m_reg_data))
-    {
-        const bool partial_data_ok = false;
-        Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok));
-        return error.Success();
-    }
-    return false;
+bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info,
+                                            RegisterValue &value) {
+  // Read the register
+  if (ReadRegisterBytes(reg_info, m_reg_data)) {
+    const bool partial_data_ok = false;
+    Error error(value.SetValueFromData(reg_info, m_reg_data,
+                                       reg_info->byte_offset, partial_data_ok));
+    return error.Success();
+  }
+  return false;
 }
 
-bool
-GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data)
-{
-    const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
-    if (reg_info == NULL)
-        return false;
+bool GDBRemoteRegisterContext::PrivateSetRegisterValue(
+    uint32_t reg, llvm::ArrayRef<uint8_t> data) {
+  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+  if (reg_info == NULL)
+    return false;
 
-    // Invalidate if needed
-    InvalidateIfNeeded(false);
+  // Invalidate if needed
+  InvalidateIfNeeded(false);
 
-    const size_t reg_byte_size = reg_info->byte_size;
-    memcpy(const_cast<uint8_t *>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), data.data(),
-           std::min(data.size(), reg_byte_size));
-    bool success = data.size() >= reg_byte_size;
-    if (success)
-    {
-        SetRegisterIsValid(reg, true);
-    }
-    else if (data.size() > 0)
-    {
-        // Only set register is valid to false if we copied some bytes, else
-        // leave it as it was.
-        SetRegisterIsValid(reg, false);
-    }
-    return success;
+  const size_t reg_byte_size = reg_info->byte_size;
+  memcpy(const_cast<uint8_t *>(
+             m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)),
+         data.data(), std::min(data.size(), reg_byte_size));
+  bool success = data.size() >= reg_byte_size;
+  if (success) {
+    SetRegisterIsValid(reg, true);
+  } else if (data.size() > 0) {
+    // Only set register is valid to false if we copied some bytes, else
+    // leave it as it was.
+    SetRegisterIsValid(reg, false);
+  }
+  return success;
 }
 
-bool
-GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, uint64_t new_reg_val)
-{
-    const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
-    if (reg_info == NULL)
-        return false;
-
-    // Early in process startup, we can get a thread that has an invalid byte order
-    // because the process hasn't been completely set up yet (see the ctor where the
-    // byte order is setfrom the process).  If that's the case, we can't set the
-    // value here.
-    if (m_reg_data.GetByteOrder() == eByteOrderInvalid)
-    {
-        return false;
-    }
-
-    // Invalidate if needed
-    InvalidateIfNeeded (false);
+bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg,
+                                                       uint64_t new_reg_val) {
+  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+  if (reg_info == NULL)
+    return false;
 
-    DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val)));
-    DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*));
+  // Early in process startup, we can get a thread that has an invalid byte
+  // order
+  // because the process hasn't been completely set up yet (see the ctor where
+  // the
+  // byte order is setfrom the process).  If that's the case, we can't set the
+  // value here.
+  if (m_reg_data.GetByteOrder() == eByteOrderInvalid) {
+    return false;
+  }
 
-    // If our register context and our register info disagree, which should never happen, don't
-    // overwrite past the end of the buffer.
-    if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
-        return false;
+  // Invalidate if needed
+  InvalidateIfNeeded(false);
 
-    // Grab a pointer to where we are going to put this register
-    uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
+  DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
+  DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
 
-    if (dst == NULL)
-        return false;
+  // If our register context and our register info disagree, which should never
+  // happen, don't
+  // overwrite past the end of the buffer.
+  if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+    return false;
 
+  // Grab a pointer to where we are going to put this register
+  uint8_t *dst = const_cast<uint8_t *>(
+      m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
 
-    if (data.CopyByteOrderedData (0,                            // src offset
-                                  reg_info->byte_size,          // src length
-                                  dst,                          // dst
-                                  reg_info->byte_size,          // dst length
-                                  m_reg_data.GetByteOrder()))   // dst byte order
-    {
-        SetRegisterIsValid (reg, true);
-        return true;
-    }
+  if (dst == NULL)
     return false;
+
+  if (data.CopyByteOrderedData(0,                          // src offset
+                               reg_info->byte_size,        // src length
+                               dst,                        // dst
+                               reg_info->byte_size,        // dst length
+                               m_reg_data.GetByteOrder())) // dst byte order
+  {
+    SetRegisterIsValid(reg, true);
+    return true;
+  }
+  return false;
 }
 
 // Helper function for GDBRemoteRegisterContext::ReadRegisterBytes().
-bool
-GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info,
-                                                GDBRemoteCommunicationClient &gdb_comm)
-{
-    const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
-    const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
-    StringExtractorGDBRemote response;
-    if (DataBufferSP buffer_sp = gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
-        return PrivateSetRegisterValue(lldb_reg,
-                                       llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(), buffer_sp->GetByteSize()));
+bool GDBRemoteRegisterContext::GetPrimordialRegister(
+    const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
+  const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB];
+  const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin];
+  StringExtractorGDBRemote response;
+  if (DataBufferSP buffer_sp =
+          gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg))
+    return PrivateSetRegisterValue(
+        lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(),
+                                          buffer_sp->GetByteSize()));
+  return false;
+}
+
+bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info,
+                                                 DataExtractor &data) {
+  ExecutionContext exe_ctx(CalculateThread());
+
+  Process *process = exe_ctx.GetProcessPtr();
+  Thread *thread = exe_ctx.GetThreadPtr();
+  if (process == NULL || thread == NULL)
     return false;
-}
 
-bool
-GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data)
-{
-    ExecutionContext exe_ctx (CalculateThread());
+  GDBRemoteCommunicationClient &gdb_comm(
+      ((ProcessGDBRemote *)process)->GetGDBRemote());
 
-    Process *process = exe_ctx.GetProcessPtr();
-    Thread *thread = exe_ctx.GetThreadPtr();
-    if (process == NULL || thread == NULL)
-        return false;
+  InvalidateIfNeeded(false);
 
-    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
 
-    InvalidateIfNeeded(false);
-
-    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+  if (!GetRegisterIsValid(reg)) {
+    if (m_read_all_at_once) {
+      if (DataBufferSP buffer_sp =
+              gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) {
+        memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()),
+               buffer_sp->GetBytes(),
+               std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
+        if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) {
+          SetAllRegisterValid(true);
+          return true;
+        }
+      }
+      return false;
+    }
+    if (reg_info->value_regs) {
+      // Process this composite register request by delegating to the
+      // constituent
+      // primordial registers.
+
+      // Index of the primordial register.
+      bool success = true;
+      for (uint32_t idx = 0; success; ++idx) {
+        const uint32_t prim_reg = reg_info->value_regs[idx];
+        if (prim_reg == LLDB_INVALID_REGNUM)
+          break;
+        // We have a valid primordial register as our constituent.
+        // Grab the corresponding register info.
+        const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+        if (prim_reg_info == NULL)
+          success = false;
+        else {
+          // Read the containing register if it hasn't already been read
+          if (!GetRegisterIsValid(prim_reg))
+            success = GetPrimordialRegister(prim_reg_info, gdb_comm);
+        }
+      }
+
+      if (success) {
+        // If we reach this point, all primordial register requests have
+        // succeeded.
+        // Validate this composite register.
+        SetRegisterIsValid(reg_info, true);
+      }
+    } else {
+      // Get each register individually
+      GetPrimordialRegister(reg_info, gdb_comm);
+    }
 
+    // Make sure we got a valid register value after reading it
     if (!GetRegisterIsValid(reg))
-    {
-        if (m_read_all_at_once)
-        {
-            if (DataBufferSP buffer_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID()))
-            {
-                memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()), buffer_sp->GetBytes(),
-                       std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize()));
-                if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize())
-                {
-                    SetAllRegisterValid(true);
-                    return true;
-                }
-            }
-            return false;
-        }
-        if (reg_info->value_regs)
-        {
-            // Process this composite register request by delegating to the constituent
-            // primordial registers.
-            
-            // Index of the primordial register.
-            bool success = true;
-            for (uint32_t idx = 0; success; ++idx)
-            {
-                const uint32_t prim_reg = reg_info->value_regs[idx];
-                if (prim_reg == LLDB_INVALID_REGNUM)
-                    break;
-                // We have a valid primordial register as our constituent.
-                // Grab the corresponding register info.
-                const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
-                if (prim_reg_info == NULL)
-                    success = false;
-                else
-                {
-                    // Read the containing register if it hasn't already been read
-                    if (!GetRegisterIsValid(prim_reg))
-                        success = GetPrimordialRegister(prim_reg_info, gdb_comm);
-                }
-            }
+      return false;
+  }
 
-            if (success)
-            {
-                // If we reach this point, all primordial register requests have succeeded.
-                // Validate this composite register.
-                SetRegisterIsValid (reg_info, true);
-            }
-        }
-        else
-        {
-            // Get each register individually
-            GetPrimordialRegister(reg_info, gdb_comm);
-        }
-
-        // Make sure we got a valid register value after reading it
-        if (!GetRegisterIsValid(reg))
-            return false;
-    }
-
-    if (&data != &m_reg_data)
-    {
-#if defined (LLDB_CONFIGURATION_DEBUG)
-        assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size);
-#endif  
-        // If our register context and our register info disagree, which should never happen, don't
-        // read past the end of the buffer.
-        if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
-            return false;
-
-        // If we aren't extracting into our own buffer (which
-        // only happens when this function is called from
-        // ReadRegisterValue(uint32_t, Scalar&)) then
-        // we transfer bytes from our buffer into the data
-        // buffer that was passed in
-
-        data.SetByteOrder (m_reg_data.GetByteOrder());
-        data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size);
-    }
-    return true;
-}
+  if (&data != &m_reg_data) {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+    assert(m_reg_data.GetByteSize() >=
+           reg_info->byte_offset + reg_info->byte_size);
+#endif
+    // If our register context and our register info disagree, which should
+    // never happen, don't
+    // read past the end of the buffer.
+    if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+      return false;
 
-bool
-GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info,
-                                         const RegisterValue &value)
-{
-    DataExtractor data;
-    if (value.GetData (data))
-        return WriteRegisterBytes (reg_info, data, 0);
-    return false;
+    // If we aren't extracting into our own buffer (which
+    // only happens when this function is called from
+    // ReadRegisterValue(uint32_t, Scalar&)) then
+    // we transfer bytes from our buffer into the data
+    // buffer that was passed in
+
+    data.SetByteOrder(m_reg_data.GetByteOrder());
+    data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size);
+  }
+  return true;
+}
+
+bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info,
+                                             const RegisterValue &value) {
+  DataExtractor data;
+  if (value.GetData(data))
+    return WriteRegisterBytes(reg_info, data, 0);
+  return false;
 }
 
 // Helper function for GDBRemoteRegisterContext::WriteRegisterBytes().
-bool
-GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info,
-                                                GDBRemoteCommunicationClient &gdb_comm)
-{
-    StreamString packet;
-    StringExtractorGDBRemote response;
-    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-    // Invalidate just this register
-    SetRegisterIsValid(reg, false);
-
-    return gdb_comm.WriteRegister(
-        m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
-        {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), reg_info->byte_size});
-}
-
-bool
-GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset)
-{
-    ExecutionContext exe_ctx (CalculateThread());
-
-    Process *process = exe_ctx.GetProcessPtr();
-    Thread *thread = exe_ctx.GetThreadPtr();
-    if (process == NULL || thread == NULL)
-        return false;
+bool GDBRemoteRegisterContext::SetPrimordialRegister(
+    const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) {
+  StreamString packet;
+  StringExtractorGDBRemote response;
+  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+  // Invalidate just this register
+  SetRegisterIsValid(reg, false);
+
+  return gdb_comm.WriteRegister(
+      m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
+      {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size),
+       reg_info->byte_size});
+}
+
+bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info,
+                                                  DataExtractor &data,
+                                                  uint32_t data_offset) {
+  ExecutionContext exe_ctx(CalculateThread());
+
+  Process *process = exe_ctx.GetProcessPtr();
+  Thread *thread = exe_ctx.GetThreadPtr();
+  if (process == NULL || thread == NULL)
+    return false;
 
-    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+  GDBRemoteCommunicationClient &gdb_comm(
+      ((ProcessGDBRemote *)process)->GetGDBRemote());
 
-#if defined (LLDB_CONFIGURATION_DEBUG)
-    assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size);
+#if defined(LLDB_CONFIGURATION_DEBUG)
+  assert(m_reg_data.GetByteSize() >=
+         reg_info->byte_offset + reg_info->byte_size);
 #endif
 
-    // If our register context and our register info disagree, which should never happen, don't
-    // overwrite past the end of the buffer.
-    if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
-        return false;
-
-    // Grab a pointer to where we are going to put this register
-    uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
+  // If our register context and our register info disagree, which should never
+  // happen, don't
+  // overwrite past the end of the buffer.
+  if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size)
+    return false;
 
-    if (dst == NULL)
-        return false;
+  // Grab a pointer to where we are going to put this register
+  uint8_t *dst = const_cast<uint8_t *>(
+      m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size));
 
+  if (dst == NULL)
+    return false;
 
-    if (data.CopyByteOrderedData (data_offset,                  // src offset
-                                  reg_info->byte_size,          // src length
-                                  dst,                          // dst
-                                  reg_info->byte_size,          // dst length
-                                  m_reg_data.GetByteOrder()))   // dst byte order
-    {
-        GDBRemoteClientBase::Lock lock(gdb_comm, false);
-        if (lock)
-        {
-                if (m_read_all_at_once)
-                {
-                    // Invalidate all register values
-                    InvalidateIfNeeded (true);
-
-                    // Set all registers in one packet
-                    if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(),
-                                                   {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
-
-                    {
-                        SetAllRegisterValid (false);
-                        return true;
-                    }
-                }
-                else
-                {
-                    bool success = true;
-
-                    if (reg_info->value_regs)
-                    {
-                        // This register is part of another register. In this case we read the actual
-                        // register data for any "value_regs", and once all that data is read, we will
-                        // have enough data in our register context bytes for the value of this register
-                        
-                        // Invalidate this composite register first.
-                        
-                        for (uint32_t idx = 0; success; ++idx)
-                        {
-                            const uint32_t reg = reg_info->value_regs[idx];
-                            if (reg == LLDB_INVALID_REGNUM)
-                                break;
-                            // We have a valid primordial register as our constituent.
-                            // Grab the corresponding register info.
-                            const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
-                            if (value_reg_info == NULL)
-                                success = false;
-                            else
-                                success = SetPrimordialRegister(value_reg_info, gdb_comm);
-                        }
-                    }
-                    else
-                    {
-                        // This is an actual register, write it
-                        success = SetPrimordialRegister(reg_info, gdb_comm);
-                    }
-
-                    // Check if writing this register will invalidate any other register values?
-                    // If so, invalidate them
-                    if (reg_info->invalidate_regs)
-                    {
-                        for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
-                             reg != LLDB_INVALID_REGNUM;
-                             reg = reg_info->invalidate_regs[++idx])
-                        {
-                            SetRegisterIsValid(reg, false);
-                        }
-                    }
-                    
-                    return success;
-                }
-        }
-        else
-        {
-            Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
-            if (log)
-            {
-                if (log->GetVerbose())
-                {
-                    StreamString strm;
-                    gdb_comm.DumpHistory(strm);
-                    log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData());
-                }
-                else
-                    log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name);
-            }
-        }
-    }
+  if (data.CopyByteOrderedData(data_offset,                // src offset
+                               reg_info->byte_size,        // src length
+                               dst,                        // dst
+                               reg_info->byte_size,        // dst length
+                               m_reg_data.GetByteOrder())) // dst byte order
+  {
+    GDBRemoteClientBase::Lock lock(gdb_comm, false);
+    if (lock) {
+      if (m_read_all_at_once) {
+        // Invalidate all register values
+        InvalidateIfNeeded(true);
+
+        // Set all registers in one packet
+        if (gdb_comm.WriteAllRegisters(
+                m_thread.GetProtocolID(),
+                {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
+
+        {
+          SetAllRegisterValid(false);
+          return true;
+        }
+      } else {
+        bool success = true;
+
+        if (reg_info->value_regs) {
+          // This register is part of another register. In this case we read the
+          // actual
+          // register data for any "value_regs", and once all that data is read,
+          // we will
+          // have enough data in our register context bytes for the value of
+          // this register
+
+          // Invalidate this composite register first.
+
+          for (uint32_t idx = 0; success; ++idx) {
+            const uint32_t reg = reg_info->value_regs[idx];
+            if (reg == LLDB_INVALID_REGNUM)
+              break;
+            // We have a valid primordial register as our constituent.
+            // Grab the corresponding register info.
+            const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+            if (value_reg_info == NULL)
+              success = false;
+            else
+              success = SetPrimordialRegister(value_reg_info, gdb_comm);
+          }
+        } else {
+          // This is an actual register, write it
+          success = SetPrimordialRegister(reg_info, gdb_comm);
+        }
+
+        // Check if writing this register will invalidate any other register
+        // values?
+        // If so, invalidate them
+        if (reg_info->invalidate_regs) {
+          for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
+               reg != LLDB_INVALID_REGNUM;
+               reg = reg_info->invalidate_regs[++idx]) {
+            SetRegisterIsValid(reg, false);
+          }
+        }
+
+        return success;
+      }
+    } else {
+      Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+                                                             GDBR_LOG_PACKETS));
+      if (log) {
+        if (log->GetVerbose()) {
+          StreamString strm;
+          gdb_comm.DumpHistory(strm);
+          log->Printf("error: failed to get packet sequence mutex, not sending "
+                      "write register for \"%s\":\n%s",
+                      reg_info->name, strm.GetData());
+        } else
+          log->Printf("error: failed to get packet sequence mutex, not sending "
+                      "write register for \"%s\"",
+                      reg_info->name);
+      }
+    }
+  }
+  return false;
+}
+
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+    RegisterCheckpoint &reg_checkpoint) {
+  ExecutionContext exe_ctx(CalculateThread());
+
+  Process *process = exe_ctx.GetProcessPtr();
+  Thread *thread = exe_ctx.GetThreadPtr();
+  if (process == NULL || thread == NULL)
     return false;
-}
 
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint)
-{
-    ExecutionContext exe_ctx (CalculateThread());
-    
-    Process *process = exe_ctx.GetProcessPtr();
-    Thread *thread = exe_ctx.GetThreadPtr();
-    if (process == NULL || thread == NULL)
-        return false;
-    
-    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-
-    uint32_t save_id = 0;
-    if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id))
-    {
-        reg_checkpoint.SetID(save_id);
-        reg_checkpoint.GetData().reset();
-        return true;
-    }
-    else
-    {
-        reg_checkpoint.SetID(0); // Invalid save ID is zero
-        return ReadAllRegisterValues(reg_checkpoint.GetData());
-    }
-}
+  GDBRemoteCommunicationClient &gdb_comm(
+      ((ProcessGDBRemote *)process)->GetGDBRemote());
 
-bool
-GDBRemoteRegisterContext::WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint)
-{
-    uint32_t save_id = reg_checkpoint.GetID();
-    if (save_id != 0)
-    {
-        ExecutionContext exe_ctx (CalculateThread());
-        
-        Process *process = exe_ctx.GetProcessPtr();
-        Thread *thread = exe_ctx.GetThreadPtr();
-        if (process == NULL || thread == NULL)
-            return false;
-        
-        GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
-        
-        return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
-    }
-    else
-    {
-        return WriteAllRegisterValues(reg_checkpoint.GetData());
-    }
+  uint32_t save_id = 0;
+  if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) {
+    reg_checkpoint.SetID(save_id);
+    reg_checkpoint.GetData().reset();
+    return true;
+  } else {
+    reg_checkpoint.SetID(0); // Invalid save ID is zero
+    return ReadAllRegisterValues(reg_checkpoint.GetData());
+  }
 }
 
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
-    ExecutionContext exe_ctx (CalculateThread());
+bool GDBRemoteRegisterContext::WriteAllRegisterValues(
+    const RegisterCheckpoint &reg_checkpoint) {
+  uint32_t save_id = reg_checkpoint.GetID();
+  if (save_id != 0) {
+    ExecutionContext exe_ctx(CalculateThread());
 
     Process *process = exe_ctx.GetProcessPtr();
     Thread *thread = exe_ctx.GetThreadPtr();
     if (process == NULL || thread == NULL)
-        return false;
+      return false;
 
-    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+    GDBRemoteCommunicationClient &gdb_comm(
+        ((ProcessGDBRemote *)process)->GetGDBRemote());
 
-    const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+    return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id);
+  } else {
+    return WriteAllRegisterValues(reg_checkpoint.GetData());
+  }
+}
 
-    GDBRemoteClientBase::Lock lock(gdb_comm, false);
-    if (lock)
-    {
-        if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
-            InvalidateAllRegisters();
-
-        if (use_g_packet && (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
-            return true;
-
-        // We're going to read each register
-        // individually and store them as binary data in a buffer.
-        const RegisterInfo *reg_info;
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  ExecutionContext exe_ctx(CalculateThread());
 
-        for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++)
-        {
-            if (reg_info->value_regs) // skip registers that are slices of real registers
-                continue;
-            ReadRegisterBytes(reg_info, m_reg_data);
-            // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer
-        }
-        data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize()));
-        return true;
-    }
-    else
-    {
-
-        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
-        if (log)
-        {
-            if (log->GetVerbose())
-            {
-                StreamString strm;
-                gdb_comm.DumpHistory(strm);
-                log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData());
-            }
-            else
-                log->Printf("error: failed to get packet sequence mutex, not sending read all registers");
-        }
-    }
-
-    data_sp.reset();
+  Process *process = exe_ctx.GetProcessPtr();
+  Thread *thread = exe_ctx.GetThreadPtr();
+  if (process == NULL || thread == NULL)
     return false;
-}
 
-bool
-GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
-    if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
-        return false;
+  GDBRemoteCommunicationClient &gdb_comm(
+      ((ProcessGDBRemote *)process)->GetGDBRemote());
 
-    ExecutionContext exe_ctx (CalculateThread());
+  const bool use_g_packet =
+      gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
 
-    Process *process = exe_ctx.GetProcessPtr();
-    Thread *thread = exe_ctx.GetThreadPtr();
-    if (process == NULL || thread == NULL)
-        return false;
+  GDBRemoteClientBase::Lock lock(gdb_comm, false);
+  if (lock) {
+    if (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
+      InvalidateAllRegisters();
+
+    if (use_g_packet &&
+        (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
+      return true;
+
+    // We're going to read each register
+    // individually and store them as binary data in a buffer.
+    const RegisterInfo *reg_info;
+
+    for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) {
+      if (reg_info
+              ->value_regs) // skip registers that are slices of real registers
+        continue;
+      ReadRegisterBytes(reg_info, m_reg_data);
+      // ReadRegisterBytes saves the contents of the register in to the
+      // m_reg_data buffer
+    }
+    data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(),
+                                     m_reg_info.GetRegisterDataByteSize()));
+    return true;
+  } else {
 
-    GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote());
+    Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+                                                           GDBR_LOG_PACKETS));
+    if (log) {
+      if (log->GetVerbose()) {
+        StreamString strm;
+        gdb_comm.DumpHistory(strm);
+        log->Printf("error: failed to get packet sequence mutex, not sending "
+                    "read all registers:\n%s",
+                    strm.GetData());
+      } else
+        log->Printf("error: failed to get packet sequence mutex, not sending "
+                    "read all registers");
+    }
+  }
+
+  data_sp.reset();
+  return false;
+}
+
+bool GDBRemoteRegisterContext::WriteAllRegisterValues(
+    const lldb::DataBufferSP &data_sp) {
+  if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
+    return false;
 
-    const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false;
+  ExecutionContext exe_ctx(CalculateThread());
 
-    GDBRemoteClientBase::Lock lock(gdb_comm, false);
-    if (lock)
-    {
-        // The data_sp contains the G response packet.
-        if (use_g_packet)
-        {
-            if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(),
-                                           {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
-                return true;
-
-            uint32_t num_restored = 0;
-            // We need to manually go through all of the registers and
-            // restore them manually
-            DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(), m_reg_data.GetAddressByteSize());
-
-            const RegisterInfo *reg_info;
-
-            // The g packet contents may either include the slice registers (registers defined in
-            // terms of other registers, e.g. eax is a subset of rax) or not.  The slice registers
-            // should NOT be in the g packet, but some implementations may incorrectly include them.
-            //
-            // If the slice registers are included in the packet, we must step over the slice registers
-            // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect.
-            // If the slice registers are not included, then using the byte_offset values into the
-            // data buffer is the best way to find individual register values.
-
-            uint64_t size_including_slice_registers = 0;
-            uint64_t size_not_including_slice_registers = 0;
-            uint64_t size_by_highest_offset = 0;
-
-            for (uint32_t reg_idx = 0; (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx)
-            {
-                size_including_slice_registers += reg_info->byte_size;
-                if (reg_info->value_regs == NULL)
-                    size_not_including_slice_registers += reg_info->byte_size;
-                if (reg_info->byte_offset >= size_by_highest_offset)
-                    size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
-            }
+  Process *process = exe_ctx.GetProcessPtr();
+  Thread *thread = exe_ctx.GetThreadPtr();
+  if (process == NULL || thread == NULL)
+    return false;
 
-            bool use_byte_offset_into_buffer;
-            if (size_by_highest_offset == restore_data.GetByteSize())
-            {
-                // The size of the packet agrees with the highest offset: + size in the register file
-                use_byte_offset_into_buffer = true;
-            }
-            else if (size_not_including_slice_registers == restore_data.GetByteSize())
-            {
-                // The size of the packet is the same as concatenating all of the registers sequentially,
-                // skipping the slice registers
-                use_byte_offset_into_buffer = true;
-            }
-            else if (size_including_slice_registers == restore_data.GetByteSize())
-            {
-                // The slice registers are present in the packet (when they shouldn't be).
-                // Don't try to use the RegisterInfo byte_offset into the restore_data, it will
-                // point to the wrong place.
-                use_byte_offset_into_buffer = false;
-            }
-            else
-            {
-                // None of our expected sizes match the actual g packet data we're looking at.
-                // The most conservative approach here is to use the running total byte offset.
-                use_byte_offset_into_buffer = false;
-            }
+  GDBRemoteCommunicationClient &gdb_comm(
+      ((ProcessGDBRemote *)process)->GetGDBRemote());
 
-            // In case our register definitions don't include the correct offsets,
-            // keep track of the size of each reg & compute offset based on that.
-            uint32_t running_byte_offset = 0;
-            for (uint32_t reg_idx = 0; (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL;
-                 ++reg_idx, running_byte_offset += reg_info->byte_size)
-            {
-                // Skip composite aka slice registers (e.g. eax is a slice of rax).
-                if (reg_info->value_regs)
-                    continue;
-
-                const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
-                uint32_t register_offset;
-                if (use_byte_offset_into_buffer)
-                {
-                    register_offset = reg_info->byte_offset;
-                }
-                else
-                {
-                    register_offset = running_byte_offset;
-                }
-
-                const uint32_t reg_byte_size = reg_info->byte_size;
-
-                const uint8_t *restore_src = restore_data.PeekData(register_offset, reg_byte_size);
-                if (restore_src)
-                {
-                    SetRegisterIsValid(reg, false);
-                    if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
-                                               {restore_src, reg_byte_size}))
-                        ++num_restored;
-                }
-            }
-            return num_restored > 0;
-        }
-        else
-        {
-            // For the use_g_packet == false case, we're going to write each register
-            // individually.  The data buffer is binary data in this case, instead of
-            // ascii characters.
-
-            bool arm64_debugserver = false;
-            if (m_thread.GetProcess().get())
-            {
-                const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture();
-                if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
-                    arch.GetTriple().getVendor() == llvm::Triple::Apple &&
-                    arch.GetTriple().getOS() == llvm::Triple::IOS)
-                {
-                    arm64_debugserver = true;
-                }
-            }
-            uint32_t num_restored = 0;
-            const RegisterInfo *reg_info;
-            for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++)
-            {
-                if (reg_info->value_regs) // skip registers that are slices of real registers
-                    continue;
-                // Skip the fpsr and fpcr floating point status/control register writing to
-                // work around a bug in an older version of debugserver that would lead to
-                // register context corruption when writing fpsr/fpcr.
-                if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 || strcmp(reg_info->name, "fpcr") == 0))
-                {
-                    continue;
-                }
-
-                SetRegisterIsValid(reg_info, false);
-                if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin],
-                                           {data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size}))
-                    ++num_restored;
-            }
-            return num_restored > 0;
-        }
-    }
-    else
-    {
-        Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
-        if (log)
-        {
-            if (log->GetVerbose())
-            {
-                StreamString strm;
-                gdb_comm.DumpHistory(strm);
-                log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData());
-            }
-            else
-                log->Printf("error: failed to get packet sequence mutex, not sending write all registers");
-        }
-    }
-    return false;
-}
+  const bool use_g_packet =
+      gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false;
 
+  GDBRemoteClientBase::Lock lock(gdb_comm, false);
+  if (lock) {
+    // The data_sp contains the G response packet.
+    if (use_g_packet) {
+      if (gdb_comm.WriteAllRegisters(
+              m_thread.GetProtocolID(),
+              {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}))
+        return true;
 
-uint32_t
-GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
-    return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num);
-}
+      uint32_t num_restored = 0;
+      // We need to manually go through all of the registers and
+      // restore them manually
+      DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(),
+                                 m_reg_data.GetAddressByteSize());
+
+      const RegisterInfo *reg_info;
+
+      // The g packet contents may either include the slice registers (registers
+      // defined in
+      // terms of other registers, e.g. eax is a subset of rax) or not.  The
+      // slice registers
+      // should NOT be in the g packet, but some implementations may incorrectly
+      // include them.
+      //
+      // If the slice registers are included in the packet, we must step over
+      // the slice registers
+      // when parsing the packet -- relying on the RegisterInfo byte_offset
+      // field would be incorrect.
+      // If the slice registers are not included, then using the byte_offset
+      // values into the
+      // data buffer is the best way to find individual register values.
+
+      uint64_t size_including_slice_registers = 0;
+      uint64_t size_not_including_slice_registers = 0;
+      uint64_t size_by_highest_offset = 0;
+
+      for (uint32_t reg_idx = 0;
+           (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) {
+        size_including_slice_registers += reg_info->byte_size;
+        if (reg_info->value_regs == NULL)
+          size_not_including_slice_registers += reg_info->byte_size;
+        if (reg_info->byte_offset >= size_by_highest_offset)
+          size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size;
+      }
+
+      bool use_byte_offset_into_buffer;
+      if (size_by_highest_offset == restore_data.GetByteSize()) {
+        // The size of the packet agrees with the highest offset: + size in the
+        // register file
+        use_byte_offset_into_buffer = true;
+      } else if (size_not_including_slice_registers ==
+                 restore_data.GetByteSize()) {
+        // The size of the packet is the same as concatenating all of the
+        // registers sequentially,
+        // skipping the slice registers
+        use_byte_offset_into_buffer = true;
+      } else if (size_including_slice_registers == restore_data.GetByteSize()) {
+        // The slice registers are present in the packet (when they shouldn't
+        // be).
+        // Don't try to use the RegisterInfo byte_offset into the restore_data,
+        // it will
+        // point to the wrong place.
+        use_byte_offset_into_buffer = false;
+      } else {
+        // None of our expected sizes match the actual g packet data we're
+        // looking at.
+        // The most conservative approach here is to use the running total byte
+        // offset.
+        use_byte_offset_into_buffer = false;
+      }
+
+      // In case our register definitions don't include the correct offsets,
+      // keep track of the size of each reg & compute offset based on that.
+      uint32_t running_byte_offset = 0;
+      for (uint32_t reg_idx = 0;
+           (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL;
+           ++reg_idx, running_byte_offset += reg_info->byte_size) {
+        // Skip composite aka slice registers (e.g. eax is a slice of rax).
+        if (reg_info->value_regs)
+          continue;
 
+        const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
 
-void
-GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch)
-{
-    // For Advanced SIMD and VFP register mapping.
-    static uint32_t g_d0_regs[] =  { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1)
-    static uint32_t g_d1_regs[] =  { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3)
-    static uint32_t g_d2_regs[] =  { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5)
-    static uint32_t g_d3_regs[] =  { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7)
-    static uint32_t g_d4_regs[] =  { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9)
-    static uint32_t g_d5_regs[] =  { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11)
-    static uint32_t g_d6_regs[] =  { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13)
-    static uint32_t g_d7_regs[] =  { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15)
-    static uint32_t g_d8_regs[] =  { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17)
-    static uint32_t g_d9_regs[] =  { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19)
-    static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21)
-    static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23)
-    static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25)
-    static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27)
-    static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29)
-    static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31)
-    static uint32_t g_q0_regs[] =  { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3)
-    static uint32_t g_q1_regs[] =  { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7)
-    static uint32_t g_q2_regs[] =  { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11)
-    static uint32_t g_q3_regs[] =  { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15)
-    static uint32_t g_q4_regs[] =  { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19)
-    static uint32_t g_q5_regs[] =  { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23)
-    static uint32_t g_q6_regs[] =  { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27)
-    static uint32_t g_q7_regs[] =  { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31)
-    static uint32_t g_q8_regs[] =  { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17)
-    static uint32_t g_q9_regs[] =  { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19)
-    static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21)
-    static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23)
-    static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25)
-    static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27)
-    static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29)
-    static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31)
-
-    // This is our array of composite registers, with each element coming from the above register mappings.
-    static uint32_t *g_composites[] = {
-        g_d0_regs, g_d1_regs,  g_d2_regs,  g_d3_regs,  g_d4_regs,  g_d5_regs,  g_d6_regs,  g_d7_regs,
-        g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs,
-        g_q0_regs, g_q1_regs,  g_q2_regs,  g_q3_regs,  g_q4_regs,  g_q5_regs,  g_q6_regs,  g_q7_regs,
-        g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs
-    };
+        uint32_t register_offset;
+        if (use_byte_offset_into_buffer) {
+          register_offset = reg_info->byte_offset;
+        } else {
+          register_offset = running_byte_offset;
+        }
+
+        const uint32_t reg_byte_size = reg_info->byte_size;
+
+        const uint8_t *restore_src =
+            restore_data.PeekData(register_offset, reg_byte_size);
+        if (restore_src) {
+          SetRegisterIsValid(reg, false);
+          if (gdb_comm.WriteRegister(
+                  m_thread.GetProtocolID(),
+                  reg_info->kinds[eRegisterKindProcessPlugin],
+                  {restore_src, reg_byte_size}))
+            ++num_restored;
+        }
+      }
+      return num_restored > 0;
+    } else {
+      // For the use_g_packet == false case, we're going to write each register
+      // individually.  The data buffer is binary data in this case, instead of
+      // ascii characters.
+
+      bool arm64_debugserver = false;
+      if (m_thread.GetProcess().get()) {
+        const ArchSpec &arch =
+            m_thread.GetProcess()->GetTarget().GetArchitecture();
+        if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 &&
+            arch.GetTriple().getVendor() == llvm::Triple::Apple &&
+            arch.GetTriple().getOS() == llvm::Triple::IOS) {
+          arm64_debugserver = true;
+        }
+      }
+      uint32_t num_restored = 0;
+      const RegisterInfo *reg_info;
+      for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL;
+           i++) {
+        if (reg_info->value_regs) // skip registers that are slices of real
+                                  // registers
+          continue;
+        // Skip the fpsr and fpcr floating point status/control register writing
+        // to
+        // work around a bug in an older version of debugserver that would lead
+        // to
+        // register context corruption when writing fpsr/fpcr.
+        if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 ||
+                                  strcmp(reg_info->name, "fpcr") == 0)) {
+          continue;
+        }
+
+        SetRegisterIsValid(reg_info, false);
+        if (gdb_comm.WriteRegister(m_thread.GetProtocolID(),
+                                   reg_info->kinds[eRegisterKindProcessPlugin],
+                                   {data_sp->GetBytes() + reg_info->byte_offset,
+                                    reg_info->byte_size}))
+          ++num_restored;
+      }
+      return num_restored > 0;
+    }
+  } else {
+    Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD |
+                                                           GDBR_LOG_PACKETS));
+    if (log) {
+      if (log->GetVerbose()) {
+        StreamString strm;
+        gdb_comm.DumpHistory(strm);
+        log->Printf("error: failed to get packet sequence mutex, not sending "
+                    "write all registers:\n%s",
+                    strm.GetData());
+      } else
+        log->Printf("error: failed to get packet sequence mutex, not sending "
+                    "write all registers");
+    }
+  }
+  return false;
+}
+
+uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber(
+    lldb::RegisterKind kind, uint32_t num) {
+  return m_reg_info.ConvertRegisterKindToRegisterNumber(kind, num);
+}
+
+void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) {
+  // For Advanced SIMD and VFP register mapping.
+  static uint32_t g_d0_regs[] = {26, 27, LLDB_INVALID_REGNUM};  // (s0, s1)
+  static uint32_t g_d1_regs[] = {28, 29, LLDB_INVALID_REGNUM};  // (s2, s3)
+  static uint32_t g_d2_regs[] = {30, 31, LLDB_INVALID_REGNUM};  // (s4, s5)
+  static uint32_t g_d3_regs[] = {32, 33, LLDB_INVALID_REGNUM};  // (s6, s7)
+  static uint32_t g_d4_regs[] = {34, 35, LLDB_INVALID_REGNUM};  // (s8, s9)
+  static uint32_t g_d5_regs[] = {36, 37, LLDB_INVALID_REGNUM};  // (s10, s11)
+  static uint32_t g_d6_regs[] = {38, 39, LLDB_INVALID_REGNUM};  // (s12, s13)
+  static uint32_t g_d7_regs[] = {40, 41, LLDB_INVALID_REGNUM};  // (s14, s15)
+  static uint32_t g_d8_regs[] = {42, 43, LLDB_INVALID_REGNUM};  // (s16, s17)
+  static uint32_t g_d9_regs[] = {44, 45, LLDB_INVALID_REGNUM};  // (s18, s19)
+  static uint32_t g_d10_regs[] = {46, 47, LLDB_INVALID_REGNUM}; // (s20, s21)
+  static uint32_t g_d11_regs[] = {48, 49, LLDB_INVALID_REGNUM}; // (s22, s23)
+  static uint32_t g_d12_regs[] = {50, 51, LLDB_INVALID_REGNUM}; // (s24, s25)
+  static uint32_t g_d13_regs[] = {52, 53, LLDB_INVALID_REGNUM}; // (s26, s27)
+  static uint32_t g_d14_regs[] = {54, 55, LLDB_INVALID_REGNUM}; // (s28, s29)
+  static uint32_t g_d15_regs[] = {56, 57, LLDB_INVALID_REGNUM}; // (s30, s31)
+  static uint32_t g_q0_regs[] = {
+      26, 27, 28, 29, LLDB_INVALID_REGNUM}; // (d0, d1) -> (s0, s1, s2, s3)
+  static uint32_t g_q1_regs[] = {
+      30, 31, 32, 33, LLDB_INVALID_REGNUM}; // (d2, d3) -> (s4, s5, s6, s7)
+  static uint32_t g_q2_regs[] = {
+      34, 35, 36, 37, LLDB_INVALID_REGNUM}; // (d4, d5) -> (s8, s9, s10, s11)
+  static uint32_t g_q3_regs[] = {
+      38, 39, 40, 41, LLDB_INVALID_REGNUM}; // (d6, d7) -> (s12, s13, s14, s15)
+  static uint32_t g_q4_regs[] = {
+      42, 43, 44, 45, LLDB_INVALID_REGNUM}; // (d8, d9) -> (s16, s17, s18, s19)
+  static uint32_t g_q5_regs[] = {
+      46, 47, 48, 49,
+      LLDB_INVALID_REGNUM}; // (d10, d11) -> (s20, s21, s22, s23)
+  static uint32_t g_q6_regs[] = {
+      50, 51, 52, 53,
+      LLDB_INVALID_REGNUM}; // (d12, d13) -> (s24, s25, s26, s27)
+  static uint32_t g_q7_regs[] = {
+      54, 55, 56, 57,
+      LLDB_INVALID_REGNUM}; // (d14, d15) -> (s28, s29, s30, s31)
+  static uint32_t g_q8_regs[] = {59, 60, LLDB_INVALID_REGNUM};  // (d16, d17)
+  static uint32_t g_q9_regs[] = {61, 62, LLDB_INVALID_REGNUM};  // (d18, d19)
+  static uint32_t g_q10_regs[] = {63, 64, LLDB_INVALID_REGNUM}; // (d20, d21)
+  static uint32_t g_q11_regs[] = {65, 66, LLDB_INVALID_REGNUM}; // (d22, d23)
+  static uint32_t g_q12_regs[] = {67, 68, LLDB_INVALID_REGNUM}; // (d24, d25)
+  static uint32_t g_q13_regs[] = {69, 70, LLDB_INVALID_REGNUM}; // (d26, d27)
+  static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29)
+  static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31)
+
+  // This is our array of composite registers, with each element coming from the
+  // above register mappings.
+  static uint32_t *g_composites[] = {
+      g_d0_regs,  g_d1_regs,  g_d2_regs,  g_d3_regs,  g_d4_regs,  g_d5_regs,
+      g_d6_regs,  g_d7_regs,  g_d8_regs,  g_d9_regs,  g_d10_regs, g_d11_regs,
+      g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, g_q0_regs,  g_q1_regs,
+      g_q2_regs,  g_q3_regs,  g_q4_regs,  g_q5_regs,  g_q6_regs,  g_q7_regs,
+      g_q8_regs,  g_q9_regs,  g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs,
+      g_q14_regs, g_q15_regs};
 
-    // clang-format off
+  // clang-format off
     static RegisterInfo g_register_infos[] = {
 //   NAME     ALT     SZ   OFF  ENCODING          FORMAT          EH_FRAME             DWARF                GENERIC                 PROCESS PLUGIN  LLDB    VALUE REGS    INVALIDATE REGS SIZE EXPR SIZE LEN
 //   ======   ======  ===  ===  =============     ==========      ===================  ===================  ======================  =============   ====    ==========    =============== ========= ========
@@ -902,121 +875,113 @@ GDBRemoteDynamicRegisterInfo::HardcodeAR
     { "q14", nullptr,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14,   LLDB_INVALID_REGNUM,   105,             105 },  g_q14_regs,           nullptr,  nullptr,       0 },
     { "q15", nullptr,   16,  0, eEncodingVector,  eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15,   LLDB_INVALID_REGNUM,   106,             106 },  g_q15_regs,           nullptr,  nullptr,       0 }
     };
-    // clang-format on
+  // clang-format on
 
-    static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
-    static ConstString gpr_reg_set ("General Purpose Registers");
-    static ConstString sfp_reg_set ("Software Floating Point Registers");
-    static ConstString vfp_reg_set ("Floating Point Registers");
-    size_t i;
-    if (from_scratch)
-    {
-        // Calculate the offsets of the registers
-        // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the
-        // "primordial" registers is important.  This enables us to calculate the offset of the composite
-        // register by using the offset of its first primordial register.  For example, to calculate the
-        // offset of q0, use s0's offset.
-        if (g_register_infos[2].byte_offset == 0)
-        {
-            uint32_t byte_offset = 0;
-            for (i=0; i<num_registers; ++i)
-            {
-                // For primordial registers, increment the byte_offset by the byte_size to arrive at the
-                // byte_offset for the next register.  Otherwise, we have a composite register whose
-                // offset can be calculated by consulting the offset of its first primordial register.
-                if (!g_register_infos[i].value_regs)
-                {
-                    g_register_infos[i].byte_offset = byte_offset;
-                    byte_offset += g_register_infos[i].byte_size;
-                }
-                else
-                {
-                    const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0];
-                    g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset;
-                }
-            }
-        }
-        for (i=0; i<num_registers; ++i)
-        {
-            ConstString name;
-            ConstString alt_name;
-            if (g_register_infos[i].name && g_register_infos[i].name[0])
-                name.SetCString(g_register_infos[i].name);
-            if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
-                alt_name.SetCString(g_register_infos[i].alt_name);
-
-            if (i <= 15 || i == 25)
-                AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set);
-            else if (i <= 24)
-                AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set);
-            else
-                AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set);
-        }
-    }
-    else
-    {
-        // Add composite registers to our primordial registers, then.
-        const size_t num_composites = llvm::array_lengthof(g_composites);
-        const size_t num_dynamic_regs = GetNumRegisters();
-        const size_t num_common_regs = num_registers - num_composites;
-        RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
-
-        // First we need to validate that all registers that we already have match the non composite regs.
-        // If so, then we can add the registers, else we need to bail
-        bool match = true;
-        if (num_dynamic_regs == num_common_regs)
-        {
-            for (i=0; match && i<num_dynamic_regs; ++i)
-            {
-                // Make sure all register names match
-                if (m_regs[i].name && g_register_infos[i].name)
-                {
-                    if (strcmp(m_regs[i].name, g_register_infos[i].name))
-                    {
-                        match = false;
-                        break;
-                    }
-                }
-                
-                // Make sure all register byte sizes match
-                if (m_regs[i].byte_size != g_register_infos[i].byte_size)
-                {
-                    match = false;
-                    break;
-                }
-            }
-        }
-        else
-        {
-            // Wrong number of registers.
+  static const uint32_t num_registers = llvm::array_lengthof(g_register_infos);
+  static ConstString gpr_reg_set("General Purpose Registers");
+  static ConstString sfp_reg_set("Software Floating Point Registers");
+  static ConstString vfp_reg_set("Floating Point Registers");
+  size_t i;
+  if (from_scratch) {
+    // Calculate the offsets of the registers
+    // Note that the layout of the "composite" registers (d0-d15 and q0-q15)
+    // which comes after the
+    // "primordial" registers is important.  This enables us to calculate the
+    // offset of the composite
+    // register by using the offset of its first primordial register.  For
+    // example, to calculate the
+    // offset of q0, use s0's offset.
+    if (g_register_infos[2].byte_offset == 0) {
+      uint32_t byte_offset = 0;
+      for (i = 0; i < num_registers; ++i) {
+        // For primordial registers, increment the byte_offset by the byte_size
+        // to arrive at the
+        // byte_offset for the next register.  Otherwise, we have a composite
+        // register whose
+        // offset can be calculated by consulting the offset of its first
+        // primordial register.
+        if (!g_register_infos[i].value_regs) {
+          g_register_infos[i].byte_offset = byte_offset;
+          byte_offset += g_register_infos[i].byte_size;
+        } else {
+          const uint32_t first_primordial_reg =
+              g_register_infos[i].value_regs[0];
+          g_register_infos[i].byte_offset =
+              g_register_infos[first_primordial_reg].byte_offset;
+        }
+      }
+    }
+    for (i = 0; i < num_registers; ++i) {
+      ConstString name;
+      ConstString alt_name;
+      if (g_register_infos[i].name && g_register_infos[i].name[0])
+        name.SetCString(g_register_infos[i].name);
+      if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0])
+        alt_name.SetCString(g_register_infos[i].alt_name);
+
+      if (i <= 15 || i == 25)
+        AddRegister(g_register_infos[i], name, alt_name, gpr_reg_set);
+      else if (i <= 24)
+        AddRegister(g_register_infos[i], name, alt_name, sfp_reg_set);
+      else
+        AddRegister(g_register_infos[i], name, alt_name, vfp_reg_set);
+    }
+  } else {
+    // Add composite registers to our primordial registers, then.
+    const size_t num_composites = llvm::array_lengthof(g_composites);
+    const size_t num_dynamic_regs = GetNumRegisters();
+    const size_t num_common_regs = num_registers - num_composites;
+    RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
+
+    // First we need to validate that all registers that we already have match
+    // the non composite regs.
+    // If so, then we can add the registers, else we need to bail
+    bool match = true;
+    if (num_dynamic_regs == num_common_regs) {
+      for (i = 0; match && i < num_dynamic_regs; ++i) {
+        // Make sure all register names match
+        if (m_regs[i].name && g_register_infos[i].name) {
+          if (strcmp(m_regs[i].name, g_register_infos[i].name)) {
             match = false;
+            break;
+          }
         }
-        // If "match" is true, then we can add extra registers.
-        if (match)
-        {
-            for (i=0; i<num_composites; ++i)
-            {
-                ConstString name;
-                ConstString alt_name;
-                const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0];
-                const char *reg_name = g_register_infos[first_primordial_reg].name;
-                if (reg_name && reg_name[0])
-                {
-                    for (uint32_t j = 0; j < num_dynamic_regs; ++j)
-                    {
-                        const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
-                        // Find a matching primordial register info entry.
-                        if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0)
-                        {
-                            // The name matches the existing primordial entry.
-                            // Find and assign the offset, and then add this composite register entry.
-                            g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
-                            name.SetCString(g_comp_register_infos[i].name);
-                            AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set);
-                        }
-                    }
-                }
+
+        // Make sure all register byte sizes match
+        if (m_regs[i].byte_size != g_register_infos[i].byte_size) {
+          match = false;
+          break;
+        }
+      }
+    } else {
+      // Wrong number of registers.
+      match = false;
+    }
+    // If "match" is true, then we can add extra registers.
+    if (match) {
+      for (i = 0; i < num_composites; ++i) {
+        ConstString name;
+        ConstString alt_name;
+        const uint32_t first_primordial_reg =
+            g_comp_register_infos[i].value_regs[0];
+        const char *reg_name = g_register_infos[first_primordial_reg].name;
+        if (reg_name && reg_name[0]) {
+          for (uint32_t j = 0; j < num_dynamic_regs; ++j) {
+            const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
+            // Find a matching primordial register info entry.
+            if (reg_info && reg_info->name &&
+                ::strcasecmp(reg_info->name, reg_name) == 0) {
+              // The name matches the existing primordial entry.
+              // Find and assign the offset, and then add this composite
+              // register entry.
+              g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
+              name.SetCString(g_comp_register_infos[i].name);
+              AddRegister(g_comp_register_infos[i], name, alt_name,
+                          vfp_reg_set);
             }
+          }
         }
+      }
     }
+  }
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h Tue Sep  6 15:57:50 2016
@@ -16,12 +16,12 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/lldb-enumerations.h"
+#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Target/RegisterContext.h"
-#include "Plugins/Process/Utility/DynamicRegisterInfo.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
 
 #include "GDBRemoteCommunicationClient.h"
 
@@ -33,130 +33,102 @@ namespace process_gdb_remote {
 class ThreadGDBRemote;
 class ProcessGDBRemote;
 
-class GDBRemoteDynamicRegisterInfo :
-    public DynamicRegisterInfo
-{
+class GDBRemoteDynamicRegisterInfo : public DynamicRegisterInfo {
 public:
-    GDBRemoteDynamicRegisterInfo () :
-        DynamicRegisterInfo()
-    {
-    }
+  GDBRemoteDynamicRegisterInfo() : DynamicRegisterInfo() {}
 
-    ~GDBRemoteDynamicRegisterInfo() override = default;
+  ~GDBRemoteDynamicRegisterInfo() override = default;
 
-    void
-    HardcodeARMRegisters(bool from_scratch);
+  void HardcodeARMRegisters(bool from_scratch);
 };
 
-class GDBRemoteRegisterContext : public RegisterContext
-{
+class GDBRemoteRegisterContext : public RegisterContext {
 public:
-    GDBRemoteRegisterContext (ThreadGDBRemote &thread,
-                              uint32_t concrete_frame_idx,
-                              GDBRemoteDynamicRegisterInfo &reg_info,
-                              bool read_all_at_once);
+  GDBRemoteRegisterContext(ThreadGDBRemote &thread, uint32_t concrete_frame_idx,
+                           GDBRemoteDynamicRegisterInfo &reg_info,
+                           bool read_all_at_once);
 
-    ~GDBRemoteRegisterContext() override;
+  ~GDBRemoteRegisterContext() override;
 
-    void
-    InvalidateAllRegisters () override;
+  void InvalidateAllRegisters() override;
 
-    size_t
-    GetRegisterCount () override;
+  size_t GetRegisterCount() override;
 
-    const RegisterInfo *
-    GetRegisterInfoAtIndex (size_t reg) override;
+  const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
 
-    size_t
-    GetRegisterSetCount () override;
+  size_t GetRegisterSetCount() override;
 
-    const RegisterSet *
-    GetRegisterSet (size_t reg_set) override;
+  const RegisterSet *GetRegisterSet(size_t reg_set) override;
 
-    bool
-    ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) override;
+  bool ReadRegister(const RegisterInfo *reg_info,
+                    RegisterValue &value) override;
 
-    bool
-    WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) override;
-    
-    bool
-    ReadAllRegisterValues (lldb::DataBufferSP &data_sp) override;
+  bool WriteRegister(const RegisterInfo *reg_info,
+                     const RegisterValue &value) override;
 
-    bool
-    WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) override;
+  bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
 
-    bool
-    ReadAllRegisterValues (RegisterCheckpoint &reg_checkpoint) override;
+  bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
 
-    bool
-    WriteAllRegisterValues (const RegisterCheckpoint &reg_checkpoint) override;
+  bool ReadAllRegisterValues(RegisterCheckpoint &reg_checkpoint) override;
 
-    uint32_t
-    ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) override;
+  bool
+  WriteAllRegisterValues(const RegisterCheckpoint &reg_checkpoint) override;
+
+  uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
+                                               uint32_t num) override;
 
 protected:
-    friend class ThreadGDBRemote;
+  friend class ThreadGDBRemote;
+
+  bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data);
+
+  bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data,
+                          uint32_t data_offset);
+
+  bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
+
+  bool PrivateSetRegisterValue(uint32_t reg, uint64_t val);
+
+  void SetAllRegisterValid(bool b);
 
-    bool
-    ReadRegisterBytes (const RegisterInfo *reg_info,
-                       DataExtractor &data);
-
-    bool
-    WriteRegisterBytes (const RegisterInfo *reg_info,
-                        DataExtractor &data, 
-                        uint32_t data_offset);
-
-    bool
-    PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
-
-    bool
-    PrivateSetRegisterValue (uint32_t reg, uint64_t val);
-
-    void
-    SetAllRegisterValid (bool b);
-
-    bool
-    GetRegisterIsValid (uint32_t reg) const
-    {
-#if defined (LLDB_CONFIGURATION_DEBUG)
-        assert (reg < m_reg_valid.size());
+  bool GetRegisterIsValid(uint32_t reg) const {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+    assert(reg < m_reg_valid.size());
 #endif
-        if (reg < m_reg_valid.size())
-            return m_reg_valid[reg];
-        return false;
-    }
-
-    void
-    SetRegisterIsValid (const RegisterInfo *reg_info, bool valid)
-    {
-        if (reg_info)
-            return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
-    }
-
-    void
-    SetRegisterIsValid (uint32_t reg, bool valid)
-    {
-#if defined (LLDB_CONFIGURATION_DEBUG)
-        assert (reg < m_reg_valid.size());
+    if (reg < m_reg_valid.size())
+      return m_reg_valid[reg];
+    return false;
+  }
+
+  void SetRegisterIsValid(const RegisterInfo *reg_info, bool valid) {
+    if (reg_info)
+      return SetRegisterIsValid(reg_info->kinds[lldb::eRegisterKindLLDB],
+                                valid);
+  }
+
+  void SetRegisterIsValid(uint32_t reg, bool valid) {
+#if defined(LLDB_CONFIGURATION_DEBUG)
+    assert(reg < m_reg_valid.size());
 #endif
-        if (reg < m_reg_valid.size())
-            m_reg_valid[reg] = valid;
-    }
-
-    GDBRemoteDynamicRegisterInfo &m_reg_info;
-    std::vector<bool> m_reg_valid;
-    DataExtractor m_reg_data;
-    bool m_read_all_at_once;
+    if (reg < m_reg_valid.size())
+      m_reg_valid[reg] = valid;
+  }
+
+  GDBRemoteDynamicRegisterInfo &m_reg_info;
+  std::vector<bool> m_reg_valid;
+  DataExtractor m_reg_data;
+  bool m_read_all_at_once;
 
 private:
-    // Helper function for ReadRegisterBytes().
-    bool GetPrimordialRegister(const RegisterInfo *reg_info,
-                               GDBRemoteCommunicationClient &gdb_comm);
-    // Helper function for WriteRegisterBytes().
-    bool SetPrimordialRegister(const RegisterInfo *reg_info,
-                               GDBRemoteCommunicationClient &gdb_comm);
+  // Helper function for ReadRegisterBytes().
+  bool GetPrimordialRegister(const RegisterInfo *reg_info,
+                             GDBRemoteCommunicationClient &gdb_comm);
+  // Helper function for WriteRegisterBytes().
+  bool SetPrimordialRegister(const RegisterInfo *reg_info,
+                             GDBRemoteCommunicationClient &gdb_comm);
 
-    DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext);
+  DISALLOW_COPY_AND_ASSIGN(GDBRemoteRegisterContext);
 };
 
 } // namespace process_gdb_remote




More information about the lldb-commits mailing list