diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
index f99352a..3b27c10 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
@@ -29,336 +29,333 @@
 
 GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;
 
-GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name, const char *listener_name)
-    : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0), m_is_running(false), m_should_stop(false)
-{
-}
+GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
+                                         const char *listener_name)
+    : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0),
+      m_is_running(false), m_should_stop(false) {}
 
-StateType
-GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals,
-                                                          llvm::StringRef payload, StringExtractorGDBRemote &response)
-{
-    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-    response.Clear();
+StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
+    ContinueDelegate &delegate, const UnixSignals &signals,
+    llvm::StringRef payload, StringExtractorGDBRemote &response) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  response.Clear();
 
-    {
-        std::lock_guard<std::mutex> lock(m_mutex);
-        m_continue_packet = payload;
-        m_should_stop = false;
-    }
-    ContinueLock cont_lock(*this);
-    if (!cont_lock)
-        return eStateInvalid;
-    OnRunPacketSent(true);
-
-    for (;;)
-    {
-        PacketResult read_result = ReadPacket(
-            response, std::chrono::duration_cast<std::chrono::microseconds>(kInterruptTimeout).count(), false);
-        switch (read_result)
-        {
-            case PacketResult::ErrorReplyTimeout:
-            {
-                std::lock_guard<std::mutex> lock(m_mutex);
-                if (m_async_count == 0)
-                    continue;
-                if (std::chrono::steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
-                    return eStateInvalid;
-            }
-            case PacketResult::Success:
-                break;
-            default:
-                if (log)
-                    log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false", __FUNCTION__);
-                return eStateInvalid;
-        }
-        if (response.Empty())
-            return eStateInvalid;
-
-        const char stop_type = response.GetChar();
-        if (log)
-            log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
-
-        switch (stop_type)
-        {
-            case 'W':
-            case 'X':
-                return eStateExited;
-            case 'E':
-                // ERROR
-                return eStateInvalid;
-            default:
-                if (log)
-                    log->Printf("GDBRemoteClientBase::%s () unrecognized async packet", __FUNCTION__);
-                return eStateInvalid;
-            case 'O':
-            {
-                std::string inferior_stdout;
-                response.GetHexByteString(inferior_stdout);
-                delegate.HandleAsyncStdout(inferior_stdout);
-                break;
-            }
-            case 'A':
-                delegate.HandleAsyncMisc(llvm::StringRef(response.GetStringRef()).substr(1));
-                break;
-
-            case 'J':
-                // Asynchronous JSON packet, destined for a
-                // StructuredDataPlugin.
-            {
-                // Parse the content into a StructuredData instance.
-                auto payload_index = strlen("JSON-async:");
-                StructuredData::ObjectSP json_sp =
-                    StructuredData::ParseJSON(response.GetStringRef()
-                                              .substr(payload_index));
-                if (log)
-                {
-                    if (json_sp)
-                        log->Printf(
-                                    "GDBRemoteCommmunicationClientBase::%s() "
-                                    "received Async StructuredData packet: %s",
-                                    __FUNCTION__,
-                                    response.GetStringRef().
-                                    substr(payload_index).c_str());
-                    else
-                        log->Printf("GDBRemoteCommmunicationClientBase::%s"
-                                    "() received StructuredData packet:"
-                                    " parse failure", __FUNCTION__);
-                }
-
-                // Pass the data to the process to route to the
-                // appropriate plugin.  The plugin controls what happens
-                // to it from there.
-                bool routed = delegate.HandleAsyncStructuredData(json_sp);
-                if (log)
-                    log->Printf("GDBRemoteCommmunicationClientBase::%s()"
-                                " packet %s", __FUNCTION__,
-                                routed ? "handled" : "not handled");
-                break;
-            }
-            case 'T':
-            case 'S':
-                // Do this with the continue lock held.
-                const bool should_stop = ShouldStop(signals, response);
-                response.SetFilePos(0);
-
-                // The packet we should resume with. In the future
-                // we should check our thread list and "do the right thing"
-                // for new threads that show up while we stop and run async
-                // packets. Setting the packet to 'c' to continue all threads
-                // is the right thing to do 99.99% of the time because if a
-                // thread was single stepping, and we sent an interrupt, we
-                // will notice above that we didn't stop due to an interrupt
-                // but stopped due to stepping and we would _not_ continue.
-                // This packet may get modified by the async actions (e.g. to send a signal).
-                m_continue_packet = 'c';
-                cont_lock.unlock();
-
-                delegate.HandleStopReply();
-                if (should_stop)
-                    return eStateStopped;
-
-                switch (cont_lock.lock())
-                {
-                    case ContinueLock::LockResult::Success:
-                        break;
-                    case ContinueLock::LockResult::Failed:
-                        return eStateInvalid;
-                    case ContinueLock::LockResult::Cancelled:
-                        return eStateStopped;
-                }
-                OnRunPacketSent(false);
-                break;
-        }
-    }
-}
-
-bool
-GDBRemoteClientBase::SendAsyncSignal(int signo)
-{
-    Lock lock(*this, true);
-    if (!lock || !lock.DidInterrupt())
-        return false;
-
-    m_continue_packet = 'C';
-    m_continue_packet += llvm::hexdigit((signo / 16) % 16);
-    m_continue_packet += llvm::hexdigit(signo % 16);
-    return true;
-}
-
-bool
-GDBRemoteClientBase::Interrupt()
-{
-    Lock lock(*this, true);
-    if (!lock.DidInterrupt())
-        return false;
-    m_should_stop = true;
-    return true;
-}
-GDBRemoteCommunication::PacketResult
-GDBRemoteClientBase::SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response,
-                                                  bool send_async)
-{
-    Lock lock(*this, send_async);
-    if (!lock)
-    {
-        if (Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
-            log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending packet '%.*s' (send_async=%d)",
-                        __FUNCTION__, int(payload.size()), payload.data(), send_async);
-        return PacketResult::ErrorSendFailed;
-    }
-
-    return SendPacketAndWaitForResponseNoLock(payload, response);
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response)
-{
-    PacketResult packet_result = SendPacketNoLock(payload);
-    if (packet_result != PacketResult::Success)
-        return packet_result;
-
-    const size_t max_response_retries = 3;
-    for (size_t i = 0; i < max_response_retries; ++i)
-    {
-        packet_result = ReadPacket(response, GetPacketTimeoutInMicroSeconds(), true);
-        // Make sure we received a response
-        if (packet_result != PacketResult::Success)
-            return packet_result;
-        // Make sure our response is valid for the payload that was sent
-        if (response.ValidateResponse())
-            return packet_result;
-        // Response says it wasn't valid
-        Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
-        if (log)
-            log->Printf("error: packet with payload \"%.*s\" got invalid response \"%s\": %s", int(payload.size()),
-                        payload.data(), response.GetStringRef().c_str(),
-                        (i == (max_response_retries - 1)) ? "using invalid response and giving up"
-                                                          : "ignoring response and waiting for another");
-    }
-    return packet_result;
-}
-
-bool
-GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload, StringExtractorGDBRemote &response)
-{
-    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
-
-    // we want to lock down packet sending while we continue
-    Lock lock(*this, true);
-
-    if (log)
-        log->Printf("GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s", __FUNCTION__, int(payload.size()),
-                    payload.data());
-
-    if (SendPacketNoLock(payload) != PacketResult::Success)
-        return false;
-
-    OnRunPacketSent(true);
-
-    // wait for the response to the vCont
-    if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-            return true;
-    }
-
-    return false;
-}
-bool
-GDBRemoteClientBase::ShouldStop(const UnixSignals &signals, StringExtractorGDBRemote &response)
-{
+  {
     std::lock_guard<std::mutex> lock(m_mutex);
+    m_continue_packet = payload;
+    m_should_stop = false;
+  }
+  ContinueLock cont_lock(*this);
+  if (!cont_lock)
+    return eStateInvalid;
+  OnRunPacketSent(true);
 
-    if (m_async_count == 0)
-        return true; // We were not interrupted. The process stopped on its own.
+  for (;;) {
+    PacketResult read_result = ReadPacket(
+        response,
+        std::chrono::duration_cast<std::chrono::microseconds>(kInterruptTimeout)
+            .count(),
+        false);
+    switch (read_result) {
+    case PacketResult::ErrorReplyTimeout: {
+      std::lock_guard<std::mutex> lock(m_mutex);
+      if (m_async_count == 0)
+        continue;
+      if (std::chrono::steady_clock::now() >=
+          m_interrupt_time + kInterruptTimeout)
+        return eStateInvalid;
+    }
+    case PacketResult::Success:
+      break;
+    default:
+      if (log)
+        log->Printf("GDBRemoteClientBase::%s () ReadPacket(...) => false",
+                    __FUNCTION__);
+      return eStateInvalid;
+    }
+    if (response.Empty())
+      return eStateInvalid;
 
-    // Older debugserver stubs (before April 2016) can return two
-    // stop-reply packets in response to a ^C packet.
-    // Additionally, all debugservers still return two stop replies if
-    // the inferior stops due to some other reason before the remote
-    // stub manages to interrupt it. We need to wait for this
-    // additional packet to make sure the packet sequence does not get
-    // skewed.
-    StringExtractorGDBRemote extra_stop_reply_packet;
-    uint32_t timeout_usec = 100000; // 100ms
-    ReadPacket(extra_stop_reply_packet, timeout_usec, false);
+    const char stop_type = response.GetChar();
+    if (log)
+      log->Printf("GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
+                  response.GetStringRef().c_str());
 
-    // Interrupting is typically done using SIGSTOP or SIGINT, so if
-    // the process stops with some other signal, we definitely want to
-    // stop.
-    const uint8_t signo = response.GetHexU8(UINT8_MAX);
-    if (signo != signals.GetSignalNumberFromName("SIGSTOP") && signo != signals.GetSignalNumberFromName("SIGINT"))
-        return true;
+    switch (stop_type) {
+    case 'W':
+    case 'X':
+      return eStateExited;
+    case 'E':
+      // ERROR
+      return eStateInvalid;
+    default:
+      if (log)
+        log->Printf("GDBRemoteClientBase::%s () unrecognized async packet",
+                    __FUNCTION__);
+      return eStateInvalid;
+    case 'O': {
+      std::string inferior_stdout;
+      response.GetHexByteString(inferior_stdout);
+      delegate.HandleAsyncStdout(inferior_stdout);
+      break;
+    }
+    case 'A':
+      delegate.HandleAsyncMisc(
+          llvm::StringRef(response.GetStringRef()).substr(1));
+      break;
 
-    // We probably only stopped to perform some async processing, so continue after that is done.
-    // TODO: This is not 100% correct, as the process may have been stopped with SIGINT or SIGSTOP
-    // that was not caused by us (e.g. raise(SIGINT)). This will normally cause a stop, but if it's
-    // done concurrently with a async interrupt, that stop will get eaten (llvm.org/pr20231).
-    return false;
+    case 'J':
+      // Asynchronous JSON packet, destined for a
+      // StructuredDataPlugin.
+      {
+        // Parse the content into a StructuredData instance.
+        auto payload_index = strlen("JSON-async:");
+        StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(
+            response.GetStringRef().substr(payload_index));
+        if (log) {
+          if (json_sp)
+            log->Printf("GDBRemoteCommmunicationClientBase::%s() "
+                        "received Async StructuredData packet: %s",
+                        __FUNCTION__,
+                        response.GetStringRef().substr(payload_index).c_str());
+          else
+            log->Printf("GDBRemoteCommmunicationClientBase::%s"
+                        "() received StructuredData packet:"
+                        " parse failure",
+                        __FUNCTION__);
+        }
+
+        // Pass the data to the process to route to the
+        // appropriate plugin.  The plugin controls what happens
+        // to it from there.
+        bool routed = delegate.HandleAsyncStructuredData(json_sp);
+        if (log)
+          log->Printf("GDBRemoteCommmunicationClientBase::%s()"
+                      " packet %s",
+                      __FUNCTION__, routed ? "handled" : "not handled");
+        break;
+      }
+    case 'T':
+    case 'S':
+      // Do this with the continue lock held.
+      const bool should_stop = ShouldStop(signals, response);
+      response.SetFilePos(0);
+
+      // The packet we should resume with. In the future
+      // we should check our thread list and "do the right thing"
+      // for new threads that show up while we stop and run async
+      // packets. Setting the packet to 'c' to continue all threads
+      // is the right thing to do 99.99% of the time because if a
+      // thread was single stepping, and we sent an interrupt, we
+      // will notice above that we didn't stop due to an interrupt
+      // but stopped due to stepping and we would _not_ continue.
+      // This packet may get modified by the async actions (e.g. to send a
+      // signal).
+      m_continue_packet = 'c';
+      cont_lock.unlock();
+
+      delegate.HandleStopReply();
+      if (should_stop)
+        return eStateStopped;
+
+      switch (cont_lock.lock()) {
+      case ContinueLock::LockResult::Success:
+        break;
+      case ContinueLock::LockResult::Failed:
+        return eStateInvalid;
+      case ContinueLock::LockResult::Cancelled:
+        return eStateStopped;
+      }
+      OnRunPacketSent(false);
+      break;
+    }
+  }
 }
 
-void
-GDBRemoteClientBase::OnRunPacketSent(bool first)
-{
-    if (first)
-        BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
+  Lock lock(*this, true);
+  if (!lock || !lock.DidInterrupt())
+    return false;
+
+  m_continue_packet = 'C';
+  m_continue_packet += llvm::hexdigit((signo / 16) % 16);
+  m_continue_packet += llvm::hexdigit(signo % 16);
+  return true;
+}
+
+bool GDBRemoteClientBase::Interrupt() {
+  Lock lock(*this, true);
+  if (!lock.DidInterrupt())
+    return false;
+  m_should_stop = true;
+  return true;
+}
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndWaitForResponse(
+    llvm::StringRef payload, StringExtractorGDBRemote &response,
+    bool send_async) {
+  Lock lock(*this, send_async);
+  if (!lock) {
+    if (Log *log =
+            ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
+      log->Printf("GDBRemoteClientBase::%s failed to get mutex, not sending "
+                  "packet '%.*s' (send_async=%d)",
+                  __FUNCTION__, int(payload.size()), payload.data(),
+                  send_async);
+    return PacketResult::ErrorSendFailed;
+  }
+
+  return SendPacketAndWaitForResponseNoLock(payload, response);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
+    llvm::StringRef payload, StringExtractorGDBRemote &response) {
+  PacketResult packet_result = SendPacketNoLock(payload);
+  if (packet_result != PacketResult::Success)
+    return packet_result;
+
+  const size_t max_response_retries = 3;
+  for (size_t i = 0; i < max_response_retries; ++i) {
+    packet_result =
+        ReadPacket(response, GetPacketTimeoutInMicroSeconds(), true);
+    // Make sure we received a response
+    if (packet_result != PacketResult::Success)
+      return packet_result;
+    // Make sure our response is valid for the payload that was sent
+    if (response.ValidateResponse())
+      return packet_result;
+    // Response says it wasn't valid
+    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
+    if (log)
+      log->Printf(
+          "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
+          int(payload.size()), payload.data(), response.GetStringRef().c_str(),
+          (i == (max_response_retries - 1))
+              ? "using invalid response and giving up"
+              : "ignoring response and waiting for another");
+  }
+  return packet_result;
+}
+
+bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
+                                          StringExtractorGDBRemote &response) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+
+  // we want to lock down packet sending while we continue
+  Lock lock(*this, true);
+
+  if (log)
+    log->Printf(
+        "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
+        __FUNCTION__, int(payload.size()), payload.data());
+
+  if (SendPacketNoLock(payload) != PacketResult::Success)
+    return false;
+
+  OnRunPacketSent(true);
+
+  // wait for the response to the vCont
+  if (ReadPacket(response, UINT32_MAX, false) == PacketResult::Success) {
+    if (response.IsOKResponse())
+      return true;
+  }
+
+  return false;
+}
+bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
+                                     StringExtractorGDBRemote &response) {
+  std::lock_guard<std::mutex> lock(m_mutex);
+
+  if (m_async_count == 0)
+    return true; // We were not interrupted. The process stopped on its own.
+
+  // Older debugserver stubs (before April 2016) can return two
+  // stop-reply packets in response to a ^C packet.
+  // Additionally, all debugservers still return two stop replies if
+  // the inferior stops due to some other reason before the remote
+  // stub manages to interrupt it. We need to wait for this
+  // additional packet to make sure the packet sequence does not get
+  // skewed.
+  StringExtractorGDBRemote extra_stop_reply_packet;
+  uint32_t timeout_usec = 100000; // 100ms
+  ReadPacket(extra_stop_reply_packet, timeout_usec, false);
+
+  // Interrupting is typically done using SIGSTOP or SIGINT, so if
+  // the process stops with some other signal, we definitely want to
+  // stop.
+  const uint8_t signo = response.GetHexU8(UINT8_MAX);
+  if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
+      signo != signals.GetSignalNumberFromName("SIGINT"))
+    return true;
+
+  // We probably only stopped to perform some async processing, so continue
+  // after that is done.
+  // TODO: This is not 100% correct, as the process may have been stopped with
+  // SIGINT or SIGSTOP
+  // that was not caused by us (e.g. raise(SIGINT)). This will normally cause a
+  // stop, but if it's
+  // done concurrently with a async interrupt, that stop will get eaten
+  // (llvm.org/pr20231).
+  return false;
+}
+
+void GDBRemoteClientBase::OnRunPacketSent(bool first) {
+  if (first)
+    BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
 }
 
 ///////////////////////////////////////
 // GDBRemoteClientBase::ContinueLock //
 ///////////////////////////////////////
 
-GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm) : m_comm(comm), m_acquired(false)
-{
-    lock();
+GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm)
+    : m_comm(comm), m_acquired(false) {
+  lock();
 }
 
-GDBRemoteClientBase::ContinueLock::~ContinueLock()
-{
-    if (m_acquired)
-        unlock();
+GDBRemoteClientBase::ContinueLock::~ContinueLock() {
+  if (m_acquired)
+    unlock();
 }
 
-void
-GDBRemoteClientBase::ContinueLock::unlock()
-{
-    lldbassert(m_acquired);
-    {
-        std::unique_lock<std::mutex> lock(m_comm.m_mutex);
-        m_comm.m_is_running = false;
-    }
-    m_comm.m_cv.notify_all();
-    m_acquired = false;
+void GDBRemoteClientBase::ContinueLock::unlock() {
+  lldbassert(m_acquired);
+  {
+    std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+    m_comm.m_is_running = false;
+  }
+  m_comm.m_cv.notify_all();
+  m_acquired = false;
 }
 
 GDBRemoteClientBase::ContinueLock::LockResult
-GDBRemoteClientBase::ContinueLock::lock()
-{
-    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
+GDBRemoteClientBase::ContinueLock::lock() {
+  Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
+  if (log)
+    log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
+                __FUNCTION__, m_comm.m_continue_packet.c_str());
+
+  lldbassert(!m_acquired);
+  std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+  m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
+  if (m_comm.m_should_stop) {
+    m_comm.m_should_stop = false;
     if (log)
-        log->Printf("GDBRemoteClientBase::ContinueLock::%s() resuming with %s", __FUNCTION__,
-                    m_comm.m_continue_packet.c_str());
+      log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled",
+                  __FUNCTION__);
+    return LockResult::Cancelled;
+  }
+  if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
+      PacketResult::Success)
+    return LockResult::Failed;
 
-    lldbassert(!m_acquired);
-    std::unique_lock<std::mutex> lock(m_comm.m_mutex);
-    m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
-    if (m_comm.m_should_stop)
-    {
-        m_comm.m_should_stop = false;
-        if (log)
-            log->Printf("GDBRemoteClientBase::ContinueLock::%s() cancelled", __FUNCTION__);
-        return LockResult::Cancelled;
-    }
-    if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) != PacketResult::Success)
-        return LockResult::Failed;
-
-    lldbassert(!m_comm.m_is_running);
-    m_comm.m_is_running = true;
-    m_acquired = true;
-    return LockResult::Success;
+  lldbassert(!m_comm.m_is_running);
+  m_comm.m_is_running = true;
+  m_acquired = true;
+  return LockResult::Success;
 }
 
 ///////////////////////////////
@@ -366,54 +363,51 @@
 ///////////////////////////////
 
 GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
-    : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm), m_acquired(false), m_did_interrupt(false)
-{
-    SyncWithContinueThread(interrupt);
-    if (m_acquired)
-        m_async_lock.lock();
+    : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
+      m_acquired(false), m_did_interrupt(false) {
+  SyncWithContinueThread(interrupt);
+  if (m_acquired)
+    m_async_lock.lock();
 }
 
-void
-GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt)
-{
-    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-    std::unique_lock<std::mutex> lock(m_comm.m_mutex);
-    if (m_comm.m_is_running && !interrupt)
-        return; // We were asked to avoid interrupting the sender. Lock is not acquired.
+void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+  if (m_comm.m_is_running && !interrupt)
+    return; // We were asked to avoid interrupting the sender. Lock is not
+            // acquired.
 
-    ++m_comm.m_async_count;
-    if (m_comm.m_is_running)
-    {
-        if (m_comm.m_async_count == 1)
-        {
-            // The sender has sent the continue packet and we are the first async packet. Let's interrupt it.
-            const char ctrl_c = '\x03';
-            ConnectionStatus status = eConnectionStatusSuccess;
-            size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
-            if (bytes_written == 0)
-            {
-                --m_comm.m_async_count;
-                if (log)
-                    log->Printf("GDBRemoteClientBase::Lock::Lock failed to send interrupt packet");
-                return;
-            }
-            if (log)
-                log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
-            m_comm.m_interrupt_time = std::chrono::steady_clock::now();
-        }
-        m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
-        m_did_interrupt = true;
-    }
-    m_acquired = true;
-}
-
-GDBRemoteClientBase::Lock::~Lock()
-{
-    if (!m_acquired)
-        return;
-    {
-        std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+  ++m_comm.m_async_count;
+  if (m_comm.m_is_running) {
+    if (m_comm.m_async_count == 1) {
+      // The sender has sent the continue packet and we are the first async
+      // packet. Let's interrupt it.
+      const char ctrl_c = '\x03';
+      ConnectionStatus status = eConnectionStatusSuccess;
+      size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, NULL);
+      if (bytes_written == 0) {
         --m_comm.m_async_count;
+        if (log)
+          log->Printf("GDBRemoteClientBase::Lock::Lock failed to send "
+                      "interrupt packet");
+        return;
+      }
+      if (log)
+        log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
+      m_comm.m_interrupt_time = std::chrono::steady_clock::now();
     }
-    m_comm.m_cv.notify_one();
+    m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; });
+    m_did_interrupt = true;
+  }
+  m_acquired = true;
+}
+
+GDBRemoteClientBase::Lock::~Lock() {
+  if (!m_acquired)
+    return;
+  {
+    std::unique_lock<std::mutex> lock(m_comm.m_mutex);
+    --m_comm.m_async_count;
+  }
+  m_comm.m_cv.notify_one();
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
index 684ef3e..f392895 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
@@ -14,147 +14,136 @@
 
 #include <condition_variable>
 
-namespace lldb_private
-{
-namespace process_gdb_remote
-{
+namespace lldb_private {
+namespace process_gdb_remote {
 
-class GDBRemoteClientBase : public GDBRemoteCommunication
-{
+class GDBRemoteClientBase : public GDBRemoteCommunication {
 public:
-    struct ContinueDelegate
-    {
-        virtual ~ContinueDelegate();
-        virtual void
-        HandleAsyncStdout(llvm::StringRef out) = 0;
-        virtual void
-        HandleAsyncMisc(llvm::StringRef data) = 0;
-        virtual void
-        HandleStopReply() = 0;
+  struct ContinueDelegate {
+    virtual ~ContinueDelegate();
+    virtual void HandleAsyncStdout(llvm::StringRef out) = 0;
+    virtual void HandleAsyncMisc(llvm::StringRef data) = 0;
+    virtual void HandleStopReply() = 0;
 
-        //
-        /// Processes async structured data.
-        ///
-        /// @return
-        ///    true if the data was handled; otherwise, false.
-        //
-        virtual bool
-        HandleAsyncStructuredData(const StructuredData::ObjectSP
-                                  &object_sp) = 0;
-    };
+    //
+    /// Processes async structured data.
+    ///
+    /// @return
+    ///    true if the data was handled; otherwise, false.
+    //
+    virtual bool
+    HandleAsyncStructuredData(const StructuredData::ObjectSP &object_sp) = 0;
+  };
 
-    GDBRemoteClientBase(const char *comm_name, const char *listener_name);
+  GDBRemoteClientBase(const char *comm_name, const char *listener_name);
 
-    bool
-    SendAsyncSignal(int signo);
+  bool SendAsyncSignal(int signo);
 
-    bool
-    Interrupt();
+  bool Interrupt();
 
-    lldb::StateType
-    SendContinuePacketAndWaitForResponse(ContinueDelegate &delegate, const UnixSignals &signals,
-                                         llvm::StringRef payload, StringExtractorGDBRemote &response);
+  lldb::StateType SendContinuePacketAndWaitForResponse(
+      ContinueDelegate &delegate, const UnixSignals &signals,
+      llvm::StringRef payload, StringExtractorGDBRemote &response);
 
-    PacketResult
-    SendPacketAndWaitForResponse(const char *payload, size_t len, StringExtractorGDBRemote &response, bool send_async)
-    {
-        return SendPacketAndWaitForResponse(llvm::StringRef(payload, len), response, send_async);
-    }
+  PacketResult SendPacketAndWaitForResponse(const char *payload, size_t len,
+                                            StringExtractorGDBRemote &response,
+                                            bool send_async) {
+    return SendPacketAndWaitForResponse(llvm::StringRef(payload, len), response,
+                                        send_async);
+  }
 
-    PacketResult
-    SendPacketAndWaitForResponse(llvm::StringRef payload, StringExtractorGDBRemote &response, bool send_async);
+  PacketResult SendPacketAndWaitForResponse(llvm::StringRef payload,
+                                            StringExtractorGDBRemote &response,
+                                            bool send_async);
 
-    bool
-    SendvContPacket(llvm::StringRef payload, StringExtractorGDBRemote &response);
+  bool SendvContPacket(llvm::StringRef payload,
+                       StringExtractorGDBRemote &response);
 
-    class Lock
-    {
-    public:
-        Lock(GDBRemoteClientBase &comm, bool interrupt);
-        ~Lock();
+  class Lock {
+  public:
+    Lock(GDBRemoteClientBase &comm, bool interrupt);
+    ~Lock();
 
-        explicit operator bool() { return m_acquired; }
+    explicit operator bool() { return m_acquired; }
 
-        // Whether we had to interrupt the continue thread to acquire the connection.
-        bool
-        DidInterrupt() const
-        {
-            return m_did_interrupt;
-        }
+    // Whether we had to interrupt the continue thread to acquire the
+    // connection.
+    bool DidInterrupt() const { return m_did_interrupt; }
 
-    private:
-        std::unique_lock<std::recursive_mutex> m_async_lock;
-        GDBRemoteClientBase &m_comm;
-        bool m_acquired;
-        bool m_did_interrupt;
+  private:
+    std::unique_lock<std::recursive_mutex> m_async_lock;
+    GDBRemoteClientBase &m_comm;
+    bool m_acquired;
+    bool m_did_interrupt;
 
-        void
-        SyncWithContinueThread(bool interrupt);
-    };
+    void SyncWithContinueThread(bool interrupt);
+  };
 
 protected:
-    PacketResult
-    SendPacketAndWaitForResponseNoLock(llvm::StringRef payload, StringExtractorGDBRemote &response);
+  PacketResult
+  SendPacketAndWaitForResponseNoLock(llvm::StringRef payload,
+                                     StringExtractorGDBRemote &response);
 
-    virtual void
-    OnRunPacketSent(bool first);
+  virtual void OnRunPacketSent(bool first);
 
 private:
-    // Variables handling synchronization between the Continue thread and any other threads
-    // wishing to send packets over the connection. Either the continue thread has control over
-    // the connection (m_is_running == true) or the connection is free for an arbitrary number of
-    // other senders to take which indicate their interest by incrementing m_async_count.
-    // Semantics of individual states:
-    // - m_continue_packet == false, m_async_count == 0: connection is free
-    // - m_continue_packet == true, m_async_count == 0: only continue thread is present
-    // - m_continue_packet == true, m_async_count > 0: continue thread has control, async threads
-    //   should interrupt it and wait for it to set m_continue_packet to false
-    // - m_continue_packet == false, m_async_count > 0: async threads have control, continue
-    //   thread needs to wait for them to finish (m_async_count goes down to 0).
-    std::mutex m_mutex;
-    std::condition_variable m_cv;
-    // Packet with which to resume after an async interrupt. Can be changed by an async thread
-    // e.g. to inject a signal.
-    std::string m_continue_packet;
-    // When was the interrupt packet sent. Used to make sure we time out if the stub does not
-    // respond to interrupt requests.
-    std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
-    uint32_t m_async_count;
-    bool m_is_running;
-    bool m_should_stop; // Whether we should resume after a stop.
-    // end of continue thread synchronization block
+  // Variables handling synchronization between the Continue thread and any
+  // other threads
+  // wishing to send packets over the connection. Either the continue thread has
+  // control over
+  // the connection (m_is_running == true) or the connection is free for an
+  // arbitrary number of
+  // other senders to take which indicate their interest by incrementing
+  // m_async_count.
+  // Semantics of individual states:
+  // - m_continue_packet == false, m_async_count == 0: connection is free
+  // - m_continue_packet == true, m_async_count == 0: only continue thread is
+  // present
+  // - m_continue_packet == true, m_async_count > 0: continue thread has
+  // control, async threads
+  //   should interrupt it and wait for it to set m_continue_packet to false
+  // - m_continue_packet == false, m_async_count > 0: async threads have
+  // control, continue
+  //   thread needs to wait for them to finish (m_async_count goes down to 0).
+  std::mutex m_mutex;
+  std::condition_variable m_cv;
+  // Packet with which to resume after an async interrupt. Can be changed by an
+  // async thread
+  // e.g. to inject a signal.
+  std::string m_continue_packet;
+  // When was the interrupt packet sent. Used to make sure we time out if the
+  // stub does not
+  // respond to interrupt requests.
+  std::chrono::time_point<std::chrono::steady_clock> m_interrupt_time;
+  uint32_t m_async_count;
+  bool m_is_running;
+  bool m_should_stop; // Whether we should resume after a stop.
+  // end of continue thread synchronization block
 
-    // This handles the synchronization between individual async threads. For now they just use a
-    // simple mutex.
-    std::recursive_mutex m_async_mutex;
+  // This handles the synchronization between individual async threads. For now
+  // they just use a
+  // simple mutex.
+  std::recursive_mutex m_async_mutex;
 
-    bool
-    ShouldStop(const UnixSignals &signals, StringExtractorGDBRemote &response);
+  bool ShouldStop(const UnixSignals &signals,
+                  StringExtractorGDBRemote &response);
 
-    class ContinueLock
-    {
-    public:
-        enum class LockResult
-        {
-            Success,
-            Cancelled,
-            Failed
-        };
+  class ContinueLock {
+  public:
+    enum class LockResult { Success, Cancelled, Failed };
 
-        explicit ContinueLock(GDBRemoteClientBase &comm);
-        ~ContinueLock();
-        explicit operator bool() { return m_acquired; }
+    explicit ContinueLock(GDBRemoteClientBase &comm);
+    ~ContinueLock();
+    explicit operator bool() { return m_acquired; }
 
-        LockResult
-        lock();
+    LockResult lock();
 
-        void
-        unlock();
+    void unlock();
 
-    private:
-        GDBRemoteClientBase &m_comm;
-        bool m_acquired;
-    };
+  private:
+    GDBRemoteClientBase &m_comm;
+    bool m_acquired;
+  };
 };
 
 } // namespace process_gdb_remote
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f3892d2..ef3e75b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "GDBRemoteCommunication.h"
 
 // C Includes
@@ -39,16 +38,16 @@
 #include "ProcessGDBRemoteLog.h"
 
 #if defined(__APPLE__)
-# define DEBUGSERVER_BASENAME    "debugserver"
+#define DEBUGSERVER_BASENAME "debugserver"
 #else
-# define DEBUGSERVER_BASENAME    "lldb-server"
+#define DEBUGSERVER_BASENAME "lldb-server"
 #endif
 
-#if defined (HAVE_LIBCOMPRESSION)
+#if defined(HAVE_LIBCOMPRESSION)
 #include <compression.h>
 #endif
 
-#if defined (HAVE_LIBZ)
+#if defined(HAVE_LIBZ)
 #include <zlib.h>
 #endif
 
@@ -56,1434 +55,1328 @@
 using namespace lldb_private;
 using namespace lldb_private::process_gdb_remote;
 
-GDBRemoteCommunication::History::History (uint32_t size) :
-    m_packets(),
-    m_curr_idx (0),
-    m_total_packet_count (0),
-    m_dumped_to_log (false)
-{
-    m_packets.resize(size);
+GDBRemoteCommunication::History::History(uint32_t size)
+    : m_packets(), m_curr_idx(0), m_total_packet_count(0),
+      m_dumped_to_log(false) {
+  m_packets.resize(size);
 }
 
-GDBRemoteCommunication::History::~History ()
-{
+GDBRemoteCommunication::History::~History() {}
+
+void GDBRemoteCommunication::History::AddPacket(char packet_char,
+                                                PacketType type,
+                                                uint32_t bytes_transmitted) {
+  const size_t size = m_packets.size();
+  if (size > 0) {
+    const uint32_t idx = GetNextIndex();
+    m_packets[idx].packet.assign(1, packet_char);
+    m_packets[idx].type = type;
+    m_packets[idx].bytes_transmitted = bytes_transmitted;
+    m_packets[idx].packet_idx = m_total_packet_count;
+    m_packets[idx].tid = Host::GetCurrentThreadID();
+  }
 }
 
-void
-GDBRemoteCommunication::History::AddPacket (char packet_char,
-                                            PacketType type,
-                                            uint32_t bytes_transmitted)
-{
-    const size_t size = m_packets.size();
-    if (size > 0)
-    {
-        const uint32_t idx = GetNextIndex();
-        m_packets[idx].packet.assign (1, packet_char);
-        m_packets[idx].type = type;
-        m_packets[idx].bytes_transmitted = bytes_transmitted;
-        m_packets[idx].packet_idx = m_total_packet_count;
-        m_packets[idx].tid = Host::GetCurrentThreadID();
-    }
+void GDBRemoteCommunication::History::AddPacket(const std::string &src,
+                                                uint32_t src_len,
+                                                PacketType type,
+                                                uint32_t bytes_transmitted) {
+  const size_t size = m_packets.size();
+  if (size > 0) {
+    const uint32_t idx = GetNextIndex();
+    m_packets[idx].packet.assign(src, 0, src_len);
+    m_packets[idx].type = type;
+    m_packets[idx].bytes_transmitted = bytes_transmitted;
+    m_packets[idx].packet_idx = m_total_packet_count;
+    m_packets[idx].tid = Host::GetCurrentThreadID();
+  }
 }
 
-void
-GDBRemoteCommunication::History::AddPacket (const std::string &src,
-                                            uint32_t src_len,
-                                            PacketType type,
-                                            uint32_t bytes_transmitted)
-{
-    const size_t size = m_packets.size();
-    if (size > 0)
-    {
-        const uint32_t idx = GetNextIndex();
-        m_packets[idx].packet.assign (src, 0, src_len);
-        m_packets[idx].type = type;
-        m_packets[idx].bytes_transmitted = bytes_transmitted;
-        m_packets[idx].packet_idx = m_total_packet_count;
-        m_packets[idx].tid = Host::GetCurrentThreadID();
-    }
+void GDBRemoteCommunication::History::Dump(Stream &strm) const {
+  const uint32_t size = GetNumPacketsInHistory();
+  const uint32_t first_idx = GetFirstSavedPacketIndex();
+  const uint32_t stop_idx = m_curr_idx + size;
+  for (uint32_t i = first_idx; i < stop_idx; ++i) {
+    const uint32_t idx = NormalizeIndex(i);
+    const Entry &entry = m_packets[idx];
+    if (entry.type == ePacketTypeInvalid || entry.packet.empty())
+      break;
+    strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
+                entry.packet_idx, entry.tid, entry.bytes_transmitted,
+                (entry.type == ePacketTypeSend) ? "send" : "read",
+                entry.packet.c_str());
+  }
 }
 
-void
-GDBRemoteCommunication::History::Dump (Stream &strm) const
-{
-    const uint32_t size = GetNumPacketsInHistory ();
-    const uint32_t first_idx = GetFirstSavedPacketIndex ();
+void GDBRemoteCommunication::History::Dump(Log *log) const {
+  if (log && !m_dumped_to_log) {
+    m_dumped_to_log = true;
+    const uint32_t size = GetNumPacketsInHistory();
+    const uint32_t first_idx = GetFirstSavedPacketIndex();
     const uint32_t stop_idx = m_curr_idx + size;
-    for (uint32_t i = first_idx;  i < stop_idx; ++i)
-    {
-        const uint32_t idx = NormalizeIndex (i);
-        const Entry &entry = m_packets[idx];
-        if (entry.type == ePacketTypeInvalid || entry.packet.empty())
-            break;
-        strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
-                     entry.packet_idx,
-                     entry.tid,
-                     entry.bytes_transmitted,
-                     (entry.type == ePacketTypeSend) ? "send" : "read",
-                     entry.packet.c_str());
+    for (uint32_t i = first_idx; i < stop_idx; ++i) {
+      const uint32_t idx = NormalizeIndex(i);
+      const Entry &entry = m_packets[idx];
+      if (entry.type == ePacketTypeInvalid || entry.packet.empty())
+        break;
+      log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
+                  entry.packet_idx, entry.tid, entry.bytes_transmitted,
+                  (entry.type == ePacketTypeSend) ? "send" : "read",
+                  entry.packet.c_str());
     }
-}
-
-void
-GDBRemoteCommunication::History::Dump (Log *log) const
-{
-    if (log && !m_dumped_to_log)
-    {
-        m_dumped_to_log = true;
-        const uint32_t size = GetNumPacketsInHistory ();
-        const uint32_t first_idx = GetFirstSavedPacketIndex ();
-        const uint32_t stop_idx = m_curr_idx + size;
-        for (uint32_t i = first_idx;  i < stop_idx; ++i)
-        {
-            const uint32_t idx = NormalizeIndex (i);
-            const Entry &entry = m_packets[idx];
-            if (entry.type == ePacketTypeInvalid || entry.packet.empty())
-                break;
-            log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
-                         entry.packet_idx,
-                         entry.tid,
-                         entry.bytes_transmitted,
-                         (entry.type == ePacketTypeSend) ? "send" : "read",
-                         entry.packet.c_str());
-        }
-    }
+  }
 }
 
 //----------------------------------------------------------------------
 // GDBRemoteCommunication constructor
 //----------------------------------------------------------------------
-GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name)
+GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
+                                               const char *listener_name)
     : Communication(comm_name),
 #ifdef LLDB_CONFIGURATION_DEBUG
       m_packet_timeout(1000),
 #else
       m_packet_timeout(1),
 #endif
-      m_echo_number(0),
-      m_supports_qEcho(eLazyBoolCalculate),
-      m_history(512),
-      m_send_acks(true),
-      m_compression_type(CompressionType::None),
-      m_listen_url()
-{
+      m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512),
+      m_send_acks(true), m_compression_type(CompressionType::None),
+      m_listen_url() {
 }
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-GDBRemoteCommunication::~GDBRemoteCommunication()
-{
-    if (IsConnected())
-    {
-        Disconnect();
-    }
+GDBRemoteCommunication::~GDBRemoteCommunication() {
+  if (IsConnected()) {
+    Disconnect();
+  }
 
-    // Stop the communications read thread which is used to parse all
-    // incoming packets.  This function will block until the read
-    // thread returns.
-    if (m_read_thread_enabled)
-        StopReadThread();
+  // Stop the communications read thread which is used to parse all
+  // incoming packets.  This function will block until the read
+  // thread returns.
+  if (m_read_thread_enabled)
+    StopReadThread();
 }
 
-char
-GDBRemoteCommunication::CalculcateChecksum (llvm::StringRef payload)
-{
-    int checksum = 0;
+char GDBRemoteCommunication::CalculcateChecksum(llvm::StringRef payload) {
+  int checksum = 0;
 
-    for (char c : payload)
-        checksum += c;
+  for (char c : payload)
+    checksum += c;
 
-    return checksum & 255;
+  return checksum & 255;
 }
 
-size_t
-GDBRemoteCommunication::SendAck ()
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+size_t GDBRemoteCommunication::SendAck() {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+  ConnectionStatus status = eConnectionStatusSuccess;
+  char ch = '+';
+  const size_t bytes_written = Write(&ch, 1, status, NULL);
+  if (log)
+    log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+  m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written);
+  return bytes_written;
+}
+
+size_t GDBRemoteCommunication::SendNack() {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
+  ConnectionStatus status = eConnectionStatusSuccess;
+  char ch = '-';
+  const size_t bytes_written = Write(&ch, 1, status, NULL);
+  if (log)
+    log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
+  m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written);
+  return bytes_written;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) {
+  if (IsConnected()) {
+    StreamString packet(0, 4, eByteOrderBig);
+
+    packet.PutChar('$');
+    packet.Write(payload.data(), payload.size());
+    packet.PutChar('#');
+    packet.PutHex8(CalculcateChecksum(payload));
+
+    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
     ConnectionStatus status = eConnectionStatusSuccess;
-    char ch = '+';
-    const size_t bytes_written = Write (&ch, 1, status, NULL);
-    if (log)
-        log->Printf ("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
-    m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
-    return bytes_written;
-}
-
-size_t
-GDBRemoteCommunication::SendNack ()
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-    ConnectionStatus status = eConnectionStatusSuccess;
-    char ch = '-';
-    const size_t bytes_written = Write (&ch, 1, status, NULL);
-    if (log)
-        log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch);
-    m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written);
-    return bytes_written;
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::SendPacketNoLock (llvm::StringRef payload)
-{
-    if (IsConnected())
-    {
-        StreamString packet(0, 4, eByteOrderBig);
-
-        packet.PutChar('$');
-        packet.Write (payload.data(), payload.size());
-        packet.PutChar('#');
-        packet.PutHex8(CalculcateChecksum (payload));
-
-        Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
-        ConnectionStatus status = eConnectionStatusSuccess;
-        const char *packet_data = packet.GetData();
-        const size_t packet_length = packet.GetSize();
-        size_t bytes_written = Write (packet_data, packet_length, status, NULL);
-        if (log)
-        {
-            size_t binary_start_offset = 0;
-            if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == 0)
-            {
-                const char *first_comma = strchr(packet_data, ',');
-                if (first_comma)
-                {
-                    const char *second_comma = strchr(first_comma + 1, ',');
-                    if (second_comma)
-                        binary_start_offset = second_comma - packet_data + 1;
-                }
-            }
-
-            // If logging was just enabled and we have history, then dump out what
-            // we have to the log so we get the historical context. The Dump() call that
-            // logs all of the packet will set a boolean so that we don't dump this more
-            // than once
-            if (!m_history.DidDumpToLog ())
-                m_history.Dump (log);
-
-            if (binary_start_offset)
-            {
-                StreamString strm;
-                // Print non binary data header
-                strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)binary_start_offset, packet_data);
-                const uint8_t *p;
-                // Print binary data exactly as sent
-                for (p = (const uint8_t*)packet_data + binary_start_offset; *p != '#'; ++p)
-                    strm.Printf("\\x%2.2x", *p);
-                // Print the checksum
-                strm.Printf("%*s", (int)3, p);
-                log->PutCString(strm.GetString().c_str());
-            }
-            else
-                log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written, (int)packet_length, packet_data);
+    const char *packet_data = packet.GetData();
+    const size_t packet_length = packet.GetSize();
+    size_t bytes_written = Write(packet_data, packet_length, status, NULL);
+    if (log) {
+      size_t binary_start_offset = 0;
+      if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) ==
+          0) {
+        const char *first_comma = strchr(packet_data, ',');
+        if (first_comma) {
+          const char *second_comma = strchr(first_comma + 1, ',');
+          if (second_comma)
+            binary_start_offset = second_comma - packet_data + 1;
         }
+      }
 
-        m_history.AddPacket (packet.GetString(), packet_length, History::ePacketTypeSend, bytes_written);
+      // If logging was just enabled and we have history, then dump out what
+      // we have to the log so we get the historical context. The Dump() call
+      // that
+      // logs all of the packet will set a boolean so that we don't dump this
+      // more
+      // than once
+      if (!m_history.DidDumpToLog())
+        m_history.Dump(log);
 
-
-        if (bytes_written == packet_length)
-        {
-            if (GetSendAcks ())
-                return GetAck ();
-            else
-                return PacketResult::Success;
-        }
-        else
-        {
-            if (log)
-                log->Printf ("error: failed to send packet: %.*s", (int)packet_length, packet_data);
-        }
+      if (binary_start_offset) {
+        StreamString strm;
+        // Print non binary data header
+        strm.Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
+                    (int)binary_start_offset, packet_data);
+        const uint8_t *p;
+        // Print binary data exactly as sent
+        for (p = (const uint8_t *)packet_data + binary_start_offset; *p != '#';
+             ++p)
+          strm.Printf("\\x%2.2x", *p);
+        // Print the checksum
+        strm.Printf("%*s", (int)3, p);
+        log->PutCString(strm.GetString().c_str());
+      } else
+        log->Printf("<%4" PRIu64 "> send packet: %.*s", (uint64_t)bytes_written,
+                    (int)packet_length, packet_data);
     }
-    return PacketResult::ErrorSendFailed;
-}
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::GetAck ()
-{
-    StringExtractorGDBRemote packet;
-    PacketResult result = ReadPacket (packet, GetPacketTimeoutInMicroSeconds (), false);
-    if (result == PacketResult::Success)
-    {
-        if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
-            return PacketResult::Success;
-        else
-            return PacketResult::ErrorSendAck;
+    m_history.AddPacket(packet.GetString(), packet_length,
+                        History::ePacketTypeSend, bytes_written);
+
+    if (bytes_written == packet_length) {
+      if (GetSendAcks())
+        return GetAck();
+      else
+        return PacketResult::Success;
+    } else {
+      if (log)
+        log->Printf("error: failed to send packet: %.*s", (int)packet_length,
+                    packet_data);
     }
-    return result;
+  }
+  return PacketResult::ErrorSendFailed;
+}
+
+GDBRemoteCommunication::PacketResult GDBRemoteCommunication::GetAck() {
+  StringExtractorGDBRemote packet;
+  PacketResult result =
+      ReadPacket(packet, GetPacketTimeoutInMicroSeconds(), false);
+  if (result == PacketResult::Success) {
+    if (packet.GetResponseType() ==
+        StringExtractorGDBRemote::ResponseType::eAck)
+      return PacketResult::Success;
+    else
+      return PacketResult::ErrorSendAck;
+  }
+  return result;
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout)
-{
-   if (m_read_thread_enabled)
-       return PopPacketFromQueue (response, timeout_usec);
-   else
-       return WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec, sync_on_timeout);
+GDBRemoteCommunication::ReadPacket(StringExtractorGDBRemote &response,
+                                   uint32_t timeout_usec,
+                                   bool sync_on_timeout) {
+  if (m_read_thread_enabled)
+    return PopPacketFromQueue(response, timeout_usec);
+  else
+    return WaitForPacketWithTimeoutMicroSecondsNoLock(response, timeout_usec,
+                                                      sync_on_timeout);
 }
 
-
 // This function is called when a packet is requested.
 // A whole packet is popped from the packet queue and returned to the caller.
 // Packets are placed into this queue from the communication read thread.
 // See GDBRemoteCommunication::AppendBytesToCache.
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec)
-{
-    auto until = std::chrono::system_clock::now() + std::chrono::microseconds(timeout_usec);
+GDBRemoteCommunication::PopPacketFromQueue(StringExtractorGDBRemote &response,
+                                           uint32_t timeout_usec) {
+  auto until = std::chrono::system_clock::now() +
+               std::chrono::microseconds(timeout_usec);
 
-    while (true)
+  while (true) {
+    // scope for the mutex
     {
-        // scope for the mutex
-        {
-            // lock down the packet queue
-            std::unique_lock<std::mutex> lock(m_packet_queue_mutex);
+      // lock down the packet queue
+      std::unique_lock<std::mutex> lock(m_packet_queue_mutex);
 
-            // Wait on condition variable.
-            if (m_packet_queue.size() == 0)
-            {
-                std::cv_status result = m_condition_queue_not_empty.wait_until(lock, until);
-                if (result == std::cv_status::timeout)
-                  break;
-            }
+      // Wait on condition variable.
+      if (m_packet_queue.size() == 0) {
+        std::cv_status result =
+            m_condition_queue_not_empty.wait_until(lock, until);
+        if (result == std::cv_status::timeout)
+          break;
+      }
 
-            if (m_packet_queue.size() > 0)
-            {
-                // get the front element of the queue
-                response = m_packet_queue.front();
+      if (m_packet_queue.size() > 0) {
+        // get the front element of the queue
+        response = m_packet_queue.front();
 
-                // remove the front element
-                m_packet_queue.pop();
+        // remove the front element
+        m_packet_queue.pop();
 
-                // we got a packet
-                return PacketResult::Success;
-            }
-         }
-
-         // Disconnected
-         if (!IsConnected())
-             return PacketResult::ErrorDisconnected;
-
-      // Loop while not timed out
+        // we got a packet
+        return PacketResult::Success;
+      }
     }
 
-    return PacketResult::ErrorReplyTimeout;
-}
+    // Disconnected
+    if (!IsConnected())
+      return PacketResult::ErrorDisconnected;
 
+    // Loop while not timed out
+  }
+
+  return PacketResult::ErrorReplyTimeout;
+}
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec, bool sync_on_timeout)
-{
-    uint8_t buffer[8192];
-    Error error;
+GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock(
+    StringExtractorGDBRemote &packet, uint32_t timeout_usec,
+    bool sync_on_timeout) {
+  uint8_t buffer[8192];
+  Error error;
 
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS |
+                                                         GDBR_LOG_VERBOSE));
 
-    // Check for a packet from our cache first without trying any reading...
-    if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
+  // Check for a packet from our cache first without trying any reading...
+  if (CheckForPacket(NULL, 0, packet) != PacketType::Invalid)
+    return PacketResult::Success;
+
+  bool timed_out = false;
+  bool disconnected = false;
+  while (IsConnected() && !timed_out) {
+    lldb::ConnectionStatus status = eConnectionStatusNoConnection;
+    size_t bytes_read =
+        Read(buffer, sizeof(buffer), timeout_usec, status, &error);
+
+    if (log)
+      log->Printf("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, "
+                  "status = %s, error = %s) => bytes_read = %" PRIu64,
+                  LLVM_PRETTY_FUNCTION, timeout_usec,
+                  Communication::ConnectionStatusAsCString(status),
+                  error.AsCString(), (uint64_t)bytes_read);
+
+    if (bytes_read > 0) {
+      if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
         return PacketResult::Success;
+    } else {
+      switch (status) {
+      case eConnectionStatusTimedOut:
+      case eConnectionStatusInterrupted:
+        if (sync_on_timeout) {
+          //------------------------------------------------------------------
+          /// Sync the remote GDB server and make sure we get a response that
+          /// corresponds to what we send.
+          ///
+          /// Sends a "qEcho" packet and makes sure it gets the exact packet
+          /// echoed back. If the qEcho packet isn't supported, we send a qC
+          /// packet and make sure we get a valid thread ID back. We use the
+          /// "qC" packet since its response if very unique: is responds with
+          /// "QC%x" where %x is the thread ID of the current thread. This
+          /// makes the response unique enough from other packet responses to
+          /// ensure we are back on track.
+          ///
+          /// This packet is needed after we time out sending a packet so we
+          /// can ensure that we are getting the response for the packet we
+          /// are sending. There are no sequence IDs in the GDB remote
+          /// protocol (there used to be, but they are not supported anymore)
+          /// so if you timeout sending packet "abc", you might then send
+          /// packet "cde" and get the response for the previous "abc" packet.
+          /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
+          /// many responses for packets can look like responses for other
+          /// packets. So if we timeout, we need to ensure that we can get
+          /// back on track. If we can't get back on track, we must
+          /// disconnect.
+          //------------------------------------------------------------------
+          bool sync_success = false;
+          bool got_actual_response = false;
+          // We timed out, we need to sync back up with the
+          char echo_packet[32];
+          int echo_packet_len = 0;
+          RegularExpression response_regex;
 
-    bool timed_out = false;
-    bool disconnected = false;
-    while (IsConnected() && !timed_out)
-    {
-        lldb::ConnectionStatus status = eConnectionStatusNoConnection;
-        size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
-        
-        if (log)
-            log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
-                         LLVM_PRETTY_FUNCTION,
-                         timeout_usec, 
-                         Communication::ConnectionStatusAsCString (status),
-                         error.AsCString(), 
-                         (uint64_t)bytes_read);
+          if (m_supports_qEcho == eLazyBoolYes) {
+            echo_packet_len = ::snprintf(echo_packet, sizeof(echo_packet),
+                                         "qEcho:%u", ++m_echo_number);
+            std::string regex_str = "^";
+            regex_str += echo_packet;
+            regex_str += "$";
+            response_regex.Compile(regex_str.c_str());
+          } else {
+            echo_packet_len =
+                ::snprintf(echo_packet, sizeof(echo_packet), "qC");
+            response_regex.Compile("^QC[0-9A-Fa-f]+$");
+          }
 
-        if (bytes_read > 0)
-        {
-            if (CheckForPacket(buffer, bytes_read, packet) != PacketType::Invalid)
-                return PacketResult::Success;
-        }
-        else
-        {
-            switch (status)
-            {
-            case eConnectionStatusTimedOut:
-            case eConnectionStatusInterrupted:
-                if (sync_on_timeout)
-                {
-                    //------------------------------------------------------------------
-                    /// Sync the remote GDB server and make sure we get a response that
-                    /// corresponds to what we send.
-                    ///
-                    /// Sends a "qEcho" packet and makes sure it gets the exact packet
-                    /// echoed back. If the qEcho packet isn't supported, we send a qC
-                    /// packet and make sure we get a valid thread ID back. We use the
-                    /// "qC" packet since its response if very unique: is responds with
-                    /// "QC%x" where %x is the thread ID of the current thread. This
-                    /// makes the response unique enough from other packet responses to
-                    /// ensure we are back on track.
-                    ///
-                    /// This packet is needed after we time out sending a packet so we
-                    /// can ensure that we are getting the response for the packet we
-                    /// are sending. There are no sequence IDs in the GDB remote
-                    /// protocol (there used to be, but they are not supported anymore)
-                    /// so if you timeout sending packet "abc", you might then send
-                    /// packet "cde" and get the response for the previous "abc" packet.
-                    /// Many responses are "OK" or "" (unsupported) or "EXX" (error) so
-                    /// many responses for packets can look like responses for other
-                    /// packets. So if we timeout, we need to ensure that we can get
-                    /// back on track. If we can't get back on track, we must
-                    /// disconnect.
-                    //------------------------------------------------------------------
-                    bool sync_success = false;
-                    bool got_actual_response = false;
-                    // We timed out, we need to sync back up with the
-                    char echo_packet[32];
-                    int echo_packet_len = 0;
-                    RegularExpression response_regex;
-
-                    if (m_supports_qEcho == eLazyBoolYes)
-                    {
-                        echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qEcho:%u", ++m_echo_number);
-                        std::string regex_str = "^";
-                        regex_str += echo_packet;
-                        regex_str += "$";
-                        response_regex.Compile(regex_str.c_str());
-                    }
-                    else
-                    {
-                        echo_packet_len = ::snprintf (echo_packet, sizeof(echo_packet), "qC");
-                        response_regex.Compile("^QC[0-9A-Fa-f]+$");
-                    }
-
-                    PacketResult echo_packet_result = SendPacketNoLock (llvm::StringRef(echo_packet, echo_packet_len));
-                    if (echo_packet_result == PacketResult::Success)
-                    {
-                        const uint32_t max_retries = 3;
-                        uint32_t successful_responses = 0;
-                        for (uint32_t i=0; i<max_retries; ++i)
-                        {
-                            StringExtractorGDBRemote echo_response;
-                            echo_packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (echo_response, timeout_usec, false);
-                            if (echo_packet_result == PacketResult::Success)
-                            {
-                                ++successful_responses;
-                                if (response_regex.Execute(echo_response.GetStringRef().c_str()))
-                                {
-                                    sync_success = true;
-                                    break;
-                                }
-                                else if (successful_responses == 1)
-                                {
-                                    // We got something else back as the first successful response, it probably is
-                                    // the  response to the packet we actually wanted, so copy it over if this
-                                    // is the first success and continue to try to get the qEcho response
-                                    packet = echo_response;
-                                    got_actual_response = true;
-                                }
-                            }
-                            else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
-                                continue;   // Packet timed out, continue waiting for a response
-                            else
-                                break;      // Something else went wrong getting the packet back, we failed and are done trying
-                        }
-                    }
-
-                    // We weren't able to sync back up with the server, we must abort otherwise
-                    // all responses might not be from the right packets...
-                    if (sync_success)
-                    {
-                        // We timed out, but were able to recover
-                        if (got_actual_response)
-                        {
-                            // We initially timed out, but we did get a response that came in before the successful
-                            // reply to our qEcho packet, so lets say everything is fine...
-                            return PacketResult::Success;
-                        }
-                    }
-                    else
-                    {
-                        disconnected = true;
-                        Disconnect();
-                    }
+          PacketResult echo_packet_result =
+              SendPacketNoLock(llvm::StringRef(echo_packet, echo_packet_len));
+          if (echo_packet_result == PacketResult::Success) {
+            const uint32_t max_retries = 3;
+            uint32_t successful_responses = 0;
+            for (uint32_t i = 0; i < max_retries; ++i) {
+              StringExtractorGDBRemote echo_response;
+              echo_packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock(
+                  echo_response, timeout_usec, false);
+              if (echo_packet_result == PacketResult::Success) {
+                ++successful_responses;
+                if (response_regex.Execute(
+                        echo_response.GetStringRef().c_str())) {
+                  sync_success = true;
+                  break;
+                } else if (successful_responses == 1) {
+                  // We got something else back as the first successful
+                  // response, it probably is
+                  // the  response to the packet we actually wanted, so copy it
+                  // over if this
+                  // is the first success and continue to try to get the qEcho
+                  // response
+                  packet = echo_response;
+                  got_actual_response = true;
                 }
-                timed_out = true;
-                break;
-            case eConnectionStatusSuccess:
-                //printf ("status = success but error = %s\n", error.AsCString("<invalid>"));
-                break;
-                
-            case eConnectionStatusEndOfFile:
-            case eConnectionStatusNoConnection:
-            case eConnectionStatusLostConnection:
-            case eConnectionStatusError:
-                disconnected = true;
-                Disconnect();
-                break;
+              } else if (echo_packet_result == PacketResult::ErrorReplyTimeout)
+                continue; // Packet timed out, continue waiting for a response
+              else
+                break; // Something else went wrong getting the packet back, we
+                       // failed and are done trying
             }
+          }
+
+          // We weren't able to sync back up with the server, we must abort
+          // otherwise
+          // all responses might not be from the right packets...
+          if (sync_success) {
+            // We timed out, but were able to recover
+            if (got_actual_response) {
+              // We initially timed out, but we did get a response that came in
+              // before the successful
+              // reply to our qEcho packet, so lets say everything is fine...
+              return PacketResult::Success;
+            }
+          } else {
+            disconnected = true;
+            Disconnect();
+          }
         }
+        timed_out = true;
+        break;
+      case eConnectionStatusSuccess:
+        // printf ("status = success but error = %s\n",
+        // error.AsCString("<invalid>"));
+        break;
+
+      case eConnectionStatusEndOfFile:
+      case eConnectionStatusNoConnection:
+      case eConnectionStatusLostConnection:
+      case eConnectionStatusError:
+        disconnected = true;
+        Disconnect();
+        break;
+      }
     }
-    packet.Clear ();
-    if (disconnected)
-        return PacketResult::ErrorDisconnected;
-    if (timed_out)
-        return PacketResult::ErrorReplyTimeout;
-    else
-        return PacketResult::ErrorReplyFailed;
+  }
+  packet.Clear();
+  if (disconnected)
+    return PacketResult::ErrorDisconnected;
+  if (timed_out)
+    return PacketResult::ErrorReplyTimeout;
+  else
+    return PacketResult::ErrorReplyFailed;
 }
 
-bool
-GDBRemoteCommunication::DecompressPacket ()
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+bool GDBRemoteCommunication::DecompressPacket() {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
 
-    if (!CompressionIsEnabled())
-        return true;
-
-    size_t pkt_size = m_bytes.size();
-
-    // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating
-    // an unsupported packet.  Anything less than 5 characters, it's definitely not a compressed packet.
-    if (pkt_size < 5)
-        return true;
-
-    if (m_bytes[0] != '$' && m_bytes[0] != '%')
-        return true;
-    if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
-        return true;
-
-    size_t hash_mark_idx = m_bytes.find ('#');
-    if (hash_mark_idx == std::string::npos)
-        return true;
-    if (hash_mark_idx + 2 >= m_bytes.size())
-        return true;
-
-    if (!::isxdigit (m_bytes[hash_mark_idx + 1]) || !::isxdigit (m_bytes[hash_mark_idx + 2]))
-        return true;
-
-    size_t content_length = pkt_size - 5;    // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
-    size_t content_start = 2;                // The first character of the compressed/not-compressed text of the packet
-    size_t checksum_idx = hash_mark_idx + 1; // The first character of the two hex checksum characters
-
-    // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain multiple packets.
-    // size_of_first_packet is the size of the initial packet which we'll replace with the decompressed
-    // version of, leaving the rest of m_bytes unmodified.
-    size_t size_of_first_packet = hash_mark_idx + 3; 
-
-    // Compressed packets ("$C") start with a base10 number which is the size of the uncompressed payload,
-    // then a : and then the compressed data.  e.g. $C1024:<binary>#00
-    // Update content_start and content_length to only include the <binary> part of the packet.
-
-    uint64_t decompressed_bufsize = ULONG_MAX;
-    if (m_bytes[1] == 'C')
-    {
-        size_t i = content_start;
-        while (i < hash_mark_idx && isdigit(m_bytes[i]))
-            i++;
-        if (i < hash_mark_idx && m_bytes[i] == ':')
-        {
-            i++;
-            content_start = i;
-            content_length = hash_mark_idx - content_start;
-            std::string bufsize_str (m_bytes.data() + 2, i - 2 - 1);
-            errno = 0;
-            decompressed_bufsize = ::strtoul (bufsize_str.c_str(), NULL, 10);
-            if (errno != 0 || decompressed_bufsize == ULONG_MAX)
-            {
-                m_bytes.erase (0, size_of_first_packet);
-                return false;
-            }
-        }
-    }
-
-    if (GetSendAcks ())
-    {
-        char packet_checksum_cstr[3];
-        packet_checksum_cstr[0] = m_bytes[checksum_idx];
-        packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
-        packet_checksum_cstr[2] = '\0';
-        long packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
-
-        long actual_checksum = CalculcateChecksum (llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
-        bool success = packet_checksum == actual_checksum;
-        if (!success)
-        {
-            if (log)
-                log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", 
-                             (int)(pkt_size), 
-                             m_bytes.c_str(),
-                             (uint8_t)packet_checksum,
-                             (uint8_t)actual_checksum);
-        }
-        // Send the ack or nack if needed
-        if (!success)
-        {
-            SendNack();
-            m_bytes.erase (0, size_of_first_packet);
-            return false;
-        }
-        else
-        {
-            SendAck();
-        }
-    }
-
-    if (m_bytes[1] == 'N')
-    {
-        // This packet was not compressed -- delete the 'N' character at the 
-        // start and the packet may be processed as-is.
-        m_bytes.erase(1, 1);
-        return true;
-    }
-
-    // Reverse the gdb-remote binary escaping that was done to the compressed text to
-    // guard characters like '$', '#', '}', etc.
-    std::vector<uint8_t> unescaped_content;
-    unescaped_content.reserve (content_length);
-    size_t i = content_start;
-    while (i < hash_mark_idx)
-    {
-        if (m_bytes[i] == '}')
-        {
-            i++;
-            unescaped_content.push_back (m_bytes[i] ^ 0x20);
-        }
-        else
-        {
-            unescaped_content.push_back (m_bytes[i]);
-        }
-        i++;
-    }
-
-    uint8_t *decompressed_buffer = nullptr;
-    size_t decompressed_bytes = 0;
-
-    if (decompressed_bufsize != ULONG_MAX)
-    {
-        decompressed_buffer = (uint8_t *) malloc (decompressed_bufsize + 1);
-        if (decompressed_buffer == nullptr)
-        {
-            m_bytes.erase (0, size_of_first_packet);
-            return false;
-        }
-
-    }
-
-#if defined (HAVE_LIBCOMPRESSION)
-    // libcompression is weak linked so check that compression_decode_buffer() is available
-    if (compression_decode_buffer != NULL &&
-        (m_compression_type == CompressionType::ZlibDeflate 
-         || m_compression_type == CompressionType::LZFSE
-         || m_compression_type == CompressionType::LZ4))
-    {
-        compression_algorithm compression_type;
-        if (m_compression_type == CompressionType::ZlibDeflate)
-            compression_type = COMPRESSION_ZLIB;
-        else if (m_compression_type == CompressionType::LZFSE)
-            compression_type = COMPRESSION_LZFSE;
-        else if (m_compression_type == CompressionType::LZ4)
-            compression_type = COMPRESSION_LZ4_RAW;
-        else if (m_compression_type == CompressionType::LZMA)
-            compression_type = COMPRESSION_LZMA;
-
-
-        // If we have the expected size of the decompressed payload, we can allocate
-        // the right-sized buffer and do it.  If we don't have that information, we'll
-        // need to try decoding into a big buffer and if the buffer wasn't big enough,
-        // increase it and try again.
-
-        if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr)
-        {
-            decompressed_bytes = compression_decode_buffer (decompressed_buffer, decompressed_bufsize + 10 ,
-                                                        (uint8_t*) unescaped_content.data(),
-                                                        unescaped_content.size(),
-                                                        NULL,
-                                                        compression_type);
-        }
-    }
-#endif
-
-#if defined (HAVE_LIBZ)
-    if (decompressed_bytes == 0 
-        && decompressed_bufsize != ULONG_MAX
-        && decompressed_buffer != nullptr 
-        && m_compression_type == CompressionType::ZlibDeflate)
-    {
-        z_stream stream;
-        memset (&stream, 0, sizeof (z_stream));
-        stream.next_in = (Bytef *) unescaped_content.data();
-        stream.avail_in = (uInt) unescaped_content.size();
-        stream.total_in = 0;
-        stream.next_out = (Bytef *) decompressed_buffer;
-        stream.avail_out = decompressed_bufsize;
-        stream.total_out = 0;
-        stream.zalloc = Z_NULL;
-        stream.zfree = Z_NULL;
-        stream.opaque = Z_NULL;
-
-        if (inflateInit2 (&stream, -15) == Z_OK)
-        {
-            int status = inflate (&stream, Z_NO_FLUSH);
-            inflateEnd (&stream);
-            if (status == Z_STREAM_END)
-            {
-                decompressed_bytes = stream.total_out;
-            }
-        }
-    }
-#endif
-
-    if (decompressed_bytes == 0 || decompressed_buffer == nullptr)
-    {
-        if (decompressed_buffer)
-            free (decompressed_buffer);
-        m_bytes.erase (0, size_of_first_packet);
-        return false;
-    }
-
-    std::string new_packet;
-    new_packet.reserve (decompressed_bytes + 6);
-    new_packet.push_back (m_bytes[0]);
-    new_packet.append ((const char *) decompressed_buffer, decompressed_bytes);
-    new_packet.push_back ('#');
-    if (GetSendAcks ())
-    {
-        uint8_t decompressed_checksum = CalculcateChecksum (llvm::StringRef((const char *) decompressed_buffer, decompressed_bytes));
-        char decompressed_checksum_str[3];
-        snprintf (decompressed_checksum_str, 3, "%02x", decompressed_checksum);
-        new_packet.append (decompressed_checksum_str);
-    }
-    else
-    {
-        new_packet.push_back ('0');
-        new_packet.push_back ('0');
-    }
-
-    m_bytes.replace (0, size_of_first_packet, new_packet.data(), new_packet.size());
-
-    free (decompressed_buffer);
+  if (!CompressionIsEnabled())
     return true;
+
+  size_t pkt_size = m_bytes.size();
+
+  // Smallest possible compressed packet is $N#00 - an uncompressed empty reply,
+  // most commonly indicating
+  // an unsupported packet.  Anything less than 5 characters, it's definitely
+  // not a compressed packet.
+  if (pkt_size < 5)
+    return true;
+
+  if (m_bytes[0] != '$' && m_bytes[0] != '%')
+    return true;
+  if (m_bytes[1] != 'C' && m_bytes[1] != 'N')
+    return true;
+
+  size_t hash_mark_idx = m_bytes.find('#');
+  if (hash_mark_idx == std::string::npos)
+    return true;
+  if (hash_mark_idx + 2 >= m_bytes.size())
+    return true;
+
+  if (!::isxdigit(m_bytes[hash_mark_idx + 1]) ||
+      !::isxdigit(m_bytes[hash_mark_idx + 2]))
+    return true;
+
+  size_t content_length =
+      pkt_size -
+      5; // not counting '$', 'C' | 'N', '#', & the two hex checksum chars
+  size_t content_start = 2; // The first character of the
+                            // compressed/not-compressed text of the packet
+  size_t checksum_idx =
+      hash_mark_idx +
+      1; // The first character of the two hex checksum characters
+
+  // Normally size_of_first_packet == m_bytes.size() but m_bytes may contain
+  // multiple packets.
+  // size_of_first_packet is the size of the initial packet which we'll replace
+  // with the decompressed
+  // version of, leaving the rest of m_bytes unmodified.
+  size_t size_of_first_packet = hash_mark_idx + 3;
+
+  // Compressed packets ("$C") start with a base10 number which is the size of
+  // the uncompressed payload,
+  // then a : and then the compressed data.  e.g. $C1024:<binary>#00
+  // Update content_start and content_length to only include the <binary> part
+  // of the packet.
+
+  uint64_t decompressed_bufsize = ULONG_MAX;
+  if (m_bytes[1] == 'C') {
+    size_t i = content_start;
+    while (i < hash_mark_idx && isdigit(m_bytes[i]))
+      i++;
+    if (i < hash_mark_idx && m_bytes[i] == ':') {
+      i++;
+      content_start = i;
+      content_length = hash_mark_idx - content_start;
+      std::string bufsize_str(m_bytes.data() + 2, i - 2 - 1);
+      errno = 0;
+      decompressed_bufsize = ::strtoul(bufsize_str.c_str(), NULL, 10);
+      if (errno != 0 || decompressed_bufsize == ULONG_MAX) {
+        m_bytes.erase(0, size_of_first_packet);
+        return false;
+      }
+    }
+  }
+
+  if (GetSendAcks()) {
+    char packet_checksum_cstr[3];
+    packet_checksum_cstr[0] = m_bytes[checksum_idx];
+    packet_checksum_cstr[1] = m_bytes[checksum_idx + 1];
+    packet_checksum_cstr[2] = '\0';
+    long packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+
+    long actual_checksum = CalculcateChecksum(
+        llvm::StringRef(m_bytes).substr(1, hash_mark_idx - 1));
+    bool success = packet_checksum == actual_checksum;
+    if (!success) {
+      if (log)
+        log->Printf(
+            "error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x",
+            (int)(pkt_size), m_bytes.c_str(), (uint8_t)packet_checksum,
+            (uint8_t)actual_checksum);
+    }
+    // Send the ack or nack if needed
+    if (!success) {
+      SendNack();
+      m_bytes.erase(0, size_of_first_packet);
+      return false;
+    } else {
+      SendAck();
+    }
+  }
+
+  if (m_bytes[1] == 'N') {
+    // This packet was not compressed -- delete the 'N' character at the
+    // start and the packet may be processed as-is.
+    m_bytes.erase(1, 1);
+    return true;
+  }
+
+  // Reverse the gdb-remote binary escaping that was done to the compressed text
+  // to
+  // guard characters like '$', '#', '}', etc.
+  std::vector<uint8_t> unescaped_content;
+  unescaped_content.reserve(content_length);
+  size_t i = content_start;
+  while (i < hash_mark_idx) {
+    if (m_bytes[i] == '}') {
+      i++;
+      unescaped_content.push_back(m_bytes[i] ^ 0x20);
+    } else {
+      unescaped_content.push_back(m_bytes[i]);
+    }
+    i++;
+  }
+
+  uint8_t *decompressed_buffer = nullptr;
+  size_t decompressed_bytes = 0;
+
+  if (decompressed_bufsize != ULONG_MAX) {
+    decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1);
+    if (decompressed_buffer == nullptr) {
+      m_bytes.erase(0, size_of_first_packet);
+      return false;
+    }
+  }
+
+#if defined(HAVE_LIBCOMPRESSION)
+  // libcompression is weak linked so check that compression_decode_buffer() is
+  // available
+  if (compression_decode_buffer != NULL &&
+      (m_compression_type == CompressionType::ZlibDeflate ||
+       m_compression_type == CompressionType::LZFSE ||
+       m_compression_type == CompressionType::LZ4)) {
+    compression_algorithm compression_type;
+    if (m_compression_type == CompressionType::ZlibDeflate)
+      compression_type = COMPRESSION_ZLIB;
+    else if (m_compression_type == CompressionType::LZFSE)
+      compression_type = COMPRESSION_LZFSE;
+    else if (m_compression_type == CompressionType::LZ4)
+      compression_type = COMPRESSION_LZ4_RAW;
+    else if (m_compression_type == CompressionType::LZMA)
+      compression_type = COMPRESSION_LZMA;
+
+    // If we have the expected size of the decompressed payload, we can allocate
+    // the right-sized buffer and do it.  If we don't have that information,
+    // we'll
+    // need to try decoding into a big buffer and if the buffer wasn't big
+    // enough,
+    // increase it and try again.
+
+    if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) {
+      decompressed_bytes = compression_decode_buffer(
+          decompressed_buffer, decompressed_bufsize + 10,
+          (uint8_t *)unescaped_content.data(), unescaped_content.size(), NULL,
+          compression_type);
+    }
+  }
+#endif
+
+#if defined(HAVE_LIBZ)
+  if (decompressed_bytes == 0 && decompressed_bufsize != ULONG_MAX &&
+      decompressed_buffer != nullptr &&
+      m_compression_type == CompressionType::ZlibDeflate) {
+    z_stream stream;
+    memset(&stream, 0, sizeof(z_stream));
+    stream.next_in = (Bytef *)unescaped_content.data();
+    stream.avail_in = (uInt)unescaped_content.size();
+    stream.total_in = 0;
+    stream.next_out = (Bytef *)decompressed_buffer;
+    stream.avail_out = decompressed_bufsize;
+    stream.total_out = 0;
+    stream.zalloc = Z_NULL;
+    stream.zfree = Z_NULL;
+    stream.opaque = Z_NULL;
+
+    if (inflateInit2(&stream, -15) == Z_OK) {
+      int status = inflate(&stream, Z_NO_FLUSH);
+      inflateEnd(&stream);
+      if (status == Z_STREAM_END) {
+        decompressed_bytes = stream.total_out;
+      }
+    }
+  }
+#endif
+
+  if (decompressed_bytes == 0 || decompressed_buffer == nullptr) {
+    if (decompressed_buffer)
+      free(decompressed_buffer);
+    m_bytes.erase(0, size_of_first_packet);
+    return false;
+  }
+
+  std::string new_packet;
+  new_packet.reserve(decompressed_bytes + 6);
+  new_packet.push_back(m_bytes[0]);
+  new_packet.append((const char *)decompressed_buffer, decompressed_bytes);
+  new_packet.push_back('#');
+  if (GetSendAcks()) {
+    uint8_t decompressed_checksum = CalculcateChecksum(
+        llvm::StringRef((const char *)decompressed_buffer, decompressed_bytes));
+    char decompressed_checksum_str[3];
+    snprintf(decompressed_checksum_str, 3, "%02x", decompressed_checksum);
+    new_packet.append(decompressed_checksum_str);
+  } else {
+    new_packet.push_back('0');
+    new_packet.push_back('0');
+  }
+
+  m_bytes.replace(0, size_of_first_packet, new_packet.data(),
+                  new_packet.size());
+
+  free(decompressed_buffer);
+  return true;
 }
 
 GDBRemoteCommunication::PacketType
-GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet)
-{
-    // Put the packet data into the buffer in a thread safe fashion
-    std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len,
+                                       StringExtractorGDBRemote &packet) {
+  // Put the packet data into the buffer in a thread safe fashion
+  std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
 
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
 
-    if (src && src_len > 0)
-    {
-        if (log && log->GetVerbose())
-        {
-            StreamString s;
-            log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s",
-                         __FUNCTION__, 
-                         (uint32_t)src_len, 
-                         (uint32_t)src_len, 
-                         src);
-        }
-        m_bytes.append ((const char *)src, src_len);
+  if (src && src_len > 0) {
+    if (log && log->GetVerbose()) {
+      StreamString s;
+      log->Printf("GDBRemoteCommunication::%s adding %u bytes: %.*s",
+                  __FUNCTION__, (uint32_t)src_len, (uint32_t)src_len, src);
+    }
+    m_bytes.append((const char *)src, src_len);
+  }
+
+  bool isNotifyPacket = false;
+
+  // Parse up the packets into gdb remote packets
+  if (!m_bytes.empty()) {
+    // end_idx must be one past the last valid packet byte. Start
+    // it off with an invalid value that is the same as the current
+    // index.
+    size_t content_start = 0;
+    size_t content_length = 0;
+    size_t total_length = 0;
+    size_t checksum_idx = std::string::npos;
+
+    // Size of packet before it is decompressed, for logging purposes
+    size_t original_packet_size = m_bytes.size();
+    if (CompressionIsEnabled()) {
+      if (DecompressPacket() == false) {
+        packet.Clear();
+        return GDBRemoteCommunication::PacketType::Standard;
+      }
     }
 
-    bool isNotifyPacket = false;
+    switch (m_bytes[0]) {
+    case '+':                            // Look for ack
+    case '-':                            // Look for cancel
+    case '\x03':                         // ^C to halt target
+      content_length = total_length = 1; // The command is one byte long...
+      break;
 
-    // Parse up the packets into gdb remote packets
-    if (!m_bytes.empty())
-    {
-        // end_idx must be one past the last valid packet byte. Start
-        // it off with an invalid value that is the same as the current
-        // index.
-        size_t content_start = 0;
-        size_t content_length = 0;
-        size_t total_length = 0;
-        size_t checksum_idx = std::string::npos;
+    case '%': // Async notify packet
+      isNotifyPacket = true;
+      LLVM_FALLTHROUGH;
 
-        // Size of packet before it is decompressed, for logging purposes
-        size_t original_packet_size = m_bytes.size();
-        if (CompressionIsEnabled())
-        {
-            if (DecompressPacket() == false)
-            {
-                packet.Clear();
-                return GDBRemoteCommunication::PacketType::Standard;
-            }
+    case '$':
+      // Look for a standard gdb packet?
+      {
+        size_t hash_pos = m_bytes.find('#');
+        if (hash_pos != std::string::npos) {
+          if (hash_pos + 2 < m_bytes.size()) {
+            checksum_idx = hash_pos + 1;
+            // Skip the dollar sign
+            content_start = 1;
+            // Don't include the # in the content or the $ in the content length
+            content_length = hash_pos - 1;
+
+            total_length =
+                hash_pos + 3; // Skip the # and the two hex checksum bytes
+          } else {
+            // Checksum bytes aren't all here yet
+            content_length = std::string::npos;
+          }
         }
+      }
+      break;
 
-        switch (m_bytes[0])
-        {
-            case '+':       // Look for ack
-            case '-':       // Look for cancel
-            case '\x03':    // ^C to halt target
-                content_length = total_length = 1;  // The command is one byte long...
-                break;
+    default: {
+      // We have an unexpected byte and we need to flush all bad
+      // data that is in m_bytes, so we need to find the first
+      // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
+      // or '$' character (start of packet header) or of course,
+      // the end of the data in m_bytes...
+      const size_t bytes_len = m_bytes.size();
+      bool done = false;
+      uint32_t idx;
+      for (idx = 1; !done && idx < bytes_len; ++idx) {
+        switch (m_bytes[idx]) {
+        case '+':
+        case '-':
+        case '\x03':
+        case '%':
+        case '$':
+          done = true;
+          break;
 
-            case '%': // Async notify packet
-                isNotifyPacket = true;
-                LLVM_FALLTHROUGH;
-
-            case '$':
-                // Look for a standard gdb packet?
-                {
-                    size_t hash_pos = m_bytes.find('#');
-                    if (hash_pos != std::string::npos)
-                    {
-                        if (hash_pos + 2 < m_bytes.size())
-                        {
-                            checksum_idx = hash_pos + 1;
-                            // Skip the dollar sign
-                            content_start = 1; 
-                            // Don't include the # in the content or the $ in the content length
-                            content_length = hash_pos - 1;  
-                            
-                            total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes
-                        }
-                        else
-                        {
-                            // Checksum bytes aren't all here yet
-                            content_length = std::string::npos;
-                        }
-                    }
-                }
-                break;
-
-            default:
-                {
-                    // We have an unexpected byte and we need to flush all bad 
-                    // data that is in m_bytes, so we need to find the first
-                    // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt),
-                    // or '$' character (start of packet header) or of course,
-                    // the end of the data in m_bytes...
-                    const size_t bytes_len = m_bytes.size();
-                    bool done = false;
-                    uint32_t idx;
-                    for (idx = 1; !done && idx < bytes_len; ++idx)
-                    {
-                        switch (m_bytes[idx])
-                        {
-                        case '+':
-                        case '-':
-                        case '\x03':
-                        case '%':
-                        case '$':
-                            done = true;
-                            break;
-                                
-                        default:
-                            break;
-                        }
-                    }
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
-                                     __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
-                    m_bytes.erase(0, idx - 1);
-                }
-                break;
+        default:
+          break;
         }
+      }
+      if (log)
+        log->Printf("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'",
+                    __FUNCTION__, idx - 1, idx - 1, m_bytes.c_str());
+      m_bytes.erase(0, idx - 1);
+    } break;
+    }
 
-        if (content_length == std::string::npos)
-        {
-            packet.Clear();
-            return GDBRemoteCommunication::PacketType::Invalid;
+    if (content_length == std::string::npos) {
+      packet.Clear();
+      return GDBRemoteCommunication::PacketType::Invalid;
+    } else if (total_length > 0) {
+
+      // We have a valid packet...
+      assert(content_length <= m_bytes.size());
+      assert(total_length <= m_bytes.size());
+      assert(content_length <= total_length);
+      size_t content_end = content_start + content_length;
+
+      bool success = true;
+      std::string &packet_str = packet.GetStringRef();
+      if (log) {
+        // If logging was just enabled and we have history, then dump out what
+        // we have to the log so we get the historical context. The Dump() call
+        // that
+        // logs all of the packet will set a boolean so that we don't dump this
+        // more
+        // than once
+        if (!m_history.DidDumpToLog())
+          m_history.Dump(log);
+
+        bool binary = false;
+        // Only detect binary for packets that start with a '$' and have a '#CC'
+        // checksum
+        if (m_bytes[0] == '$' && total_length > 4) {
+          for (size_t i = 0; !binary && i < total_length; ++i) {
+            if (isprint(m_bytes[i]) == 0 && isspace(m_bytes[i]) == 0) {
+              binary = true;
+            }
+          }
         }
-        else if (total_length > 0)
-        {
-
-            // We have a valid packet...
-            assert (content_length <= m_bytes.size());
-            assert (total_length <= m_bytes.size());
-            assert (content_length <= total_length);
-            size_t content_end = content_start + content_length;
-
-            bool success = true;
-            std::string &packet_str = packet.GetStringRef();
-            if (log)
-            {
-                // If logging was just enabled and we have history, then dump out what
-                // we have to the log so we get the historical context. The Dump() call that
-                // logs all of the packet will set a boolean so that we don't dump this more
-                // than once
-                if (!m_history.DidDumpToLog ())
-                    m_history.Dump (log);
-                
-                bool binary = false;
-                // Only detect binary for packets that start with a '$' and have a '#CC' checksum
-                if (m_bytes[0] == '$' && total_length > 4)
-                {
-                    for (size_t i=0; !binary && i<total_length; ++i)
-                    {
-                        if (isprint (m_bytes[i]) == 0 && isspace (m_bytes[i]) == 0)
-                        {
-                            binary = true;
-                        }
-                    }
-                }
-                if (binary)
-                {
-                    StreamString strm;
-                    // Packet header...
-                    if (CompressionIsEnabled())
-                        strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c", (uint64_t) original_packet_size, (uint64_t)total_length, m_bytes[0]);
-                    else
-                        strm.Printf("<%4" PRIu64 "> read packet: %c", (uint64_t)total_length, m_bytes[0]);
-                    for (size_t i=content_start; i<content_end; ++i)
-                    {
-                        // Remove binary escaped bytes when displaying the packet...
-                        const char ch = m_bytes[i];
-                        if (ch == 0x7d)
-                        {
-                            // 0x7d is the escape character.  The next character is to
-                            // be XOR'd with 0x20.
-                            const char escapee = m_bytes[++i] ^ 0x20;
-                            strm.Printf("%2.2x", escapee);
-                        }
-                        else
-                        {
-                            strm.Printf("%2.2x", (uint8_t)ch);
-                        }
-                    }
-                    // Packet footer...
-                    strm.Printf("%c%c%c", m_bytes[total_length-3], m_bytes[total_length-2], m_bytes[total_length-1]);
-                    log->PutCString(strm.GetString().c_str());
-                }
-                else
-                {
-                    if (CompressionIsEnabled())
-                        log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s", (uint64_t) original_packet_size, (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
-                    else
-                        log->Printf("<%4" PRIu64 "> read packet: %.*s", (uint64_t)total_length, (int)(total_length), m_bytes.c_str());
-                }
+        if (binary) {
+          StreamString strm;
+          // Packet header...
+          if (CompressionIsEnabled())
+            strm.Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %c",
+                        (uint64_t)original_packet_size, (uint64_t)total_length,
+                        m_bytes[0]);
+          else
+            strm.Printf("<%4" PRIu64 "> read packet: %c",
+                        (uint64_t)total_length, m_bytes[0]);
+          for (size_t i = content_start; i < content_end; ++i) {
+            // Remove binary escaped bytes when displaying the packet...
+            const char ch = m_bytes[i];
+            if (ch == 0x7d) {
+              // 0x7d is the escape character.  The next character is to
+              // be XOR'd with 0x20.
+              const char escapee = m_bytes[++i] ^ 0x20;
+              strm.Printf("%2.2x", escapee);
+            } else {
+              strm.Printf("%2.2x", (uint8_t)ch);
             }
+          }
+          // Packet footer...
+          strm.Printf("%c%c%c", m_bytes[total_length - 3],
+                      m_bytes[total_length - 2], m_bytes[total_length - 1]);
+          log->PutCString(strm.GetString().c_str());
+        } else {
+          if (CompressionIsEnabled())
+            log->Printf("<%4" PRIu64 ":%" PRIu64 "> read packet: %.*s",
+                        (uint64_t)original_packet_size, (uint64_t)total_length,
+                        (int)(total_length), m_bytes.c_str());
+          else
+            log->Printf("<%4" PRIu64 "> read packet: %.*s",
+                        (uint64_t)total_length, (int)(total_length),
+                        m_bytes.c_str());
+        }
+      }
 
-            m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length);
+      m_history.AddPacket(m_bytes.c_str(), total_length,
+                          History::ePacketTypeRecv, total_length);
 
-            // Clear packet_str in case there is some existing data in it.
-            packet_str.clear();
-            // Copy the packet from m_bytes to packet_str expanding the
-            // run-length encoding in the process.
-            // Reserve enough byte for the most common case (no RLE used)
-            packet_str.reserve(m_bytes.length());
-            for (std::string::const_iterator c = m_bytes.begin() + content_start; c != m_bytes.begin() + content_end; ++c)
-            {
-                if (*c == '*')
-                {
-                    // '*' indicates RLE. Next character will give us the
-                    // repeat count and previous character is what is to be
-                    // repeated.
-                    char char_to_repeat = packet_str.back();
-                    // Number of time the previous character is repeated
-                    int repeat_count = *++c + 3 - ' ';
-                    // We have the char_to_repeat and repeat_count. Now push
-                    // it in the packet.
-                    for (int i = 0; i < repeat_count; ++i)
-                        packet_str.push_back(char_to_repeat);
-                }
-                else if (*c == 0x7d)
-                {
-                    // 0x7d is the escape character.  The next character is to
-                    // be XOR'd with 0x20.
-                    char escapee = *++c ^ 0x20;
-                    packet_str.push_back(escapee);
-                }
-                else
-                {
-                    packet_str.push_back(*c);
-                }
+      // Clear packet_str in case there is some existing data in it.
+      packet_str.clear();
+      // Copy the packet from m_bytes to packet_str expanding the
+      // run-length encoding in the process.
+      // Reserve enough byte for the most common case (no RLE used)
+      packet_str.reserve(m_bytes.length());
+      for (std::string::const_iterator c = m_bytes.begin() + content_start;
+           c != m_bytes.begin() + content_end; ++c) {
+        if (*c == '*') {
+          // '*' indicates RLE. Next character will give us the
+          // repeat count and previous character is what is to be
+          // repeated.
+          char char_to_repeat = packet_str.back();
+          // Number of time the previous character is repeated
+          int repeat_count = *++c + 3 - ' ';
+          // We have the char_to_repeat and repeat_count. Now push
+          // it in the packet.
+          for (int i = 0; i < repeat_count; ++i)
+            packet_str.push_back(char_to_repeat);
+        } else if (*c == 0x7d) {
+          // 0x7d is the escape character.  The next character is to
+          // be XOR'd with 0x20.
+          char escapee = *++c ^ 0x20;
+          packet_str.push_back(escapee);
+        } else {
+          packet_str.push_back(*c);
+        }
+      }
+
+      if (m_bytes[0] == '$' || m_bytes[0] == '%') {
+        assert(checksum_idx < m_bytes.size());
+        if (::isxdigit(m_bytes[checksum_idx + 0]) ||
+            ::isxdigit(m_bytes[checksum_idx + 1])) {
+          if (GetSendAcks()) {
+            const char *packet_checksum_cstr = &m_bytes[checksum_idx];
+            char packet_checksum = strtol(packet_checksum_cstr, NULL, 16);
+            char actual_checksum = CalculcateChecksum(packet_str);
+            success = packet_checksum == actual_checksum;
+            if (!success) {
+              if (log)
+                log->Printf("error: checksum mismatch: %.*s expected 0x%2.2x, "
+                            "got 0x%2.2x",
+                            (int)(total_length), m_bytes.c_str(),
+                            (uint8_t)packet_checksum, (uint8_t)actual_checksum);
             }
-
-            if (m_bytes[0] == '$' || m_bytes[0] == '%')
-            {
-                assert (checksum_idx < m_bytes.size());
-                if (::isxdigit (m_bytes[checksum_idx+0]) || 
-                    ::isxdigit (m_bytes[checksum_idx+1]))
-                {
-                    if (GetSendAcks ())
-                    {
-                        const char *packet_checksum_cstr = &m_bytes[checksum_idx];
-                        char packet_checksum = strtol (packet_checksum_cstr, NULL, 16);
-                        char actual_checksum = CalculcateChecksum (packet_str);
-                        success = packet_checksum == actual_checksum;
-                        if (!success)
-                        {
-                            if (log)
-                                log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", 
-                                             (int)(total_length), 
-                                             m_bytes.c_str(),
-                                             (uint8_t)packet_checksum,
-                                             (uint8_t)actual_checksum);
-                        }
-                        // Send the ack or nack if needed
-                        if (!success)
-                            SendNack();
-                        else
-                            SendAck();
-                    }
-                }
-                else
-                {
-                    success = false;
-                    if (log)
-                        log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str());
-                }
-            }
-            
-            m_bytes.erase(0, total_length);
-            packet.SetFilePos(0);
-
-            if (isNotifyPacket)
-                return GDBRemoteCommunication::PacketType::Notify;
+            // Send the ack or nack if needed
+            if (!success)
+              SendNack();
             else
-                return GDBRemoteCommunication::PacketType::Standard;
+              SendAck();
+          }
+        } else {
+          success = false;
+          if (log)
+            log->Printf("error: invalid checksum in packet: '%s'\n",
+                        m_bytes.c_str());
         }
+      }
+
+      m_bytes.erase(0, total_length);
+      packet.SetFilePos(0);
+
+      if (isNotifyPacket)
+        return GDBRemoteCommunication::PacketType::Notify;
+      else
+        return GDBRemoteCommunication::PacketType::Standard;
     }
-    packet.Clear();
-    return GDBRemoteCommunication::PacketType::Invalid;
+  }
+  packet.Clear();
+  return GDBRemoteCommunication::PacketType::Invalid;
 }
 
-Error
-GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
-{
-    Error error;
-    if (m_listen_thread.IsJoinable())
-    {
-        error.SetErrorString("listen thread already running");
-    }
+Error GDBRemoteCommunication::StartListenThread(const char *hostname,
+                                                uint16_t port) {
+  Error error;
+  if (m_listen_thread.IsJoinable()) {
+    error.SetErrorString("listen thread already running");
+  } else {
+    char listen_url[512];
+    if (hostname && hostname[0])
+      snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname,
+               port);
     else
-    {
-        char listen_url[512];
-        if (hostname && hostname[0])
-            snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
-        else
-            snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
-        m_listen_url = listen_url;
-        SetConnection(new ConnectionFileDescriptor());
-        m_listen_thread = ThreadLauncher::LaunchThread(listen_url, GDBRemoteCommunication::ListenThread, this, &error);
-    }
-    return error;
+      snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
+    m_listen_url = listen_url;
+    SetConnection(new ConnectionFileDescriptor());
+    m_listen_thread = ThreadLauncher::LaunchThread(
+        listen_url, GDBRemoteCommunication::ListenThread, this, &error);
+  }
+  return error;
 }
 
-bool
-GDBRemoteCommunication::JoinListenThread ()
-{
-    if (m_listen_thread.IsJoinable())
-        m_listen_thread.Join(nullptr);
-    return true;
+bool GDBRemoteCommunication::JoinListenThread() {
+  if (m_listen_thread.IsJoinable())
+    m_listen_thread.Join(nullptr);
+  return true;
 }
 
 lldb::thread_result_t
-GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
-{
-    GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
-    Error error;
-    ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
-    
-    if (connection)
-    {
-        // Do the listen on another thread so we can continue on...
-        if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
-            comm->SetConnection(NULL);
-    }
-    return NULL;
+GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) {
+  GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+  Error error;
+  ConnectionFileDescriptor *connection =
+      (ConnectionFileDescriptor *)comm->GetConnection();
+
+  if (connection) {
+    // Do the listen on another thread so we can continue on...
+    if (connection->Connect(comm->m_listen_url.c_str(), &error) !=
+        eConnectionStatusSuccess)
+      comm->SetConnection(NULL);
+  }
+  return NULL;
 }
 
-Error
-GDBRemoteCommunication::StartDebugserverProcess (const char *url,
-                                                 Platform *platform,
-                                                 ProcessLaunchInfo &launch_info,
-                                                 uint16_t *port,
-                                                 const Args* inferior_args,
-                                                 int pass_comm_fd)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+Error GDBRemoteCommunication::StartDebugserverProcess(
+    const char *url, Platform *platform, ProcessLaunchInfo &launch_info,
+    uint16_t *port, const Args *inferior_args, int pass_comm_fd) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")",
+                __FUNCTION__, url ? url : "<empty>",
+                port ? *port : uint16_t(0));
+
+  Error error;
+  // If we locate debugserver, keep that located version around
+  static FileSpec g_debugserver_file_spec;
+
+  char debugserver_path[PATH_MAX];
+  FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
+
+  // Always check to see if we have an environment override for the path
+  // to the debugserver to use and use it if we do.
+  const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
+  if (env_debugserver_path) {
+    debugserver_file_spec.SetFile(env_debugserver_path, false);
     if (log)
-        log->Printf ("GDBRemoteCommunication::%s(url=%s, port=%" PRIu16 ")", __FUNCTION__, url ? url : "<empty>", port ? *port : uint16_t(0));
-
-    Error error;
-    // If we locate debugserver, keep that located version around
-    static FileSpec g_debugserver_file_spec;
-    
-    char debugserver_path[PATH_MAX];
-    FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
-    
-    // Always check to see if we have an environment override for the path
-    // to the debugserver to use and use it if we do.
-    const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
-    if (env_debugserver_path)
-    {
-        debugserver_file_spec.SetFile (env_debugserver_path, false);
+      log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set "
+                  "from environment variable: %s",
+                  __FUNCTION__, env_debugserver_path);
+  } else
+    debugserver_file_spec = g_debugserver_file_spec;
+  bool debugserver_exists = debugserver_file_spec.Exists();
+  if (!debugserver_exists) {
+    // The debugserver binary is in the LLDB.framework/Resources
+    // directory.
+    if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir,
+                              debugserver_file_spec)) {
+      debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME);
+      debugserver_exists = debugserver_file_spec.Exists();
+      if (debugserver_exists) {
         if (log)
-            log->Printf ("GDBRemoteCommunication::%s() gdb-remote stub exe path set from environment variable: %s", __FUNCTION__, env_debugserver_path);
-    }
-    else
-        debugserver_file_spec = g_debugserver_file_spec;
-    bool debugserver_exists = debugserver_file_spec.Exists();
-    if (!debugserver_exists)
-    {
-        // The debugserver binary is in the LLDB.framework/Resources
-        // directory.
-        if (HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, debugserver_file_spec))
-        {
-            debugserver_file_spec.AppendPathComponent (DEBUGSERVER_BASENAME);
-            debugserver_exists = debugserver_file_spec.Exists();
-            if (debugserver_exists)
-            {
-                if (log)
-                    log->Printf ("GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
+          log->Printf(
+              "GDBRemoteCommunication::%s() found gdb-remote stub exe '%s'",
+              __FUNCTION__, debugserver_file_spec.GetPath().c_str());
 
-                g_debugserver_file_spec = debugserver_file_spec;
-            }
-            else
-            {
-                debugserver_file_spec = platform->LocateExecutable(DEBUGSERVER_BASENAME);
-                if (debugserver_file_spec)
-                {
-                    // Platform::LocateExecutable() wouldn't return a path if it doesn't exist
-                    debugserver_exists = true;
-                }
-                else
-                {
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());
-                }
-                // Don't cache the platform specific GDB server binary as it could change
-                // from platform to platform
-                g_debugserver_file_spec.Clear();
-            }
+        g_debugserver_file_spec = debugserver_file_spec;
+      } else {
+        debugserver_file_spec =
+            platform->LocateExecutable(DEBUGSERVER_BASENAME);
+        if (debugserver_file_spec) {
+          // Platform::LocateExecutable() wouldn't return a path if it doesn't
+          // exist
+          debugserver_exists = true;
+        } else {
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() could not find "
+                        "gdb-remote stub exe '%s'",
+                        __FUNCTION__, debugserver_file_spec.GetPath().c_str());
         }
+        // Don't cache the platform specific GDB server binary as it could
+        // change
+        // from platform to platform
+        g_debugserver_file_spec.Clear();
+      }
     }
-    
-    if (debugserver_exists)
-    {
-        debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
+  }
 
-        Args &debugserver_args = launch_info.GetArguments();
-        debugserver_args.Clear();
-        char arg_cstr[PATH_MAX];
+  if (debugserver_exists) {
+    debugserver_file_spec.GetPath(debugserver_path, sizeof(debugserver_path));
 
-        // Start args with "debugserver /file/path -r --"
-        debugserver_args.AppendArgument(debugserver_path);
+    Args &debugserver_args = launch_info.GetArguments();
+    debugserver_args.Clear();
+    char arg_cstr[PATH_MAX];
+
+    // Start args with "debugserver /file/path -r --"
+    debugserver_args.AppendArgument(debugserver_path);
 
 #if !defined(__APPLE__)
-        // First argument to lldb-server must be mode in which to run.
-        debugserver_args.AppendArgument("gdbserver");
+    // First argument to lldb-server must be mode in which to run.
+    debugserver_args.AppendArgument("gdbserver");
 #endif
 
-        // If a url is supplied then use it
-        if (url)
-            debugserver_args.AppendArgument(url);
+    // If a url is supplied then use it
+    if (url)
+      debugserver_args.AppendArgument(url);
 
-        if (pass_comm_fd >= 0)
-        {
-            StreamString fd_arg;
-            fd_arg.Printf("--fd=%i", pass_comm_fd);
-            debugserver_args.AppendArgument(fd_arg.GetData());
-            // Send "pass_comm_fd" down to the inferior so it can use it to
-            // communicate back with this process
-            launch_info.AppendDuplicateFileAction(pass_comm_fd, pass_comm_fd);
-        }
+    if (pass_comm_fd >= 0) {
+      StreamString fd_arg;
+      fd_arg.Printf("--fd=%i", pass_comm_fd);
+      debugserver_args.AppendArgument(fd_arg.GetData());
+      // Send "pass_comm_fd" down to the inferior so it can use it to
+      // communicate back with this process
+      launch_info.AppendDuplicateFileAction(pass_comm_fd, pass_comm_fd);
+    }
 
-        // use native registers, not the GDB registers
-        debugserver_args.AppendArgument("--native-regs");
+    // use native registers, not the GDB registers
+    debugserver_args.AppendArgument("--native-regs");
 
-        if (launch_info.GetLaunchInSeparateProcessGroup())
-        {
-            debugserver_args.AppendArgument("--setsid");
-        }
+    if (launch_info.GetLaunchInSeparateProcessGroup()) {
+      debugserver_args.AppendArgument("--setsid");
+    }
 
-        llvm::SmallString<PATH_MAX> named_pipe_path;
-        // socket_pipe is used by debug server to communicate back either
-        // TCP port or domain socket name which it listens on.
-        // The second purpose of the pipe to serve as a synchronization point -
-        // once data is written to the pipe, debug server is up and running.
-        Pipe socket_pipe;
+    llvm::SmallString<PATH_MAX> named_pipe_path;
+    // socket_pipe is used by debug server to communicate back either
+    // TCP port or domain socket name which it listens on.
+    // The second purpose of the pipe to serve as a synchronization point -
+    // once data is written to the pipe, debug server is up and running.
+    Pipe socket_pipe;
 
-        // port is null when debug server should listen on domain socket -
-        // we're not interested in port value but rather waiting for debug server
-        // to become available.
-        if (pass_comm_fd == -1 && ((port != nullptr && *port == 0) || port == nullptr))
-        {
-            if (url)
-            {
-                // Create a temporary file to get the stdout/stderr and redirect the
-                // output of the command into this file. We will later read this file
-                // if all goes well and fill the data into "command_output_ptr"
-    
+    // port is null when debug server should listen on domain socket -
+    // we're not interested in port value but rather waiting for debug server
+    // to become available.
+    if (pass_comm_fd == -1 &&
+        ((port != nullptr && *port == 0) || port == nullptr)) {
+      if (url) {
+// Create a temporary file to get the stdout/stderr and redirect the
+// output of the command into this file. We will later read this file
+// if all goes well and fill the data into "command_output_ptr"
+
 #if defined(__APPLE__)
-                // Binding to port zero, we need to figure out what port it ends up
-                // using using a named pipe...
-                error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
-                if (error.Fail())
-                {
-                    if (log)
-                        log->Printf("GDBRemoteCommunication::%s() "
-                                "named pipe creation failed: %s",
-                                __FUNCTION__, error.AsCString());
-                    return error;
-                }
-                debugserver_args.AppendArgument("--named-pipe");
-                debugserver_args.AppendArgument(named_pipe_path.c_str());
+        // Binding to port zero, we need to figure out what port it ends up
+        // using using a named pipe...
+        error = socket_pipe.CreateWithUniqueName("debugserver-named-pipe",
+                                                 false, named_pipe_path);
+        if (error.Fail()) {
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() "
+                        "named pipe creation failed: %s",
+                        __FUNCTION__, error.AsCString());
+          return error;
+        }
+        debugserver_args.AppendArgument("--named-pipe");
+        debugserver_args.AppendArgument(named_pipe_path.c_str());
 #else
-                // Binding to port zero, we need to figure out what port it ends up
-                // using using an unnamed pipe...
-                error = socket_pipe.CreateNew(true);
-                if (error.Fail())
-                {
-                    if (log)
-                        log->Printf("GDBRemoteCommunication::%s() "
-                                "unnamed pipe creation failed: %s",
-                                __FUNCTION__, error.AsCString());
-                    return error;
-                }
-                int write_fd = socket_pipe.GetWriteFileDescriptor();
-                debugserver_args.AppendArgument("--pipe");
-                debugserver_args.AppendArgument(llvm::to_string(write_fd).c_str());
-                launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
+        // Binding to port zero, we need to figure out what port it ends up
+        // using using an unnamed pipe...
+        error = socket_pipe.CreateNew(true);
+        if (error.Fail()) {
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() "
+                        "unnamed pipe creation failed: %s",
+                        __FUNCTION__, error.AsCString());
+          return error;
+        }
+        int write_fd = socket_pipe.GetWriteFileDescriptor();
+        debugserver_args.AppendArgument("--pipe");
+        debugserver_args.AppendArgument(llvm::to_string(write_fd).c_str());
+        launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor());
 #endif
-            }
-            else
-            {
-                // No host and port given, so lets listen on our end and make the debugserver
-                // connect to us..
-                error = StartListenThread ("127.0.0.1", 0);
-                if (error.Fail())
-                {
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s() unable to start listen thread: %s", __FUNCTION__, error.AsCString());
-                    return error;
-                }
-    
-                ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
-                // Wait for 10 seconds to resolve the bound port
-                uint16_t port_ = connection->GetListeningPort(10);
-                if (port_ > 0)
-                {
-                    char port_cstr[32];
-                    snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", port_);
-                    // Send the host and port down that debugserver and specify an option
-                    // so that it connects back to the port we are listening to in this process
-                    debugserver_args.AppendArgument("--reverse-connect");
-                    debugserver_args.AppendArgument(port_cstr);
-                    if (port)
-                        *port = port_;
-                }
-                else
-                {
-                    error.SetErrorString ("failed to bind to port 0 on 127.0.0.1");
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
-                    return error;
-                }
-            }
+      } else {
+        // No host and port given, so lets listen on our end and make the
+        // debugserver
+        // connect to us..
+        error = StartListenThread("127.0.0.1", 0);
+        if (error.Fail()) {
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() unable to start listen "
+                        "thread: %s",
+                        __FUNCTION__, error.AsCString());
+          return error;
         }
-        
-        const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
-        if (env_debugserver_log_file)
-        {
-            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
-            debugserver_args.AppendArgument(arg_cstr);
+
+        ConnectionFileDescriptor *connection =
+            (ConnectionFileDescriptor *)GetConnection();
+        // Wait for 10 seconds to resolve the bound port
+        uint16_t port_ = connection->GetListeningPort(10);
+        if (port_ > 0) {
+          char port_cstr[32];
+          snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", port_);
+          // Send the host and port down that debugserver and specify an option
+          // so that it connects back to the port we are listening to in this
+          // process
+          debugserver_args.AppendArgument("--reverse-connect");
+          debugserver_args.AppendArgument(port_cstr);
+          if (port)
+            *port = port_;
+        } else {
+          error.SetErrorString("failed to bind to port 0 on 127.0.0.1");
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+                        error.AsCString());
+          return error;
         }
-        
+      }
+    }
+
+    const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
+    if (env_debugserver_log_file) {
+      ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-file=%s",
+                 env_debugserver_log_file);
+      debugserver_args.AppendArgument(arg_cstr);
+    }
+
 #if defined(__APPLE__)
-        const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
-        if (env_debugserver_log_flags)
-        {
-            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
-            debugserver_args.AppendArgument(arg_cstr);
-        }
+    const char *env_debugserver_log_flags =
+        getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
+    if (env_debugserver_log_flags) {
+      ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-flags=%s",
+                 env_debugserver_log_flags);
+      debugserver_args.AppendArgument(arg_cstr);
+    }
 #else
-        const char *env_debugserver_log_channels = getenv("LLDB_SERVER_LOG_CHANNELS");
-        if (env_debugserver_log_channels)
-        {
-            ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-channels=%s", env_debugserver_log_channels);
-            debugserver_args.AppendArgument(arg_cstr);
-        }
+    const char *env_debugserver_log_channels =
+        getenv("LLDB_SERVER_LOG_CHANNELS");
+    if (env_debugserver_log_channels) {
+      ::snprintf(arg_cstr, sizeof(arg_cstr), "--log-channels=%s",
+                 env_debugserver_log_channels);
+      debugserver_args.AppendArgument(arg_cstr);
+    }
 #endif
 
-        // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an env var doesn't come back.
-        uint32_t env_var_index = 1;
-        bool has_env_var;
-        do
-        {
-            char env_var_name[64];
-            snprintf (env_var_name, sizeof (env_var_name), "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
-            const char *extra_arg = getenv(env_var_name);
-            has_env_var = extra_arg != nullptr;
+    // Add additional args, starting with LLDB_DEBUGSERVER_EXTRA_ARG_1 until an
+    // env var doesn't come back.
+    uint32_t env_var_index = 1;
+    bool has_env_var;
+    do {
+      char env_var_name[64];
+      snprintf(env_var_name, sizeof(env_var_name),
+               "LLDB_DEBUGSERVER_EXTRA_ARG_%" PRIu32, env_var_index++);
+      const char *extra_arg = getenv(env_var_name);
+      has_env_var = extra_arg != nullptr;
 
-            if (has_env_var)
-            {
-                debugserver_args.AppendArgument (extra_arg);
-                if (log)
-                    log->Printf ("GDBRemoteCommunication::%s adding env var %s contents to stub command line (%s)", __FUNCTION__, env_var_name, extra_arg);
-            }
-        } while (has_env_var);
-
-        if (inferior_args && inferior_args->GetArgumentCount() > 0)
-        {
-            debugserver_args.AppendArgument ("--");
-            debugserver_args.AppendArguments (*inferior_args);
-        }
-
-        // Copy the current environment to the gdbserver/debugserver instance
-        StringList env;
-        if (Host::GetEnvironment(env))
-        {
-            for (size_t i = 0; i < env.GetSize(); ++i)
-                launch_info.GetEnvironmentEntries().AppendArgument(env[i].c_str());
-        }
-
-        // Close STDIN, STDOUT and STDERR.
-        launch_info.AppendCloseFileAction (STDIN_FILENO);
-        launch_info.AppendCloseFileAction (STDOUT_FILENO);
-        launch_info.AppendCloseFileAction (STDERR_FILENO);
-
-        // Redirect STDIN, STDOUT and STDERR to "/dev/null".
-        launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
-        launch_info.AppendSuppressFileAction (STDOUT_FILENO, false, true);
-        launch_info.AppendSuppressFileAction (STDERR_FILENO, false, true);
-
+      if (has_env_var) {
+        debugserver_args.AppendArgument(extra_arg);
         if (log)
-        {
-            StreamString string_stream;
-            Platform *const platform = nullptr;
-            launch_info.Dump(string_stream, platform);
-            log->Printf("launch info for gdb-remote stub:\n%s", string_stream.GetString().c_str());
+          log->Printf("GDBRemoteCommunication::%s adding env var %s contents "
+                      "to stub command line (%s)",
+                      __FUNCTION__, env_var_name, extra_arg);
+      }
+    } while (has_env_var);
+
+    if (inferior_args && inferior_args->GetArgumentCount() > 0) {
+      debugserver_args.AppendArgument("--");
+      debugserver_args.AppendArguments(*inferior_args);
+    }
+
+    // Copy the current environment to the gdbserver/debugserver instance
+    StringList env;
+    if (Host::GetEnvironment(env)) {
+      for (size_t i = 0; i < env.GetSize(); ++i)
+        launch_info.GetEnvironmentEntries().AppendArgument(env[i].c_str());
+    }
+
+    // Close STDIN, STDOUT and STDERR.
+    launch_info.AppendCloseFileAction(STDIN_FILENO);
+    launch_info.AppendCloseFileAction(STDOUT_FILENO);
+    launch_info.AppendCloseFileAction(STDERR_FILENO);
+
+    // Redirect STDIN, STDOUT and STDERR to "/dev/null".
+    launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
+    launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
+    launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);
+
+    if (log) {
+      StreamString string_stream;
+      Platform *const platform = nullptr;
+      launch_info.Dump(string_stream, platform);
+      log->Printf("launch info for gdb-remote stub:\n%s",
+                  string_stream.GetString().c_str());
+    }
+    error = Host::LaunchProcess(launch_info);
+
+    if (error.Success() &&
+        (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) &&
+        pass_comm_fd == -1) {
+      if (named_pipe_path.size() > 0) {
+        error = socket_pipe.OpenAsReader(named_pipe_path, false);
+        if (error.Fail())
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() "
+                        "failed to open named pipe %s for reading: %s",
+                        __FUNCTION__, named_pipe_path.c_str(),
+                        error.AsCString());
+      }
+
+      if (socket_pipe.CanWrite())
+        socket_pipe.CloseWriteFileDescriptor();
+      if (socket_pipe.CanRead()) {
+        char port_cstr[PATH_MAX] = {0};
+        port_cstr[0] = '\0';
+        size_t num_bytes = sizeof(port_cstr);
+        // Read port from pipe with 10 second timeout.
+        error = socket_pipe.ReadWithTimeout(
+            port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes);
+        if (error.Success() && (port != nullptr)) {
+          assert(num_bytes > 0 && port_cstr[num_bytes - 1] == '\0');
+          *port = StringConvert::ToUInt32(port_cstr, 0);
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() "
+                        "debugserver listens %u port",
+                        __FUNCTION__, *port);
+        } else {
+          if (log)
+            log->Printf("GDBRemoteCommunication::%s() "
+                        "failed to read a port value from pipe %s: %s",
+                        __FUNCTION__, named_pipe_path.c_str(),
+                        error.AsCString());
         }
-        error = Host::LaunchProcess(launch_info);
-        
-        if (error.Success() && (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) && pass_comm_fd == -1)
-        {
-            if (named_pipe_path.size() > 0)
-            {
-                error = socket_pipe.OpenAsReader(named_pipe_path, false);
-                if (error.Fail())
-                    if (log)
-                        log->Printf("GDBRemoteCommunication::%s() "
-                                "failed to open named pipe %s for reading: %s",
-                                __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
-            }
+        socket_pipe.Close();
+      }
 
-            if (socket_pipe.CanWrite())
-                socket_pipe.CloseWriteFileDescriptor();
-            if (socket_pipe.CanRead())
-            {
-                char port_cstr[PATH_MAX] = {0};
-                port_cstr[0] = '\0';
-                size_t num_bytes = sizeof(port_cstr);
-                // Read port from pipe with 10 second timeout.
-                error = socket_pipe.ReadWithTimeout(port_cstr, num_bytes,
-                        std::chrono::seconds{10}, num_bytes);
-                if (error.Success() && (port != nullptr))
-                {
-                    assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
-                    *port = StringConvert::ToUInt32(port_cstr, 0);
-                    if (log)
-                        log->Printf("GDBRemoteCommunication::%s() "
-                                    "debugserver listens %u port",
-                                    __FUNCTION__, *port);
-                }
-                else
-                {
-                    if (log)
-                        log->Printf("GDBRemoteCommunication::%s() "
-                                "failed to read a port value from pipe %s: %s",
-                                __FUNCTION__, named_pipe_path.c_str(), error.AsCString());
-
-                }
-                socket_pipe.Close();
-            }
-
-            if (named_pipe_path.size() > 0)
-            {
-                const auto err = socket_pipe.Delete(named_pipe_path);
-                if (err.Fail())
-                {
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s failed to delete pipe %s: %s",
-                                __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
-                }
-            }
-
-            // Make sure we actually connect with the debugserver...
-            JoinListenThread();
+      if (named_pipe_path.size() > 0) {
+        const auto err = socket_pipe.Delete(named_pipe_path);
+        if (err.Fail()) {
+          if (log)
+            log->Printf(
+                "GDBRemoteCommunication::%s failed to delete pipe %s: %s",
+                __FUNCTION__, named_pipe_path.c_str(), err.AsCString());
         }
+      }
+
+      // Make sure we actually connect with the debugserver...
+      JoinListenThread();
     }
-    else
-    {
-        error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME );
-    }
+  } else {
+    error.SetErrorStringWithFormat("unable to locate " DEBUGSERVER_BASENAME);
+  }
 
-    if (error.Fail())
-    {
-        if (log)
-            log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
-    }
+  if (error.Fail()) {
+    if (log)
+      log->Printf("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__,
+                  error.AsCString());
+  }
 
-    return error;
+  return error;
 }
 
-void
-GDBRemoteCommunication::DumpHistory(Stream &strm)
-{
-    m_history.Dump (strm);
+void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); }
+
+GDBRemoteCommunication::ScopedTimeout::ScopedTimeout(
+    GDBRemoteCommunication &gdb_comm, uint32_t timeout)
+    : m_gdb_comm(gdb_comm) {
+  m_saved_timeout = m_gdb_comm.SetPacketTimeout(timeout);
 }
 
-GDBRemoteCommunication::ScopedTimeout::ScopedTimeout (GDBRemoteCommunication& gdb_comm,
-                                                      uint32_t timeout) :
-    m_gdb_comm (gdb_comm)
-{
-    m_saved_timeout = m_gdb_comm.SetPacketTimeout (timeout);
+GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout() {
+  m_gdb_comm.SetPacketTimeout(m_saved_timeout);
 }
 
-GDBRemoteCommunication::ScopedTimeout::~ScopedTimeout ()
-{
-    m_gdb_comm.SetPacketTimeout (m_saved_timeout);
-}
-
-// This function is called via the Communications class read thread when bytes become available
-// for this connection. This function will consume all incoming bytes and try to parse whole
-// packets as they become available. Full packets are placed in a queue, so that all packet
-// requests can simply pop from this queue. Async notification packets will be dispatched
+// This function is called via the Communications class read thread when bytes
+// become available
+// for this connection. This function will consume all incoming bytes and try to
+// parse whole
+// packets as they become available. Full packets are placed in a queue, so that
+// all packet
+// requests can simply pop from this queue. Async notification packets will be
+// dispatched
 // immediately to the ProcessGDBRemote Async thread via an event.
-void GDBRemoteCommunication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, lldb::ConnectionStatus status)
-{
-    StringExtractorGDBRemote packet;
+void GDBRemoteCommunication::AppendBytesToCache(const uint8_t *bytes,
+                                                size_t len, bool broadcast,
+                                                lldb::ConnectionStatus status) {
+  StringExtractorGDBRemote packet;
 
-    while (true)
-    {
-        PacketType type = CheckForPacket(bytes, len, packet);
+  while (true) {
+    PacketType type = CheckForPacket(bytes, len, packet);
 
-        // scrub the data so we do not pass it back to CheckForPacket
-        // on future passes of the loop
-        bytes = nullptr;
-        len = 0;
+    // scrub the data so we do not pass it back to CheckForPacket
+    // on future passes of the loop
+    bytes = nullptr;
+    len = 0;
 
-        // we may have received no packet so lets bail out
-        if (type == PacketType::Invalid)
-            break;
+    // we may have received no packet so lets bail out
+    if (type == PacketType::Invalid)
+      break;
 
-        if (type == PacketType::Standard)
-        {
-            // scope for the mutex
-            {
-                // lock down the packet queue
-                std::lock_guard<std::mutex> guard(m_packet_queue_mutex);
-                // push a new packet into the queue
-                m_packet_queue.push(packet);
-                // Signal condition variable that we have a packet
-                m_condition_queue_not_empty.notify_one();
-            }
-        }
-
-        if (type == PacketType::Notify)
-        {
-            // put this packet into an event
-            const char *pdata = packet.GetStringRef().c_str();
-
-            // as the communication class, we are a broadcaster and the
-            // async thread is tuned to listen to us
-            BroadcastEvent(
-                eBroadcastBitGdbReadThreadGotNotify,
-                new EventDataBytes(pdata));
-        }
+    if (type == PacketType::Standard) {
+      // scope for the mutex
+      {
+        // lock down the packet queue
+        std::lock_guard<std::mutex> guard(m_packet_queue_mutex);
+        // push a new packet into the queue
+        m_packet_queue.push(packet);
+        // Signal condition variable that we have a packet
+        m_condition_queue_not_empty.notify_one();
+      }
     }
+
+    if (type == PacketType::Notify) {
+      // put this packet into an event
+      const char *pdata = packet.GetStringRef().c_str();
+
+      // as the communication class, we are a broadcaster and the
+      // async thread is tuned to listen to us
+      BroadcastEvent(eBroadcastBitGdbReadThreadGotNotify,
+                     new EventDataBytes(pdata));
+    }
+  }
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index 5343a91..854fa76 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -14,334 +14,277 @@
 // C++ Includes
 #include <condition_variable>
 #include <mutex>
-#include <string>
 #include <queue>
+#include <string>
 #include <vector>
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-public.h"
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/Listener.h"
 #include "lldb/Host/HostThread.h"
 #include "lldb/Host/Predicate.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Interpreter/Args.h"
+#include "lldb/lldb-public.h"
 
 #include "Utility/StringExtractorGDBRemote.h"
 
 namespace lldb_private {
 namespace process_gdb_remote {
 
-typedef enum
-{
-    eStoppointInvalid = -1,
-    eBreakpointSoftware = 0,
-    eBreakpointHardware,
-    eWatchpointWrite,
-    eWatchpointRead,
-    eWatchpointReadWrite
+typedef enum {
+  eStoppointInvalid = -1,
+  eBreakpointSoftware = 0,
+  eBreakpointHardware,
+  eWatchpointWrite,
+  eWatchpointRead,
+  eWatchpointReadWrite
 } GDBStoppointType;
 
-enum class CompressionType
-{
-    None = 0,       // no compression
-    ZlibDeflate,    // zlib's deflate compression scheme, requires zlib or Apple's libcompression
-    LZFSE,          // an Apple compression scheme, requires Apple's libcompression
-    LZ4,            // lz compression - called "lz4 raw" in libcompression terms, compat with https://code.google.com/p/lz4/
-    LZMA,           // Lempel–Ziv–Markov chain algorithm
+enum class CompressionType {
+  None = 0,    // no compression
+  ZlibDeflate, // zlib's deflate compression scheme, requires zlib or Apple's
+               // libcompression
+  LZFSE,       // an Apple compression scheme, requires Apple's libcompression
+  LZ4, // lz compression - called "lz4 raw" in libcompression terms, compat with
+       // https://code.google.com/p/lz4/
+  LZMA, // Lempel–Ziv–Markov chain algorithm
 };
 
 class ProcessGDBRemote;
 
-class GDBRemoteCommunication : public Communication
-{
+class GDBRemoteCommunication : public Communication {
 public:
-    enum
-    {
-        eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
-        eBroadcastBitGdbReadThreadGotNotify = kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
-    };
+  enum {
+    eBroadcastBitRunPacketSent = kLoUserBroadcastBit,
+    eBroadcastBitGdbReadThreadGotNotify =
+        kLoUserBroadcastBit << 1 // Sent when we received a notify packet.
+  };
 
-    enum class PacketType
-    {
-        Invalid = 0,
-        Standard,
-        Notify
-    };
+  enum class PacketType { Invalid = 0, Standard, Notify };
 
-    enum class PacketResult
-    {
-        Success = 0,        // Success
-        ErrorSendFailed,    // Error sending the packet
-        ErrorSendAck,       // Didn't get an ack back after sending a packet
-        ErrorReplyFailed,   // Error getting the reply
-        ErrorReplyTimeout,  // Timed out waiting for reply
-        ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that was sent
-        ErrorReplyAck,      // Sending reply ack failed
-        ErrorDisconnected,  // We were disconnected
-        ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
-    };
+  enum class PacketResult {
+    Success = 0,        // Success
+    ErrorSendFailed,    // Error sending the packet
+    ErrorSendAck,       // Didn't get an ack back after sending a packet
+    ErrorReplyFailed,   // Error getting the reply
+    ErrorReplyTimeout,  // Timed out waiting for reply
+    ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that
+                        // was sent
+    ErrorReplyAck,      // Sending reply ack failed
+    ErrorDisconnected,  // We were disconnected
+    ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
+                        // request
+  };
 
-    // Class to change the timeout for a given scope and restore it to the original value when the
-    // created ScopedTimeout object got out of scope
-    class ScopedTimeout
-    {
-    public:
-        ScopedTimeout (GDBRemoteCommunication& gdb_comm, uint32_t timeout);
-        ~ScopedTimeout ();
+  // Class to change the timeout for a given scope and restore it to the
+  // original value when the
+  // created ScopedTimeout object got out of scope
+  class ScopedTimeout {
+  public:
+    ScopedTimeout(GDBRemoteCommunication &gdb_comm, uint32_t timeout);
+    ~ScopedTimeout();
 
-    private:
-        GDBRemoteCommunication& m_gdb_comm;
-        uint32_t m_saved_timeout;
-    };
+  private:
+    GDBRemoteCommunication &m_gdb_comm;
+    uint32_t m_saved_timeout;
+  };
 
-    GDBRemoteCommunication(const char *comm_name, 
-                           const char *listener_name);
+  GDBRemoteCommunication(const char *comm_name, const char *listener_name);
 
-    ~GDBRemoteCommunication() override;
+  ~GDBRemoteCommunication() override;
 
-    PacketResult
-    GetAck ();
+  PacketResult GetAck();
 
-    size_t
-    SendAck ();
+  size_t SendAck();
 
-    size_t
-    SendNack ();
+  size_t SendNack();
 
-    char
-    CalculcateChecksum (llvm::StringRef payload);
+  char CalculcateChecksum(llvm::StringRef payload);
 
-    PacketType
-    CheckForPacket (const uint8_t *src, 
-                    size_t src_len, 
-                    StringExtractorGDBRemote &packet);
+  PacketType CheckForPacket(const uint8_t *src, size_t src_len,
+                            StringExtractorGDBRemote &packet);
 
-    bool
-    GetSendAcks ()
-    {
-        return m_send_acks;
-    }
+  bool GetSendAcks() { return m_send_acks; }
 
-    //------------------------------------------------------------------
-    // Set the global packet timeout.
-    //
-    // For clients, this is the timeout that gets used when sending
-    // packets and waiting for responses. For servers, this might not
-    // get used, and if it doesn't this should be moved to the
-    // GDBRemoteCommunicationClient.
-    //------------------------------------------------------------------
-    uint32_t 
-    SetPacketTimeout (uint32_t packet_timeout)
-    {
-        const uint32_t old_packet_timeout = m_packet_timeout;
-        m_packet_timeout = packet_timeout;
-        return old_packet_timeout;
-    }
+  //------------------------------------------------------------------
+  // Set the global packet timeout.
+  //
+  // For clients, this is the timeout that gets used when sending
+  // packets and waiting for responses. For servers, this might not
+  // get used, and if it doesn't this should be moved to the
+  // GDBRemoteCommunicationClient.
+  //------------------------------------------------------------------
+  uint32_t SetPacketTimeout(uint32_t packet_timeout) {
+    const uint32_t old_packet_timeout = m_packet_timeout;
+    m_packet_timeout = packet_timeout;
+    return old_packet_timeout;
+  }
 
-    uint32_t
-    GetPacketTimeoutInMicroSeconds () const
-    {
-        return m_packet_timeout * TimeValue::MicroSecPerSec;
-    }
+  uint32_t GetPacketTimeoutInMicroSeconds() const {
+    return m_packet_timeout * TimeValue::MicroSecPerSec;
+  }
 
-    //------------------------------------------------------------------
-    // Start a debugserver instance on the current host using the
-    // supplied connection URL.
-    //------------------------------------------------------------------
-    Error
-    StartDebugserverProcess(const char *url,
-                            Platform *platform, // If non nullptr, then check with the platform for the GDB server binary if it can't be located
-                            ProcessLaunchInfo &launch_info,
-                            uint16_t *port,
-                            const Args *inferior_args,
-                            int pass_comm_fd); // Communication file descriptor to pass during fork/exec to avoid having to connect/accept
+  //------------------------------------------------------------------
+  // Start a debugserver instance on the current host using the
+  // supplied connection URL.
+  //------------------------------------------------------------------
+  Error StartDebugserverProcess(
+      const char *url,
+      Platform *platform, // If non nullptr, then check with the platform for
+                          // the GDB server binary if it can't be located
+      ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args,
+      int pass_comm_fd); // Communication file descriptor to pass during
+                         // fork/exec to avoid having to connect/accept
 
-    void
-    DumpHistory(Stream &strm);
-    
+  void DumpHistory(Stream &strm);
+
 protected:
-    class History
-    {
-    public:
-        enum PacketType
-        {
-            ePacketTypeInvalid = 0,
-            ePacketTypeSend,
-            ePacketTypeRecv
-        };
-
-        struct Entry
-        {
-            Entry() :
-                packet(),
-                type (ePacketTypeInvalid),
-                bytes_transmitted (0),
-                packet_idx (0),
-                tid (LLDB_INVALID_THREAD_ID)
-            {
-            }
-            
-            void
-            Clear ()
-            {
-                packet.clear();
-                type = ePacketTypeInvalid;
-                bytes_transmitted = 0;
-                packet_idx = 0;
-                tid = LLDB_INVALID_THREAD_ID;
-            }
-            std::string packet;
-            PacketType type;
-            uint32_t bytes_transmitted;
-            uint32_t packet_idx;
-            lldb::tid_t tid;
-        };
-
-        History (uint32_t size);
-        
-        ~History ();
-
-        // For single char packets for ack, nack and /x03
-        void
-        AddPacket (char packet_char,
-                   PacketType type,
-                   uint32_t bytes_transmitted);
-
-        void
-        AddPacket (const std::string &src,
-                   uint32_t src_len,
-                   PacketType type,
-                   uint32_t bytes_transmitted);
-        
-        void
-        Dump (Stream &strm) const;
-
-        void
-        Dump (Log *log) const;
-
-        bool
-        DidDumpToLog () const
-        {
-            return m_dumped_to_log;
-        }
-    
-    protected:
-        uint32_t
-        GetFirstSavedPacketIndex () const
-        {
-            if (m_total_packet_count < m_packets.size())
-                return 0;
-            else
-                return m_curr_idx + 1;
-        }
-
-        uint32_t
-        GetNumPacketsInHistory () const
-        {
-            if (m_total_packet_count < m_packets.size())
-                return m_total_packet_count;
-            else
-                return (uint32_t)m_packets.size();
-        }
-
-        uint32_t
-        GetNextIndex()
-        {
-            ++m_total_packet_count;
-            const uint32_t idx = m_curr_idx;
-            m_curr_idx = NormalizeIndex(idx + 1);
-            return idx;
-        }
-
-        uint32_t
-        NormalizeIndex (uint32_t i) const
-        {
-            return i % m_packets.size();
-        }
-
-        std::vector<Entry> m_packets;
-        uint32_t m_curr_idx;
-        uint32_t m_total_packet_count;
-        mutable bool m_dumped_to_log;
+  class History {
+  public:
+    enum PacketType {
+      ePacketTypeInvalid = 0,
+      ePacketTypeSend,
+      ePacketTypeRecv
     };
 
-    uint32_t m_packet_timeout;
-    uint32_t m_echo_number;
-    LazyBool m_supports_qEcho;
-    History m_history;
-    bool m_send_acks;
-    bool m_is_platform; // Set to true if this class represents a platform,
-                        // false if this class represents a debug session for
-                        // a single process
-    
-    CompressionType m_compression_type;
+    struct Entry {
+      Entry()
+          : packet(), type(ePacketTypeInvalid), bytes_transmitted(0),
+            packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {}
 
-    PacketResult
-    SendPacketNoLock (llvm::StringRef payload);
+      void Clear() {
+        packet.clear();
+        type = ePacketTypeInvalid;
+        bytes_transmitted = 0;
+        packet_idx = 0;
+        tid = LLDB_INVALID_THREAD_ID;
+      }
+      std::string packet;
+      PacketType type;
+      uint32_t bytes_transmitted;
+      uint32_t packet_idx;
+      lldb::tid_t tid;
+    };
 
-    PacketResult
-    ReadPacket (StringExtractorGDBRemote &response, uint32_t timeout_usec, bool sync_on_timeout);
+    History(uint32_t size);
 
-    // Pop a packet from the queue in a thread safe manner
-    PacketResult
-    PopPacketFromQueue (StringExtractorGDBRemote &response, uint32_t timeout_usec);
+    ~History();
 
-    PacketResult
-    WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response, 
-                                                uint32_t timeout_usec,
-                                                bool sync_on_timeout);
+    // For single char packets for ack, nack and /x03
+    void AddPacket(char packet_char, PacketType type,
+                   uint32_t bytes_transmitted);
 
-    bool
-    CompressionIsEnabled ()
-    {
-        return m_compression_type != CompressionType::None;
+    void AddPacket(const std::string &src, uint32_t src_len, PacketType type,
+                   uint32_t bytes_transmitted);
+
+    void Dump(Stream &strm) const;
+
+    void Dump(Log *log) const;
+
+    bool DidDumpToLog() const { return m_dumped_to_log; }
+
+  protected:
+    uint32_t GetFirstSavedPacketIndex() const {
+      if (m_total_packet_count < m_packets.size())
+        return 0;
+      else
+        return m_curr_idx + 1;
     }
 
-    // If compression is enabled, decompress the packet in m_bytes and update
-    // m_bytes with the uncompressed version.
-    // Returns 'true' packet was decompressed and m_bytes is the now-decompressed text.
-    // Returns 'false' if unable to decompress or if the checksum was invalid.
-    //
-    // NB: Once the packet has been decompressed, checksum cannot be computed based
-    // on m_bytes.  The checksum was for the compressed packet.
-    bool
-    DecompressPacket ();
+    uint32_t GetNumPacketsInHistory() const {
+      if (m_total_packet_count < m_packets.size())
+        return m_total_packet_count;
+      else
+        return (uint32_t)m_packets.size();
+    }
 
-    Error
-    StartListenThread (const char *hostname = "127.0.0.1", uint16_t port = 0);
+    uint32_t GetNextIndex() {
+      ++m_total_packet_count;
+      const uint32_t idx = m_curr_idx;
+      m_curr_idx = NormalizeIndex(idx + 1);
+      return idx;
+    }
 
-    bool
-    JoinListenThread ();
+    uint32_t NormalizeIndex(uint32_t i) const { return i % m_packets.size(); }
 
-    static lldb::thread_result_t
-    ListenThread (lldb::thread_arg_t arg);
+    std::vector<Entry> m_packets;
+    uint32_t m_curr_idx;
+    uint32_t m_total_packet_count;
+    mutable bool m_dumped_to_log;
+  };
 
-    // GDB-Remote read thread
-    //  . this thread constantly tries to read from the communication
-    //    class and stores all packets received in a queue.  The usual
-    //    threads read requests simply pop packets off the queue in the
-    //    usual order.
-    //    This setup allows us to intercept and handle async packets, such
-    //    as the notify packet.
+  uint32_t m_packet_timeout;
+  uint32_t m_echo_number;
+  LazyBool m_supports_qEcho;
+  History m_history;
+  bool m_send_acks;
+  bool m_is_platform; // Set to true if this class represents a platform,
+                      // false if this class represents a debug session for
+                      // a single process
 
-    // This method is defined as part of communication.h
-    // when the read thread gets any bytes it will pass them on to this function
-    void AppendBytesToCache(const uint8_t * bytes,
-                            size_t len,
-                            bool broadcast,
-                            lldb::ConnectionStatus status) override;
+  CompressionType m_compression_type;
+
+  PacketResult SendPacketNoLock(llvm::StringRef payload);
+
+  PacketResult ReadPacket(StringExtractorGDBRemote &response,
+                          uint32_t timeout_usec, bool sync_on_timeout);
+
+  // Pop a packet from the queue in a thread safe manner
+  PacketResult PopPacketFromQueue(StringExtractorGDBRemote &response,
+                                  uint32_t timeout_usec);
+
+  PacketResult
+  WaitForPacketWithTimeoutMicroSecondsNoLock(StringExtractorGDBRemote &response,
+                                             uint32_t timeout_usec,
+                                             bool sync_on_timeout);
+
+  bool CompressionIsEnabled() {
+    return m_compression_type != CompressionType::None;
+  }
+
+  // If compression is enabled, decompress the packet in m_bytes and update
+  // m_bytes with the uncompressed version.
+  // Returns 'true' packet was decompressed and m_bytes is the now-decompressed
+  // text.
+  // Returns 'false' if unable to decompress or if the checksum was invalid.
+  //
+  // NB: Once the packet has been decompressed, checksum cannot be computed
+  // based
+  // on m_bytes.  The checksum was for the compressed packet.
+  bool DecompressPacket();
+
+  Error StartListenThread(const char *hostname = "127.0.0.1",
+                          uint16_t port = 0);
+
+  bool JoinListenThread();
+
+  static lldb::thread_result_t ListenThread(lldb::thread_arg_t arg);
+
+  // GDB-Remote read thread
+  //  . this thread constantly tries to read from the communication
+  //    class and stores all packets received in a queue.  The usual
+  //    threads read requests simply pop packets off the queue in the
+  //    usual order.
+  //    This setup allows us to intercept and handle async packets, such
+  //    as the notify packet.
+
+  // This method is defined as part of communication.h
+  // when the read thread gets any bytes it will pass them on to this function
+  void AppendBytesToCache(const uint8_t *bytes, size_t len, bool broadcast,
+                          lldb::ConnectionStatus status) override;
 
 private:
-    std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
-    std::mutex m_packet_queue_mutex;                     // Mutex for accessing queue
-    std::condition_variable m_condition_queue_not_empty; // Condition variable to wait for packets
+  std::queue<StringExtractorGDBRemote> m_packet_queue; // The packet queue
+  std::mutex m_packet_queue_mutex; // Mutex for accessing queue
+  std::condition_variable
+      m_condition_queue_not_empty; // Condition variable to wait for packets
 
-    HostThread m_listen_thread;
-    std::string m_listen_url;
+  HostThread m_listen_thread;
+  std::string m_listen_url;
 
-    DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
+  DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
 };
 
 } // namespace process_gdb_remote
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 555ae46..6e09196 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -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 @@
       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 @@
       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);
+  // 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");
-        }
+    // 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;
+  } else {
+    if (error_ptr)
+      error_ptr->SetErrorString("failed to send the handshake ack");
+  }
+  return false;
 }
 
-bool
-GDBRemoteCommunicationClient::GetEchoSupported ()
-{
-    if (m_supports_qEcho == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qEcho == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetEchoSupported() {
+  if (m_supports_qEcho == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qEcho == eLazyBoolYes;
 }
 
-
-bool
-GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
-{
-    if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
+  if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_augmented_libraries_svr4_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
-{
-    if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported() {
+  if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_libraries_svr4_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
-{
-    if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_libraries_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported() {
+  if (m_supports_qXfer_libraries_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_libraries_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
-{
-    if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_auxv_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferAuxvReadSupported() {
+  if (m_supports_qXfer_auxv_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_auxv_read == eLazyBoolYes;
 }
 
-bool
-GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported ()
-{
-    if (m_supports_qXfer_features_read == eLazyBoolCalculate)
-    {
-        GetRemoteQSupported();
-    }
-    return m_supports_qXfer_features_read == eLazyBoolYes;
+bool GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported() {
+  if (m_supports_qXfer_features_read == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_qXfer_features_read == eLazyBoolYes;
 }
 
-uint64_t
-GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
-{
-    if (m_max_packet_size == 0)
-    {
-        GetRemoteQSupported();
-    }
-    return m_max_packet_size;
+uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
+  if (m_max_packet_size == 0) {
+    GetRemoteQSupported();
+  }
+  return m_max_packet_size;
 }
 
-bool
-GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
-{
-    if (m_supports_not_sending_acks == eLazyBoolCalculate)
-    {
-        m_send_acks = true;
-        m_supports_not_sending_acks = eLazyBoolNo;
+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.
+    // This is the first real packet that we'll send in a debug session and it
+    // may take a little
+    // longer than normal to receive a reply.  Wait at least 6 seconds for a
+    // reply to this packet.
 
-        const uint32_t minimum_timeout = 6;
-        uint32_t old_timeout = GetPacketTimeoutInMicroSeconds() / lldb_private::TimeValue::MicroSecPerSec;
-        GDBRemoteCommunication::ScopedTimeout timeout (*this, std::max (old_timeout, minimum_timeout));
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-            {
-                m_send_acks = false;
-                m_supports_not_sending_acks = eLazyBoolYes;
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-void
-GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
-{
-    if (m_supports_threads_in_stop_reply == eLazyBoolCalculate)
-    {
-        m_supports_threads_in_stop_reply = eLazyBoolNo;
-        
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-                m_supports_threads_in_stop_reply = eLazyBoolYes;
-        }
-    }
-}
-
-bool
-GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
-{
-    if (m_attach_or_wait_reply == eLazyBoolCalculate)
-    {
-        m_attach_or_wait_reply = eLazyBoolNo;
-        
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-                m_attach_or_wait_reply = eLazyBoolYes;
-        }
-    }
-    if (m_attach_or_wait_reply == eLazyBoolYes)
-        return true;
-    else
-        return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
-{
-    if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate)
-    {
-        m_prepare_for_reg_writing_reply = eLazyBoolNo;
-        
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-                m_prepare_for_reg_writing_reply = eLazyBoolYes;
-        }
-    }
-    if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
-        return true;
-    else
-        return false;
-}
-
-
-void
-GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
-{
-    if (did_exec == false)
-    {
-        // Hard reset everything, this is when we first connect to a GDB server
-        m_supports_not_sending_acks = eLazyBoolCalculate;
-        m_supports_thread_suffix = eLazyBoolCalculate;
-        m_supports_threads_in_stop_reply = eLazyBoolCalculate;
-        m_supports_vCont_c = eLazyBoolCalculate;
-        m_supports_vCont_C = eLazyBoolCalculate;
-        m_supports_vCont_s = eLazyBoolCalculate;
-        m_supports_vCont_S = eLazyBoolCalculate;
-        m_supports_p = eLazyBoolCalculate;
-        m_supports_x = eLazyBoolCalculate;
-        m_supports_QSaveRegisterState = eLazyBoolCalculate;
-        m_qHostInfo_is_valid = eLazyBoolCalculate;
-        m_curr_pid_is_valid = eLazyBoolCalculate;
-        m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
-        m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
-        m_supports_memory_region_info = eLazyBoolCalculate;
-        m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
-        m_attach_or_wait_reply = eLazyBoolCalculate;
-        m_avoid_g_packets = eLazyBoolCalculate;
-        m_supports_qXfer_auxv_read = eLazyBoolCalculate;
-        m_supports_qXfer_libraries_read = eLazyBoolCalculate;
-        m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
-        m_supports_qXfer_features_read = eLazyBoolCalculate;
-        m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
-        m_supports_qProcessInfoPID = true;
-        m_supports_qfProcessInfo = true;
-        m_supports_qUserName = true;
-        m_supports_qGroupName = true;
-        m_supports_qThreadStopInfo = true;
-        m_supports_z0 = true;
-        m_supports_z1 = true;
-        m_supports_z2 = true;
-        m_supports_z3 = true;
-        m_supports_z4 = true;
-        m_supports_QEnvironment = true;
-        m_supports_QEnvironmentHexEncoded = true;
-        m_supports_qSymbol = true;
-        m_qSymbol_requests_done = false;
-        m_supports_qModuleInfo = true;
-        m_host_arch.Clear();
-        m_os_version_major = UINT32_MAX;
-        m_os_version_minor = UINT32_MAX;
-        m_os_version_update = UINT32_MAX;
-        m_os_build.clear();
-        m_os_kernel.clear();
-        m_hostname.clear();
-        m_gdb_server_name.clear();
-        m_gdb_server_version = UINT32_MAX;
-        m_default_packet_timeout = 0;
-        m_max_packet_size = 0;
-        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( ) );
-    }
+    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(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 (supported_compressions.size() > 0)
-                {
-                    MaybeEnableCompression (supported_compressions);
-                }
-            }
-        }
-
-        if (::strstr (response_cstr, "qEcho"))
-            m_supports_qEcho = eLazyBoolYes;
-        else
-            m_supports_qEcho = eLazyBoolNo;
-
-        const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
-        if (packet_size_str)
-        {
-            StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
-            m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
-            if (m_max_packet_size == 0)
-            {
-                m_max_packet_size = UINT64_MAX;  // Must have been a garbled response
-                Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-                if (log)
-                    log->Printf ("Garbled PacketSize spec in qSupported response");
-            }
-        }
+    if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) ==
+        PacketResult::Success) {
+      if (response.IsOKResponse()) {
+        m_send_acks = false;
+        m_supports_not_sending_acks = eLazyBoolYes;
+      }
+      return true;
     }
+  }
+  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;
-        }
+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;
     }
-    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;
+bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() {
+  if (m_attach_or_wait_reply == eLazyBoolCalculate) {
+    m_attach_or_wait_reply = eLazyBoolNo;
 
-            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;
-            }
-        }
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        m_attach_or_wait_reply = 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;
-    }
+  }
+  if (m_attach_or_wait_reply == eLazyBoolYes)
+    return true;
+  else
     return false;
 }
 
+bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() {
+  if (m_prepare_for_reg_writing_reply == eLazyBoolCalculate) {
+    m_prepare_for_reg_writing_reply = eLazyBoolNo;
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        m_prepare_for_reg_writing_reply = eLazyBoolYes;
+    }
+  }
+  if (m_prepare_for_reg_writing_reply == eLazyBoolYes)
+    return true;
+  else
+    return false;
+}
+
+void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
+  if (did_exec == false) {
+    // Hard reset everything, this is when we first connect to a GDB server
+    m_supports_not_sending_acks = eLazyBoolCalculate;
+    m_supports_thread_suffix = eLazyBoolCalculate;
+    m_supports_threads_in_stop_reply = eLazyBoolCalculate;
+    m_supports_vCont_c = eLazyBoolCalculate;
+    m_supports_vCont_C = eLazyBoolCalculate;
+    m_supports_vCont_s = eLazyBoolCalculate;
+    m_supports_vCont_S = eLazyBoolCalculate;
+    m_supports_p = eLazyBoolCalculate;
+    m_supports_x = eLazyBoolCalculate;
+    m_supports_QSaveRegisterState = eLazyBoolCalculate;
+    m_qHostInfo_is_valid = eLazyBoolCalculate;
+    m_curr_pid_is_valid = eLazyBoolCalculate;
+    m_qGDBServerVersion_is_valid = eLazyBoolCalculate;
+    m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
+    m_supports_memory_region_info = eLazyBoolCalculate;
+    m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
+    m_attach_or_wait_reply = eLazyBoolCalculate;
+    m_avoid_g_packets = eLazyBoolCalculate;
+    m_supports_qXfer_auxv_read = eLazyBoolCalculate;
+    m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+    m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+    m_supports_qXfer_features_read = eLazyBoolCalculate;
+    m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
+    m_supports_qProcessInfoPID = true;
+    m_supports_qfProcessInfo = true;
+    m_supports_qUserName = true;
+    m_supports_qGroupName = true;
+    m_supports_qThreadStopInfo = true;
+    m_supports_z0 = true;
+    m_supports_z1 = true;
+    m_supports_z2 = true;
+    m_supports_z3 = true;
+    m_supports_z4 = true;
+    m_supports_QEnvironment = true;
+    m_supports_QEnvironmentHexEncoded = true;
+    m_supports_qSymbol = true;
+    m_qSymbol_requests_done = false;
+    m_supports_qModuleInfo = true;
+    m_host_arch.Clear();
+    m_os_version_major = UINT32_MAX;
+    m_os_version_minor = UINT32_MAX;
+    m_os_version_update = UINT32_MAX;
+    m_os_build.clear();
+    m_os_kernel.clear();
+    m_hostname.clear();
+    m_gdb_server_name.clear();
+    m_gdb_server_version = UINT32_MAX;
+    m_default_packet_timeout = 0;
+    m_max_packet_size = 0;
+    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 (supported_compressions.size() > 0) {
+          MaybeEnableCompression(supported_compressions);
+        }
+      }
+    }
+
+    if (::strstr(response_cstr, "qEcho"))
+      m_supports_qEcho = eLazyBoolYes;
+    else
+      m_supports_qEcho = eLazyBoolNo;
+
+    const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
+    if (packet_size_str) {
+      StringExtractorGDBRemote packet_response(packet_size_str +
+                                               strlen("PacketSize="));
+      m_max_packet_size =
+          packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+      if (m_max_packet_size == 0) {
+        m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+        Log *log(
+            ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+        if (log)
+          log->Printf("Garbled PacketSize spec in qSupported response");
+      }
+    }
+  }
+}
+
+bool GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
+  if (m_supports_thread_suffix == eLazyBoolCalculate) {
+    StringExtractorGDBRemote response;
+    m_supports_thread_suffix = eLazyBoolNo;
+    if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        m_supports_thread_suffix = eLazyBoolYes;
+    }
+  }
+  return m_supports_thread_suffix;
+}
+bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
+  if (m_supports_vCont_c == eLazyBoolCalculate) {
+    StringExtractorGDBRemote response;
+    m_supports_vCont_any = eLazyBoolNo;
+    m_supports_vCont_all = eLazyBoolNo;
+    m_supports_vCont_c = eLazyBoolNo;
+    m_supports_vCont_C = eLazyBoolNo;
+    m_supports_vCont_s = eLazyBoolNo;
+    m_supports_vCont_S = eLazyBoolNo;
+    if (SendPacketAndWaitForResponse("vCont?", response, false) ==
+        PacketResult::Success) {
+      const char *response_cstr = response.GetStringRef().c_str();
+      if (::strstr(response_cstr, ";c"))
+        m_supports_vCont_c = eLazyBoolYes;
+
+      if (::strstr(response_cstr, ";C"))
+        m_supports_vCont_C = eLazyBoolYes;
+
+      if (::strstr(response_cstr, ";s"))
+        m_supports_vCont_s = eLazyBoolYes;
+
+      if (::strstr(response_cstr, ";S"))
+        m_supports_vCont_S = eLazyBoolYes;
+
+      if (m_supports_vCont_c == eLazyBoolYes &&
+          m_supports_vCont_C == eLazyBoolYes &&
+          m_supports_vCont_s == eLazyBoolYes &&
+          m_supports_vCont_S == eLazyBoolYes) {
+        m_supports_vCont_all = eLazyBoolYes;
+      }
+
+      if (m_supports_vCont_c == eLazyBoolYes ||
+          m_supports_vCont_C == eLazyBoolYes ||
+          m_supports_vCont_s == eLazyBoolYes ||
+          m_supports_vCont_S == eLazyBoolYes) {
+        m_supports_vCont_any = eLazyBoolYes;
+      }
+    }
+  }
+
+  switch (flavor) {
+  case 'a':
+    return m_supports_vCont_any;
+  case 'A':
+    return m_supports_vCont_all;
+  case 'c':
+    return m_supports_vCont_c;
+  case 'C':
+    return m_supports_vCont_C;
+  case 's':
+    return m_supports_vCont_s;
+  case 'S':
+    return m_supports_vCont_S;
+  default:
+    break;
+  }
+  return false;
+}
+
 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;
-    }
+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;
-    }
+  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 @@
 // 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;
-        }
+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;
+  }
+  return m_supports_p;
 }
 
-StructuredData::ObjectSP
-GDBRemoteCommunicationClient::GetThreadsInfo()
-{
-    // Get information on all threads at one using the "jThreadsInfo" packet
-    StructuredData::ObjectSP object_sp;
+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());
-            }
-        }
+  if (m_supports_jThreadsInfo) {
+    StringExtractorGDBRemote response;
+    response.SetResponseValidatorToJSON();
+    if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) ==
+        PacketResult::Success) {
+      if (response.IsUnsupportedResponse()) {
+        m_supports_jThreadsInfo = false;
+      } else if (!response.Empty()) {
+        object_sp = StructuredData::ParseJSON(response.GetStringRef());
+      }
     }
-    return object_sp;
+  }
+  return object_sp;
 }
 
-
-bool
-GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported ()
-{
-    if (m_supports_jThreadExtendedInfo == eLazyBoolCalculate)
-    {
-        StringExtractorGDBRemote response;
-        m_supports_jThreadExtendedInfo = eLazyBoolNo;
-        if (SendPacketAndWaitForResponse("jThreadExtendedInfo:", response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-            {
-                m_supports_jThreadExtendedInfo = eLazyBoolYes;
-            }
-        }
+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;
+  }
+  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;
-            }
-        }
+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;
+  }
+  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;
-            }
-        }
+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;
+  }
+  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;
-        }
+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;
+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;
     }
-
-    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;
-    }
+    // 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;
-                    }
-                }
-            }
-        }
+lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) {
+  if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes)
+    return m_curr_pid;
 
-        // If we don't get a response for $qC, check if $qfThreadID gives us a result.
-        if (m_curr_pid == LLDB_INVALID_PROCESS_ID)
-        {
-            std::vector<lldb::tid_t> thread_ids;
-            bool sequence_mutex_unavailable;
-            size_t size;
-            size = GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
-            if (size && sequence_mutex_unavailable == false)
-            {
-                m_curr_pid = thread_ids.front();
-                m_curr_pid_is_valid = eLazyBoolYes;
-                return m_curr_pid;
-            }
-        }
-    }
-    
-    return LLDB_INVALID_PROCESS_ID;
-}
-
-bool
-GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
-{
-    error_str.clear();
+  // 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("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);
+    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;
+          }
         }
-        else
-        {
-            error_str.assign ("unknown error occurred launching process");
-        }
+      }
     }
-    else
-    {
-        error_str.assign ("timed out waiting for app to launch");
+
+    // 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 false;
+  }
+
+  return LLDB_INVALID_PROCESS_ID;
 }
 
-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;
+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");
     }
-    if (!exe_path.empty())
-    {
-        argv.push_back(exe_path.c_str());
-        for (uint32_t i=1; (arg = launch_args.GetArgumentAtIndex(i)) != NULL; ++i)
-        {
-            if (arg)
-                argv.push_back(arg);
-        }
-    }
-    if (!argv.empty())
-    {
-        StreamString packet;
-        packet.PutChar('A');
-        for (size_t i = 0, n = argv.size(); i < n; ++i)
-        {
-            arg = argv[i];
-            const int arg_len = strlen(arg);
-            if (i > 0)
-                packet.PutChar(',');
-            packet.Printf("%i,%i,", arg_len * 2, (int)i);
-            packet.PutBytesAsRawHex8 (arg, arg_len);
-        }
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
+  } else {
+    error_str.assign("timed out waiting for app to launch");
+  }
+  return false;
 }
 
-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;
-            }
-        }
+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);
     }
-    return -1;
-}
-
-int
-GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
-{
-    if (arch && arch[0])
-    {
-        StreamString packet;
-        packet.Printf("QLaunchArch:%s", arch);
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-                return 0;
-            uint8_t error = response.GetError();
-            if (error)
-                return error;
-        }
-    }
-    return -1;
-}
-
-int
-GDBRemoteCommunicationClient::SendLaunchEventDataPacket (char const *data, bool *was_supported)
-{
-    if (data && *data != '\0')
-    {
-        StreamString packet;
-        packet.Printf("QSetProcessEvent:%s", data);
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
-        {
-            if (response.IsOKResponse())
-            {
-                if (was_supported)
-                    *was_supported = true;
-                return 0;
-            }
-            else if (response.IsUnsupportedResponse())
-            {
-                if (was_supported)
-                    *was_supported = false;
-                return -1;
-            }
-            else
-            {
-                uint8_t error = response.GetError();
-                if (was_supported)
-                    *was_supported = true;
-                if (error)
-                    return error;
-            }
-        }
-    }
-    return -1;
-}
-
-bool
-GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, 
-                                            uint32_t &minor, 
-                                            uint32_t &update)
-{
-    if (GetHostInfo ())
-    {
-        if (m_os_version_major != UINT32_MAX)
-        {
-            major = m_os_version_major;
-            minor = m_os_version_minor;
-            update = m_os_version_update;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetOSBuildString (std::string &s)
-{
-    if (GetHostInfo ())
-    {
-        if (!m_os_build.empty())
-        {
-            s = m_os_build;
-            return true;
-        }
-    }
-    s.clear();
-    return false;
-}
-
-
-bool
-GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s)
-{
-    if (GetHostInfo ())
-    {
-        if (!m_os_kernel.empty())
-        {
-            s = m_os_kernel;
-            return true;
-        }
-    }
-    s.clear();
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetHostname (std::string &s)
-{
-    if (GetHostInfo ())
-    {
-        if (!m_hostname.empty())
-        {
-            s = m_hostname;
-            return true;
-        }
-    }
-    s.clear();
-    return false;
-}
-
-ArchSpec
-GDBRemoteCommunicationClient::GetSystemArchitecture ()
-{
-    if (GetHostInfo ())
-        return m_host_arch;
-    return ArchSpec();
-}
-
-const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetProcessArchitecture ()
-{
-    if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
-        GetCurrentProcessInfo ();
-    return m_process_arch;
-}
-
-bool
-GDBRemoteCommunicationClient::GetGDBServerVersion()
-{
-    if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate)
-    {
-        m_gdb_server_name.clear();
-        m_gdb_server_version = 0;
-        m_qGDBServerVersion_is_valid = eLazyBoolNo;
-
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse ("qGDBServerVersion", response, false) == PacketResult::Success)
-        {
-            if (response.IsNormalResponse())
-            {
-                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;
-            }
-        }
-    }
-#endif
-
-#if defined (HAVE_LIBZ)
-    if (avail_type == CompressionType::None)
-    {
-        for (auto compression : supported_compressions)
-        {
-            if (compression == "zlib-deflate")
-            {
-                avail_type = CompressionType::ZlibDeflate;
-                avail_name = compression;
-                break;
-            }
-        }
-    }
-#endif
-
-#if defined (HAVE_LIBCOMPRESSION)
-    // libcompression is weak linked so test if compression_decode_buffer() is available
-    if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
-    {
-        for (auto compression : supported_compressions)
-        {
-            if (compression == "lz4")
-            {
-                avail_type = CompressionType::LZ4;
-                avail_name = compression;
-                break;
-            }
-        }
-    }
-#endif
-
-#if defined (HAVE_LIBCOMPRESSION)
-    // libcompression is weak linked so test if compression_decode_buffer() is available
-    if (compression_decode_buffer != NULL && avail_type == CompressionType::None)
-    {
-        for (auto compression : supported_compressions)
-        {
-            if (compression == "lzma")
-            {
-                avail_type = CompressionType::LZMA;
-                avail_name = compression;
-                break;
-            }
-        }
-    }
-#endif
-
-    if (avail_type != CompressionType::None)
-    {
-        StringExtractorGDBRemote response;
-        std::string packet = "QEnableCompression:type:" + avail_name + ";";
-        if (SendPacketAndWaitForResponse (packet.c_str(), response, false) !=  PacketResult::Success)
-            return;
-    
-        if (response.IsOKResponse())
-        {
-            m_compression_type = avail_type;
-        }
-    }
-}
-
-const char *
-GDBRemoteCommunicationClient::GetGDBServerProgramName()
-{
-    if (GetGDBServerVersion())
-    {
-        if (!m_gdb_server_name.empty())
-            return m_gdb_server_name.c_str();
-    }
-    return NULL;
-}
-
-uint32_t
-GDBRemoteCommunicationClient::GetGDBServerProgramVersion()
-{
-    if (GetGDBServerVersion())
-        return m_gdb_server_version;
-    return 0;
-}
-
-bool
-GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
-{
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qC",response,false) !=  PacketResult::Success)
-        return false;
-
-    if (!response.IsNormalResponse())
-        return false;
-
-    if (response.GetChar() == 'Q' && response.GetChar() == 'C')
-        tid = response.GetHexMaxU32(true, -1);
-
-    return true;
-}
-
-bool
-GDBRemoteCommunicationClient::GetHostInfo (bool force)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
-
-    if (force || m_qHostInfo_is_valid == eLazyBoolCalculate)
-    {
-        m_qHostInfo_is_valid = eLazyBoolNo;
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
-        {
-            if (response.IsNormalResponse())
-            {
-                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;
-}
-
-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)
-{
+  }
+  if (!argv.empty()) {
     StreamString packet;
-    packet.PutCString("I");
-    packet.PutBytesAsRawHex8(data, data_len);
+    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 (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(),
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
         return 0;
-    }
-    return response.GetError();
-
-}
-
-const lldb_private::ArchSpec &
-GDBRemoteCommunicationClient::GetHostArchitecture ()
-{
-    if (m_qHostInfo_is_valid == eLazyBoolCalculate)
-        GetHostInfo ();
-    return m_host_arch;
-}
-
-uint32_t
-GDBRemoteCommunicationClient::GetHostDefaultPacketTimeout ()
-{
-    if (m_qHostInfo_is_valid == eLazyBoolCalculate)
-        GetHostInfo ();
-    return m_default_packet_timeout;
-}
-
-addr_t
-GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
-{
-    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
-    {
-        m_supports_alloc_dealloc_memory = eLazyBoolYes;
-        char packet[64];
-        const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
-                                           (uint64_t)size,
-                                           permissions & lldb::ePermissionsReadable ? "r" : "",
-                                           permissions & lldb::ePermissionsWritable ? "w" : "",
-                                           permissions & lldb::ePermissionsExecutable ? "x" : "");
-        assert (packet_len < (int)sizeof(packet));
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
-        {
-            if (response.IsUnsupportedResponse())
-                m_supports_alloc_dealloc_memory = eLazyBoolNo;
-            else if (!response.IsErrorResponse())
-                return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-        }
-        else
-        {
-            m_supports_alloc_dealloc_memory = eLazyBoolNo;
-        }
-    }
-    return LLDB_INVALID_ADDRESS;
-}
-
-bool
-GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
-{
-    if (m_supports_alloc_dealloc_memory != eLazyBoolNo)
-    {
-        m_supports_alloc_dealloc_memory = eLazyBoolYes;
-        char packet[64];
-        const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
-        assert (packet_len < (int)sizeof(packet));
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
-        {
-            if (response.IsUnsupportedResponse())
-                m_supports_alloc_dealloc_memory = eLazyBoolNo;
-            else if (response.IsOKResponse())
-                return true;
-        }
-        else
-        {
-            m_supports_alloc_dealloc_memory = eLazyBoolNo;
-        }
-    }
-    return false;
-}
-
-Error
-GDBRemoteCommunicationClient::Detach (bool keep_stopped)
-{
-    Error error;
-    
-    if (keep_stopped)
-    {
-        if (m_supports_detach_stay_stopped == eLazyBoolCalculate)
-        {
-            char packet[64];
-            const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
-            assert (packet_len < (int)sizeof(packet));
-            StringExtractorGDBRemote response;
-            if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success
-                  && response.IsOKResponse())
-            {
-                m_supports_detach_stay_stopped = eLazyBoolYes;        
-            }
-            else
-            {
-                m_supports_detach_stay_stopped = eLazyBoolNo;
-            }
-        }
-
-        if (m_supports_detach_stay_stopped == eLazyBoolNo)
-        {
-            error.SetErrorString("Stays stopped not supported by this target.");
-            return error;
-        }
-        else
-        {
-            StringExtractorGDBRemote response;
-            PacketResult packet_result = SendPacketAndWaitForResponse ("D1", 2, response, false);
-            if (packet_result != PacketResult::Success)
-                error.SetErrorString ("Sending extended disconnect packet failed.");
-        }
-    }
-    else
-    {
-        StringExtractorGDBRemote response;
-        PacketResult packet_result = SendPacketAndWaitForResponse ("D", 1, response, false);
-        if (packet_result != PacketResult::Success)
-            error.SetErrorString ("Sending disconnect packet failed.");
-    }
-    return error;
-}
-
-Error
-GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, 
-                                                  lldb_private::MemoryRegionInfo &region_info)
-{
-    Error error;
-    region_info.Clear();
-
-    if (m_supports_memory_region_info != eLazyBoolNo)
-    {
-        m_supports_memory_region_info = eLazyBoolYes;
-        char packet[64];
-        const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
-        assert (packet_len < (int)sizeof(packet));
-        StringExtractorGDBRemote response;
-        if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
-        {
-            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;
+      uint8_t error = response.GetError();
+      if (error)
         return error;
     }
+  }
+  return -1;
+}
 
-    // 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;
-                }
-            }
+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
-        {
-            m_supports_watchpoint_support_info = eLazyBoolNo;
-        }
+      } else {
+        // We have non printable characters, lets hex encode this...
+        send_hex_encoding = true;
+      }
     }
 
-    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 (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())
-            return false;
-        if (response.IsErrorResponse())
-            return false;
-        std::string cwd;
-        response.GetHexByteString(cwd);
-        working_dir.SetFile(cwd, false, GetHostArchitecture());
-        return !cwd.empty();
+          m_supports_QEnvironment = false;
+      }
     }
-    return false;
+  }
+  return -1;
 }
 
-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());
+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;
+}
 
-        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::SendLaunchEventDataPacket(
+    char const *data, bool *was_supported) {
+  if (data && *data != '\0') {
+    StreamString packet;
+    packet.Printf("QSetProcessEvent:%s", data);
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(),
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse()) {
+        if (was_supported)
+          *was_supported = true;
+        return 0;
+      } else if (response.IsUnsupportedResponse()) {
+        if (was_supported)
+          *was_supported = false;
+        return -1;
+      } else {
+        uint8_t error = response.GetError();
+        if (was_supported)
+          *was_supported = true;
+        if (error)
+          return error;
+      }
+    }
+  }
+  return -1;
+}
+
+bool GDBRemoteCommunicationClient::GetOSVersion(uint32_t &major,
+                                                uint32_t &minor,
+                                                uint32_t &update) {
+  if (GetHostInfo()) {
+    if (m_os_version_major != UINT32_MAX) {
+      major = m_os_version_major;
+      minor = m_os_version_minor;
+      update = m_os_version_update;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) {
+  if (GetHostInfo()) {
+    if (!m_os_build.empty()) {
+      s = m_os_build;
+      return true;
+    }
+  }
+  s.clear();
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) {
+  if (GetHostInfo()) {
+    if (!m_os_kernel.empty()) {
+      s = m_os_kernel;
+      return true;
+    }
+  }
+  s.clear();
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::GetHostname(std::string &s) {
+  if (GetHostInfo()) {
+    if (!m_hostname.empty()) {
+      s = m_hostname;
+      return true;
+    }
+  }
+  s.clear();
+  return false;
+}
+
+ArchSpec GDBRemoteCommunicationClient::GetSystemArchitecture() {
+  if (GetHostInfo())
+    return m_host_arch;
+  return ArchSpec();
+}
+
+const lldb_private::ArchSpec &
+GDBRemoteCommunicationClient::GetProcessArchitecture() {
+  if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+    GetCurrentProcessInfo();
+  return m_process_arch;
+}
+
+bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
+  if (m_qGDBServerVersion_is_valid == eLazyBoolCalculate) {
+    m_gdb_server_name.clear();
+    m_gdb_server_version = 0;
+    m_qGDBServerVersion_is_valid = eLazyBoolNo;
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse("qGDBServerVersion", response, false) ==
+        PacketResult::Success) {
+      if (response.IsNormalResponse()) {
+        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 -1;
+  }
+  return m_qGDBServerVersion_is_valid == eLazyBoolYes;
 }
 
-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));
+void GDBRemoteCommunicationClient::MaybeEnableCompression(
+    std::vector<std::string> supported_compressions) {
+  CompressionType avail_type = CompressionType::None;
+  std::string avail_name;
+
+#if defined(HAVE_LIBCOMPRESSION)
+  // libcompression is weak linked so test if compression_decode_buffer() is
+  // available
+  if (compression_decode_buffer != NULL &&
+      avail_type == CompressionType::None) {
+    for (auto compression : supported_compressions) {
+      if (compression == "lzfse") {
+        avail_type = CompressionType::LZFSE;
+        avail_name = compression;
+        break;
+      }
+    }
+  }
+#endif
+
+#if defined(HAVE_LIBCOMPRESSION)
+  // libcompression is weak linked so test if compression_decode_buffer() is
+  // available
+  if (compression_decode_buffer != NULL &&
+      avail_type == CompressionType::None) {
+    for (auto compression : supported_compressions) {
+      if (compression == "zlib-deflate") {
+        avail_type = CompressionType::ZlibDeflate;
+        avail_name = compression;
+        break;
+      }
+    }
+  }
+#endif
+
+#if defined(HAVE_LIBZ)
+  if (avail_type == CompressionType::None) {
+    for (auto compression : supported_compressions) {
+      if (compression == "zlib-deflate") {
+        avail_type = CompressionType::ZlibDeflate;
+        avail_name = compression;
+        break;
+      }
+    }
+  }
+#endif
+
+#if defined(HAVE_LIBCOMPRESSION)
+  // libcompression is weak linked so test if compression_decode_buffer() is
+  // available
+  if (compression_decode_buffer != NULL &&
+      avail_type == CompressionType::None) {
+    for (auto compression : supported_compressions) {
+      if (compression == "lz4") {
+        avail_type = CompressionType::LZ4;
+        avail_name = compression;
+        break;
+      }
+    }
+  }
+#endif
+
+#if defined(HAVE_LIBCOMPRESSION)
+  // libcompression is weak linked so test if compression_decode_buffer() is
+  // available
+  if (compression_decode_buffer != NULL &&
+      avail_type == CompressionType::None) {
+    for (auto compression : supported_compressions) {
+      if (compression == "lzma") {
+        avail_type = CompressionType::LZMA;
+        avail_name = compression;
+        break;
+      }
+    }
+  }
+#endif
+
+  if (avail_type != CompressionType::None) {
     StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-            return 0;
-        uint8_t error = response.GetError();
-        if (error)
-            return error;
+    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;
     }
-    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));
+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 (packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-            return 0;
-        uint8_t error = response.GetError();
-        if (error)
-            return error;
-    }
-    return -1;
-}
-
-
-bool
-GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info)
-{
-    if (response.IsNormalResponse())
-    {
+    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);
+        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;
             }
-            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 (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;
-                }
+            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;
             }
-            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;
-            }
+            m_host_arch.SetTriple(triple.c_str());
 
-            // 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
-            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;
-}
-
-size_t
-GDBRemoteCommunicationClient::QueryGDBServer (std::vector<std::pair<uint16_t, std::string>>& connection_urls)
-{
-    connection_urls.clear();
-
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) != PacketResult::Success)
-        return 0;
-
-    StructuredData::ObjectSP data = StructuredData::ParseJSON(response.GetStringRef());
-    if (!data)
-        return 0;
-
-    StructuredData::Array* array = data->GetAsArray();
-    if (!array)
-        return 0;
-
-    for (size_t i = 0, count = array->GetSize(); i < count; ++i)
-    {
-        StructuredData::Dictionary* element = nullptr;
-        if (!array->GetItemAtIndexAsDictionary(i, element))
-            continue;
-
-        uint16_t port = 0;
-        if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port")))
-            port = port_osp->GetIntegerValue(0);
-
-        std::string socket_name;
-        if (StructuredData::ObjectSP socket_name_osp = element->GetValueForKey(llvm::StringRef("socket_name")))
-            socket_name = socket_name_osp->GetStringValue();
-
-        if (port != 0 || !socket_name.empty())
-            connection_urls.emplace_back(port, socket_name);
-    }
-    return connection_urls.size();
-}
-
-bool
-GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
-{
-    StreamString stream;
-    stream.Printf ("qKillSpawnedProcess:%" PRId64 , pid);
-    const char *packet = stream.GetData();
-    int packet_len = stream.GetSize();
-
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-            return true;
-    }
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
-{
-    if (m_curr_tid == tid)
-        return true;
-
-    char packet[32];
-    int packet_len;
-    if (tid == UINT64_MAX)
-        packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
-    else
-        packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
-    assert (packet_len + 1 < (int)sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-        {
-            m_curr_tid = tid;
-            return true;
-        }
-
-        /*
-         * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hg packet.
-         * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
-         * give us pid and/or tid. Assume pid=tid=1 in such cases.
-        */
-        if (response.IsUnsupportedResponse() && IsConnected())
-        {
-            m_curr_tid = 1;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
-{
-    if (m_curr_tid_run == tid)
-        return true;
-
-    char packet[32];
-    int packet_len;
-    if (tid == UINT64_MAX)
-        packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
-    else
-        packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
-
-    assert (packet_len + 1 < (int)sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-        {
-            m_curr_tid_run = tid;
-            return true;
-        }
-
-        /*
-         * Connected bare-iron target (like YAMON gdb-stub) may not have support for Hc packet.
-         * The reply from '?' packet could be as simple as 'S05'. There is no packet which can
-         * give us pid and/or tid. Assume pid=tid=1 in such cases.
-        */
-        if (response.IsUnsupportedResponse() && IsConnected())
-        {
-            m_curr_tid_run = 1;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
-{
-    if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
-        return response.IsNormalResponse();
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtractorGDBRemote &response)
-{
-    if (m_supports_qThreadStopInfo)
-    {
-        char packet[256];
-        int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
-        assert (packet_len < (int)sizeof(packet));
-        if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-        {
-            if (response.IsUnsupportedResponse())
-                m_supports_qThreadStopInfo = false;
-            else if (response.IsNormalResponse())
-                return true;
-            else
-                return false;
-        }
-        else
-        {
-            m_supports_qThreadStopInfo = false;
-        }
-    }
-    return false;
-}
-
-
-uint8_t
-GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert,  addr_t addr, uint32_t length)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
-                     __FUNCTION__, insert ? "add" : "remove", addr);
-
-    // Check if the stub is known not to support this breakpoint type
-    if (!SupportsGDBStoppointPacket(type))
-        return UINT8_MAX;
-    // Construct the breakpoint packet
-    char packet[64];
-    const int packet_len = ::snprintf (packet, 
-                                       sizeof(packet), 
-                                       "%c%i,%" PRIx64 ",%x",
-                                       insert ? 'Z' : 'z', 
-                                       type, 
-                                       addr, 
-                                       length);
-    // Check we haven't overwritten the end of the packet buffer
-    assert (packet_len + 1 < (int)sizeof(packet));
-    StringExtractorGDBRemote response;
-    // Make sure the response is either "OK", "EXX" where XX are two hex digits, or "" (unsupported)
-    response.SetResponseValidatorToOKErrorNotSupported();
-    // Try to send the breakpoint packet, and check that it was correctly sent
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
-    {
-        // Receive and OK packet when the breakpoint successfully placed
-        if (response.IsOKResponse())
-            return 0;
-
-        // Error while setting breakpoint, send back specific error
-        if (response.IsErrorResponse())
-            return response.GetError();
-
-        // Empty packet informs us that breakpoint is not supported
-        if (response.IsUnsupportedResponse())
-        {
-            // Disable this breakpoint type since it is unsupported
-            switch (type)
-            {
-            case eBreakpointSoftware:   m_supports_z0 = false; break;
-            case eBreakpointHardware:   m_supports_z1 = false; break;
-            case eWatchpointWrite:      m_supports_z2 = false; break;
-            case eWatchpointRead:       m_supports_z3 = false; break;
-            case eWatchpointReadWrite:  m_supports_z4 = false; break;
-            case eStoppointInvalid:     return UINT8_MAX;
-            }
-        }
-    }
-    // Signal generic failure
-    return UINT8_MAX;
-}
-
-size_t
-GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids, 
-                                                   bool &sequence_mutex_unavailable)
-{
-    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')
+            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;
-            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
+              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());
+          }
 
-        /*
-         * 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);
+          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());
+      }
     }
-    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();
+  }
+  return m_qHostInfo_is_valid == eLazyBoolYes;
 }
 
-lldb::addr_t
-GDBRemoteCommunicationClient::GetShlibInfoAddr()
-{
+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("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) {
+      if (response.IsUnsupportedResponse())
+        m_supports_alloc_dealloc_memory = eLazyBoolNo;
+      else if (!response.IsErrorResponse())
+        return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+    } else {
+      m_supports_alloc_dealloc_memory = eLazyBoolNo;
+    }
+  }
+  return LLDB_INVALID_ADDRESS;
+}
+
+bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) {
+  if (m_supports_alloc_dealloc_memory != eLazyBoolNo) {
+    m_supports_alloc_dealloc_memory = eLazyBoolYes;
+    char packet[64];
+    const int packet_len =
+        ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
+    assert(packet_len < (int)sizeof(packet));
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+        PacketResult::Success) {
+      if (response.IsUnsupportedResponse())
+        m_supports_alloc_dealloc_memory = eLazyBoolNo;
+      else if (response.IsOKResponse())
+        return true;
+    } else {
+      m_supports_alloc_dealloc_memory = eLazyBoolNo;
+    }
+  }
+  return false;
+}
+
+Error GDBRemoteCommunicationClient::Detach(bool keep_stopped) {
+  Error error;
+
+  if (keep_stopped) {
+    if (m_supports_detach_stay_stopped == eLazyBoolCalculate) {
+      char packet[64];
+      const int packet_len =
+          ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
+      assert(packet_len < (int)sizeof(packet));
+      StringExtractorGDBRemote response;
+      if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+              PacketResult::Success &&
+          response.IsOKResponse()) {
+        m_supports_detach_stay_stopped = eLazyBoolYes;
+      } else {
+        m_supports_detach_stay_stopped = eLazyBoolNo;
+      }
+    }
+
+    if (m_supports_detach_stay_stopped == eLazyBoolNo) {
+      error.SetErrorString("Stays stopped not supported by this target.");
+      return error;
+    } else {
+      StringExtractorGDBRemote response;
+      PacketResult packet_result =
+          SendPacketAndWaitForResponse("D1", 2, response, false);
+      if (packet_result != PacketResult::Success)
+        error.SetErrorString("Sending extended disconnect packet failed.");
+    }
+  } else {
+    StringExtractorGDBRemote response;
+    PacketResult packet_result =
+        SendPacketAndWaitForResponse("D", 1, response, false);
+    if (packet_result != PacketResult::Success)
+      error.SetErrorString("Sending disconnect packet failed.");
+  }
+  return error;
+}
+
+Error GDBRemoteCommunicationClient::GetMemoryRegionInfo(
+    lldb::addr_t addr, lldb_private::MemoryRegionInfo &region_info) {
+  Error error;
+  region_info.Clear();
+
+  if (m_supports_memory_region_info != eLazyBoolNo) {
+    m_supports_memory_region_info = eLazyBoolYes;
+    char packet[64];
+    const int packet_len = ::snprintf(
+        packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
+    assert(packet_len < (int)sizeof(packet));
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+        PacketResult::Success) {
+      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::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");
-}
+GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction(
+    bool &after, const ArchSpec &arch) {
+  Error error;
+  llvm::Triple::ArchType atype = arch.GetMachine();
 
-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);
-    }
+  // 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
-        error.Clear();
-    return  result;
+      after = true;
+  } else {
+    // For MIPS, set m_watchpoints_trigger_after_instruction to eLazyBoolNo
+    // if it is not calculated before.
+    if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate &&
+        (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel ||
+         atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el))
+      m_watchpoints_trigger_after_instruction = eLazyBoolNo;
+
+    after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo);
+  }
+  return error;
+}
+
+int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) {
+  if (file_spec) {
+    std::string path{file_spec.GetPath(false)};
+    StreamString packet;
+    packet.PutCString("QSetSTDIN:");
+    packet.PutCStringAsRawHex8(path.c_str());
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(),
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        return 0;
+      uint8_t error = response.GetError();
+      if (error)
+        return error;
+    }
+  }
+  return -1;
+}
+
+int GDBRemoteCommunicationClient::SetSTDOUT(const FileSpec &file_spec) {
+  if (file_spec) {
+    std::string path{file_spec.GetPath(false)};
+    StreamString packet;
+    packet.PutCString("QSetSTDOUT:");
+    packet.PutCStringAsRawHex8(path.c_str());
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(),
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        return 0;
+      uint8_t error = response.GetError();
+      if (error)
+        return error;
+    }
+  }
+  return -1;
+}
+
+int GDBRemoteCommunicationClient::SetSTDERR(const FileSpec &file_spec) {
+  if (file_spec) {
+    std::string path{file_spec.GetPath(false)};
+    StreamString packet;
+    packet.PutCString("QSetSTDERR:");
+    packet.PutCStringAsRawHex8(path.c_str());
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(),
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        return 0;
+      uint8_t error = response.GetError();
+      if (error)
+        return error;
+    }
+  }
+  return -1;
+}
+
+bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) {
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse("qGetWorkingDir", response, false) ==
+      PacketResult::Success) {
+    if (response.IsUnsupportedResponse())
+      return false;
+    if (response.IsErrorResponse())
+      return false;
+    std::string cwd;
+    response.GetHexByteString(cwd);
+    working_dir.SetFile(cwd, false, GetHostArchitecture());
+    return !cwd.empty();
+  }
+  return false;
+}
+
+int GDBRemoteCommunicationClient::SetWorkingDir(const FileSpec &working_dir) {
+  if (working_dir) {
+    std::string path{working_dir.GetPath(false)};
+    StreamString packet;
+    packet.PutCString("QSetWorkingDir:");
+    packet.PutCStringAsRawHex8(path.c_str());
+
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(),
+                                     response,
+                                     false) == PacketResult::Success) {
+      if (response.IsOKResponse())
+        return 0;
+      uint8_t error = response.GetError();
+      if (error)
+        return error;
+    }
+  }
+  return -1;
+}
+
+int GDBRemoteCommunicationClient::SetDisableASLR(bool enable) {
+  char packet[32];
+  const int packet_len =
+      ::snprintf(packet, sizeof(packet), "QSetDisableASLR:%i", enable ? 1 : 0);
+  assert(packet_len < (int)sizeof(packet));
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.IsOKResponse())
+      return 0;
+    uint8_t error = response.GetError();
+    if (error)
+      return error;
+  }
+  return -1;
+}
+
+int GDBRemoteCommunicationClient::SetDetachOnError(bool enable) {
+  char packet[32];
+  const int packet_len = ::snprintf(packet, sizeof(packet),
+                                    "QSetDetachOnError:%i", enable ? 1 : 0);
+  assert(packet_len < (int)sizeof(packet));
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.IsOKResponse())
+      return 0;
+    uint8_t error = response.GetError();
+    if (error)
+      return error;
+  }
+  return -1;
+}
+
+bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse(
+    StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) {
+  if (response.IsNormalResponse()) {
+    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) {
+      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
+      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;
+}
+
+size_t GDBRemoteCommunicationClient::QueryGDBServer(
+    std::vector<std::pair<uint16_t, std::string>> &connection_urls) {
+  connection_urls.clear();
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse("qQueryGDBServer", response, false) !=
+      PacketResult::Success)
+    return 0;
+
+  StructuredData::ObjectSP data =
+      StructuredData::ParseJSON(response.GetStringRef());
+  if (!data)
+    return 0;
+
+  StructuredData::Array *array = data->GetAsArray();
+  if (!array)
+    return 0;
+
+  for (size_t i = 0, count = array->GetSize(); i < count; ++i) {
+    StructuredData::Dictionary *element = nullptr;
+    if (!array->GetItemAtIndexAsDictionary(i, element))
+      continue;
+
+    uint16_t port = 0;
+    if (StructuredData::ObjectSP port_osp =
+            element->GetValueForKey(llvm::StringRef("port")))
+      port = port_osp->GetIntegerValue(0);
+
+    std::string socket_name;
+    if (StructuredData::ObjectSP socket_name_osp =
+            element->GetValueForKey(llvm::StringRef("socket_name")))
+      socket_name = socket_name_osp->GetStringValue();
+
+    if (port != 0 || !socket_name.empty())
+      connection_urls.emplace_back(port, socket_name);
+  }
+  return connection_urls.size();
+}
+
+bool GDBRemoteCommunicationClient::KillSpawnedProcess(lldb::pid_t pid) {
+  StreamString stream;
+  stream.Printf("qKillSpawnedProcess:%" PRId64, pid);
+  const char *packet = stream.GetData();
+  int packet_len = stream.GetSize();
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.IsOKResponse())
+      return true;
+  }
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::SetCurrentThread(uint64_t tid) {
+  if (m_curr_tid == tid)
+    return true;
+
+  char packet[32];
+  int packet_len;
+  if (tid == UINT64_MAX)
+    packet_len = ::snprintf(packet, sizeof(packet), "Hg-1");
+  else
+    packet_len = ::snprintf(packet, sizeof(packet), "Hg%" PRIx64, tid);
+  assert(packet_len + 1 < (int)sizeof(packet));
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.IsOKResponse()) {
+      m_curr_tid = tid;
+      return true;
+    }
+
+    /*
+     * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+     * Hg packet.
+     * The reply from '?' packet could be as simple as 'S05'. There is no packet
+     * which can
+     * give us pid and/or tid. Assume pid=tid=1 in such cases.
+    */
+    if (response.IsUnsupportedResponse() && IsConnected()) {
+      m_curr_tid = 1;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::SetCurrentThreadForRun(uint64_t tid) {
+  if (m_curr_tid_run == tid)
+    return true;
+
+  char packet[32];
+  int packet_len;
+  if (tid == UINT64_MAX)
+    packet_len = ::snprintf(packet, sizeof(packet), "Hc-1");
+  else
+    packet_len = ::snprintf(packet, sizeof(packet), "Hc%" PRIx64, tid);
+
+  assert(packet_len + 1 < (int)sizeof(packet));
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.IsOKResponse()) {
+      m_curr_tid_run = tid;
+      return true;
+    }
+
+    /*
+     * Connected bare-iron target (like YAMON gdb-stub) may not have support for
+     * Hc packet.
+     * The reply from '?' packet could be as simple as 'S05'. There is no packet
+     * which can
+     * give us pid and/or tid. Assume pid=tid=1 in such cases.
+    */
+    if (response.IsUnsupportedResponse() && IsConnected()) {
+      m_curr_tid_run = 1;
+      return true;
+    }
+  }
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::GetStopReply(
+    StringExtractorGDBRemote &response) {
+  if (SendPacketAndWaitForResponse("?", 1, response, false) ==
+      PacketResult::Success)
+    return response.IsNormalResponse();
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::GetThreadStopInfo(
+    lldb::tid_t tid, StringExtractorGDBRemote &response) {
+  if (m_supports_qThreadStopInfo) {
+    char packet[256];
+    int packet_len =
+        ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
+    assert(packet_len < (int)sizeof(packet));
+    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+        PacketResult::Success) {
+      if (response.IsUnsupportedResponse())
+        m_supports_qThreadStopInfo = false;
+      else if (response.IsNormalResponse())
+        return true;
+      else
+        return false;
+    } else {
+      m_supports_qThreadStopInfo = false;
+    }
+  }
+  return false;
+}
+
+uint8_t GDBRemoteCommunicationClient::SendGDBStoppointTypePacket(
+    GDBStoppointType type, bool insert, addr_t addr, uint32_t length) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationClient::%s() %s at addr = 0x%" PRIx64,
+                __FUNCTION__, insert ? "add" : "remove", addr);
+
+  // Check if the stub is known not to support this breakpoint type
+  if (!SupportsGDBStoppointPacket(type))
+    return UINT8_MAX;
+  // Construct the breakpoint packet
+  char packet[64];
+  const int packet_len =
+      ::snprintf(packet, sizeof(packet), "%c%i,%" PRIx64 ",%x",
+                 insert ? 'Z' : 'z', type, addr, length);
+  // Check we haven't overwritten the end of the packet buffer
+  assert(packet_len + 1 < (int)sizeof(packet));
+  StringExtractorGDBRemote response;
+  // Make sure the response is either "OK", "EXX" where XX are two hex digits,
+  // or "" (unsupported)
+  response.SetResponseValidatorToOKErrorNotSupported();
+  // Try to send the breakpoint packet, and check that it was correctly sent
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, true) ==
+      PacketResult::Success) {
+    // Receive and OK packet when the breakpoint successfully placed
+    if (response.IsOKResponse())
+      return 0;
+
+    // Error while setting breakpoint, send back specific error
+    if (response.IsErrorResponse())
+      return response.GetError();
+
+    // Empty packet informs us that breakpoint is not supported
+    if (response.IsUnsupportedResponse()) {
+      // Disable this breakpoint type since it is unsupported
+      switch (type) {
+      case eBreakpointSoftware:
+        m_supports_z0 = false;
+        break;
+      case eBreakpointHardware:
+        m_supports_z1 = false;
+        break;
+      case eWatchpointWrite:
+        m_supports_z2 = false;
+        break;
+      case eWatchpointRead:
+        m_supports_z3 = false;
+        break;
+      case eWatchpointReadWrite:
+        m_supports_z4 = false;
+        break;
+      case eStoppointInvalid:
+        return UINT8_MAX;
+      }
+    }
+  }
+  // Signal generic failure
+  return UINT8_MAX;
+}
+
+size_t GDBRemoteCommunicationClient::GetCurrentThreadIDs(
+    std::vector<lldb::tid_t> &thread_ids, bool &sequence_mutex_unavailable) {
+  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();
+}
+
+lldb::addr_t GDBRemoteCommunicationClient::GetShlibInfoAddr() {
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse("qShlibInfoAddr", response, false) !=
+          PacketResult::Success ||
+      !response.IsNormalResponse())
+    return LLDB_INVALID_ADDRESS;
+  return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+}
+
+lldb_private::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);
-    }
+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;
+bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd, Error &error) {
+  lldb_private::StreamString stream;
+  stream.Printf("vFile:close:%i", (int)fd);
+  const char *packet = stream.GetData();
+  int packet_len = stream.GetSize();
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    return ParseHostIOPacketResponse(response, -1, error) == 0;
+  }
+  return false;
 }
 
 // Extension of host I/O packets to get the file size.
-lldb::user_id_t
-GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_spec)
-{
-    std::string path(file_spec.GetPath(false));
-    lldb_private::StreamString stream;
-    stream.PutCString("vFile:size:");
-    stream.PutCStringAsRawHex8(path.c_str());
-    const char* packet = stream.GetData();
-    int packet_len = stream.GetSize();
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.GetChar() != 'F')
-            return UINT64_MAX;
-        uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX);
-        return retcode;
-    }
-    return UINT64_MAX;
+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 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();
-            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.SetErrorToGenericError();
+      } else {
+        file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO);
+      }
     }
-    else
-    {
-        error.SetErrorString ("failed to send vFile:pwrite packet");
-    }
-    return 0;
+  } else {
+    error.SetErrorStringWithFormat("failed to send '%s' packet", packet);
+  }
+  return error;
 }
 
-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");
-        }
+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;
+      }
     }
-    else
-    {
-        error.SetErrorString ("failed to send vFile:symlink packet");
-    }
-    return error;
+  }
+  return 0;
 }
 
-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");
-        }
+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;
     }
-    else
-    {
-        error.SetErrorString ("failed to send vFile:unlink packet");
+    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 error;
+    return bytes_written;
+  } else {
+    error.SetErrorString("failed to send vFile:pwrite packet");
+  }
+  return 0;
+}
+
+Error GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src,
+                                                  const FileSpec &dst) {
+  std::string src_path{src.GetPath(false)}, dst_path{dst.GetPath(false)};
+  Error error;
+  lldb_private::StreamGDBRemote stream;
+  stream.PutCString("vFile:symlink:");
+  // the unix symlink() command reverses its parameters where the dst if first,
+  // so we follow suit here
+  stream.PutCStringAsRawHex8(dst_path.c_str());
+  stream.PutChar(',');
+  stream.PutCStringAsRawHex8(src_path.c_str());
+  const char *packet = stream.GetData();
+  int packet_len = stream.GetSize();
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.GetChar() == 'F') {
+      uint32_t result = response.GetU32(UINT32_MAX);
+      if (result != 0) {
+        error.SetErrorToGenericError();
+        if (response.GetChar() == ',') {
+          int response_errno = response.GetS32(-1);
+          if (response_errno > 0)
+            error.SetError(response_errno, lldb::eErrorTypePOSIX);
+        }
+      }
+    } else {
+      // Should have returned with 'F<result>[,<errno>]'
+      error.SetErrorStringWithFormat("symlink failed");
+    }
+  } else {
+    error.SetErrorString("failed to send vFile:symlink packet");
+  }
+  return error;
+}
+
+Error GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) {
+  std::string path{file_spec.GetPath(false)};
+  Error error;
+  lldb_private::StreamGDBRemote stream;
+  stream.PutCString("vFile:unlink:");
+  // the unix symlink() command reverses its parameters where the dst if first,
+  // so we follow suit here
+  stream.PutCStringAsRawHex8(path.c_str());
+  const char *packet = stream.GetData();
+  int packet_len = stream.GetSize();
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.GetChar() == 'F') {
+      uint32_t result = response.GetU32(UINT32_MAX);
+      if (result != 0) {
+        error.SetErrorToGenericError();
+        if (response.GetChar() == ',') {
+          int response_errno = response.GetS32(-1);
+          if (response_errno > 0)
+            error.SetError(response_errno, lldb::eErrorTypePOSIX);
+        }
+      }
+    } else {
+      // Should have returned with 'F<result>[,<errno>]'
+      error.SetErrorStringWithFormat("unlink failed");
+    }
+  } else {
+    error.SetErrorString("failed to send vFile:unlink packet");
+  }
+  return error;
 }
 
 // Extension of host I/O packets to get whether a file exists.
-bool
-GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_spec)
-{
-    std::string path(file_spec.GetPath(false));
-    lldb_private::StreamString stream;
-    stream.PutCString("vFile:exists:");
-    stream.PutCStringAsRawHex8(path.c_str());
-    const char* packet = stream.GetData();
-    int packet_len = stream.GetSize();
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.GetChar() != 'F')
-            return false;
-        if (response.GetChar() != ',')
-            return false;
-        bool retcode = (response.GetChar() != '0');
-        return retcode;
-    }
-    return false;
+bool GDBRemoteCommunicationClient::GetFileExists(
+    const lldb_private::FileSpec &file_spec) {
+  std::string path(file_spec.GetPath(false));
+  lldb_private::StreamString stream;
+  stream.PutCString("vFile:exists:");
+  stream.PutCStringAsRawHex8(path.c_str());
+  const char *packet = stream.GetData();
+  int packet_len = stream.GetSize();
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet, packet_len, response, false) ==
+      PacketResult::Success) {
+    if (response.GetChar() != 'F')
+      return false;
+    if (response.GetChar() != ',')
+      return false;
+    bool retcode = (response.GetChar() != '0');
+    return retcode;
+  }
+  return false;
 }
 
-bool
-GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_spec,
-                                            uint64_t &high,
-                                            uint64_t &low)
-{
-    std::string path(file_spec.GetPath(false));
-    lldb_private::StreamString stream;
-    stream.PutCString("vFile:MD5:");
-    stream.PutCStringAsRawHex8(path.c_str());
-    const char* packet = stream.GetData();
-    int packet_len = stream.GetSize();
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
-    {
-        if (response.GetChar() != 'F')
-            return false;
-        if (response.GetChar() != ',')
-            return false;
-        if (response.Peek() && *response.Peek() == 'x')
-            return false;
-        low = response.GetHexMaxU64(false, UINT64_MAX);
-        high = response.GetHexMaxU64(false, UINT64_MAX);
-        return true;
-    }
-    return false;
-}
-
-bool
-GDBRemoteCommunicationClient::AvoidGPackets (ProcessGDBRemote *process)
-{
-    // Some targets have issues with g/G packets and we need to avoid using them
-    if (m_avoid_g_packets == eLazyBoolCalculate)
-    {
-        if (process)
-        {
-            m_avoid_g_packets = eLazyBoolNo;
-            const ArchSpec &arch = process->GetTarget().GetArchitecture();
-            if (arch.IsValid()
-                && arch.GetTriple().getVendor() == llvm::Triple::Apple
-                && arch.GetTriple().getOS() == llvm::Triple::IOS
-                && arch.GetTriple().getArch() == llvm::Triple::aarch64)
-            {
-                m_avoid_g_packets = eLazyBoolYes;
-                uint32_t gdb_server_version = GetGDBServerProgramVersion();
-                if (gdb_server_version != 0)
-                {
-                    const char *gdb_server_name = GetGDBServerProgramName();
-                    if (gdb_server_name && strcmp(gdb_server_name, "debugserver") == 0)
-                    {
-                        if (gdb_server_version >= 310)
-                            m_avoid_g_packets = eLazyBoolNo;
-                    }
-                }
-            }
-        }
-    }
-    return m_avoid_g_packets == eLazyBoolYes;
-}
-
-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;
+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;
+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;
+}
 
-    StreamString payload;
-    payload.Printf("QRestoreRegisterState:%u", save_id);
-    StringExtractorGDBRemote response;
-    if (SendThreadSpecificPacketAndWaitForResponse(tid, std::move(payload), response, false) != PacketResult::Success)
-        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;
 
-    if (response.IsOKResponse())
-        return true;
+  DataBufferSP buffer_sp(
+      new DataBufferHeap(response.GetStringRef().size() / 2, 0));
+  response.GetHexBytes(buffer_sp->GetData(), '\xcc');
+  return buffer_sp;
+}
 
-    if (response.IsUnsupportedResponse())
-        m_supports_QSaveRegisterState = eLazyBoolNo;
+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::SyncThreadState(lldb::tid_t tid)
-{
-    if (!GetSyncThreadStateSupported())
-        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 packet;
-    StringExtractorGDBRemote response;
-    packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
-    return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
-               GDBRemoteCommunication::PacketResult::Success &&
-           response.IsOKResponse();
-}
+  StreamString payload;
+  payload.Printf("QRestoreRegisterState:%u", save_id);
+  StringExtractorGDBRemote response;
+  if (SendThreadSpecificPacketAndWaitForResponse(
+          tid, std::move(payload), response, false) != PacketResult::Success)
+    return false;
 
-bool
-GDBRemoteCommunicationClient::GetModuleInfo(const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
-                                            ModuleSpec &module_spec)
-{
-    if (!m_supports_qModuleInfo)
-        return false;
-
-    std::string module_path = module_file_spec.GetPath (false);
-    if (module_path.empty ())
-        return false;
-
-    StreamString packet;
-    packet.PutCString("qModuleInfo:");
-    packet.PutCStringAsRawHex8(module_path.c_str());
-    packet.PutCString(";");
-    const auto& triple = arch_spec.GetTriple().getTriple();
-    packet.PutCStringAsRawHex8(triple.c_str());
-
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)
-        return false;
-
-    if (response.IsErrorResponse ())
-        return false;
-
-    if (response.IsUnsupportedResponse ())
-    {
-        m_supports_qModuleInfo = false;
-        return false;
-    }
-
-    llvm::StringRef name;
-    llvm::StringRef value;
-
-    module_spec.Clear ();
-    module_spec.GetFileSpec () = module_file_spec;
-
-    while (response.GetNameColonValue (name, value))
-    {
-        if (name == "uuid" || name == "md5")
-        {
-            StringExtractor extractor(value);
-            std::string uuid;
-            extractor.GetHexByteString(uuid);
-            module_spec.GetUUID().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);
-        }
-    }
-
+  if (response.IsOKResponse())
     return true;
+
+  if (response.IsUnsupportedResponse())
+    m_supports_QSaveRegisterState = eLazyBoolNo;
+  return false;
+}
+
+bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
+  if (!GetSyncThreadStateSupported())
+    return false;
+
+  StreamString packet;
+  StringExtractorGDBRemote response;
+  packet.Printf("QSyncThreadState:%4.4" PRIx64 ";", tid);
+  return SendPacketAndWaitForResponse(packet.GetString(), response, false) ==
+             GDBRemoteCommunication::PacketResult::Success &&
+         response.IsOKResponse();
+}
+
+bool GDBRemoteCommunicationClient::GetModuleInfo(
+    const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
+    ModuleSpec &module_spec) {
+  if (!m_supports_qModuleInfo)
+    return false;
+
+  std::string module_path = module_file_spec.GetPath(false);
+  if (module_path.empty())
+    return false;
+
+  StreamString packet;
+  packet.PutCString("qModuleInfo:");
+  packet.PutCStringAsRawHex8(module_path.c_str());
+  packet.PutCString(";");
+  const auto &triple = arch_spec.GetTriple().getTriple();
+  packet.PutCStringAsRawHex8(triple.c_str());
+
+  StringExtractorGDBRemote response;
+  if (SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response,
+                                   false) != PacketResult::Success)
+    return false;
+
+  if (response.IsErrorResponse())
+    return false;
+
+  if (response.IsUnsupportedResponse()) {
+    m_supports_qModuleInfo = false;
+    return false;
+  }
+
+  llvm::StringRef name;
+  llvm::StringRef value;
+
+  module_spec.Clear();
+  module_spec.GetFileSpec() = module_file_spec;
+
+  while (response.GetNameColonValue(name, value)) {
+    if (name == "uuid" || name == "md5") {
+      StringExtractor extractor(value);
+      std::string uuid;
+      extractor.GetHexByteString(uuid);
+      module_spec.GetUUID().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;
 }
 
 // query the target remote for extended information using the qXfer packet
@@ -3667,368 +3237,342 @@
 // 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) {
+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;
+  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;
+  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 ) {
+  // 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;
+    // 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 );
+    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;
-        }
+    if (res != GDBRemoteCommunication::PacketResult::Success) {
+      err.SetErrorString("Error sending $qXfer packet");
+      return false;
     }
 
-    out = output.str( );
-    err.Success( );
-    return true;
+    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;
+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;
+  // 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;
+  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;
+                      }
                     }
-
-                    // We are done serving symbols requests
-                    return;
+                  }
                 }
-                first_qsymbol_query = false;
+              }
+              // 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.
 
-                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
-                        }
-                    }
-                }
+              // 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;
+          }
+        }
+      }
+      // 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__);
-        }
+    } 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;
+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));
+    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;
-
-    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());
-        }
+    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__);
     }
-    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);
+
+    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 error;
+  }
+
+  return m_supported_async_json_packets_sp
+             ? m_supported_async_json_packets_sp->GetAsArray()
+             : nullptr;
 }
 
-void
-GDBRemoteCommunicationClient::OnRunPacketSent(bool first)
-{
-    GDBRemoteClientBase::OnRunPacketSent(first);
-    m_curr_tid = LLDB_INVALID_THREAD_ID;
+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;
+  }
+
+  // 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;
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index eeeecb5..e40c08c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -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);
+  //------------------------------------------------------------------
+  // 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);
+  // 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();
+  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 ();
+  // 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 ();
+  void GetListThreadsInStopReplySupported();
 
-    lldb::pid_t
-    GetCurrentProcessID (bool allow_lazy = true);
+  lldb::pid_t GetCurrentProcessID(bool allow_lazy = true);
 
-    bool
-    GetLaunchSuccess (std::string &error_str);
+  bool GetLaunchSuccess(std::string &error_str);
 
-    bool
-    LaunchGDBServer (const char *remote_accept_hostname,
-                     lldb::pid_t &pid,
-                     uint16_t &port,
-                     std::string &socket_name);
+  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);
+  size_t QueryGDBServer(
+      std::vector<std::pair<uint16_t, std::string>> &connection_urls);
 
-    bool
-    KillSpawnedProcess (lldb::pid_t pid);
+  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 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);
+  //------------------------------------------------------------------
+  /// 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);
+  int SendLaunchArchPacket(const char *arch);
 
-    //------------------------------------------------------------------
-    /// 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);
+  int SendLaunchEventDataPacket(const char *data,
+                                bool *was_supported = nullptr);
 
-    //------------------------------------------------------------------
-    /// 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);
+  //------------------------------------------------------------------
+  /// 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);
 
-    //------------------------------------------------------------------
-    /// 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);
+  //------------------------------------------------------------------
+  /// 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 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);
+  //------------------------------------------------------------------
+  /// 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);
 
-    //------------------------------------------------------------------
-    /// 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);
+  //------------------------------------------------------------------
+  /// 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);
 
-    lldb::addr_t
-    AllocateMemory (size_t size, uint32_t permissions);
+  //------------------------------------------------------------------
+  /// 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);
 
-    bool
-    DeallocateMemory (lldb::addr_t addr);
+  //------------------------------------------------------------------
+  /// 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);
 
-    Error
-    Detach (bool keep_stopped);
+  //------------------------------------------------------------------
+  /// 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);
 
-    Error
-    GetMemoryRegionInfo (lldb::addr_t addr, MemoryRegionInfo &range_info); 
+  lldb::addr_t AllocateMemory(size_t size, uint32_t permissions);
 
-    Error
-    GetWatchpointSupportInfo (uint32_t &num); 
+  bool DeallocateMemory(lldb::addr_t addr);
 
-    Error
-    GetWatchpointSupportInfo (uint32_t &num, bool& after, const ArchSpec &arch);
-    
-    Error
-    GetWatchpointsTriggerAfterInstruction (bool &after, const ArchSpec &arch);
+  Error Detach(bool keep_stopped);
 
-    const ArchSpec &
-    GetHostArchitecture ();
-    
-    uint32_t
-    GetHostDefaultPacketTimeout();
+  Error GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info);
 
-    const ArchSpec &
-    GetProcessArchitecture ();
+  Error GetWatchpointSupportInfo(uint32_t &num);
 
-    void
-    GetRemoteQSupported();
+  Error GetWatchpointSupportInfo(uint32_t &num, bool &after,
+                                 const ArchSpec &arch);
 
-    bool
-    GetVContSupported (char flavor);
+  Error GetWatchpointsTriggerAfterInstruction(bool &after,
+                                              const ArchSpec &arch);
 
-    bool
-    GetpPacketSupported (lldb::tid_t tid);
+  const ArchSpec &GetHostArchitecture();
 
-    bool
-    GetxPacketSupported ();
+  uint32_t GetHostDefaultPacketTimeout();
 
-    bool
-    GetVAttachOrWaitSupported ();
-    
-    bool
-    GetSyncThreadStateSupported();
-    
-    void
-    ResetDiscoverableSettings (bool did_exec);
+  const ArchSpec &GetProcessArchitecture();
 
-    bool
-    GetHostInfo (bool force = false);
+  void GetRemoteQSupported();
 
-    bool
-    GetDefaultThreadId (lldb::tid_t &tid);
-    
-    bool
-    GetOSVersion (uint32_t &major, 
-                  uint32_t &minor, 
-                  uint32_t &update);
+  bool GetVContSupported(char flavor);
 
-    bool
-    GetOSBuildString (std::string &s);
-    
-    bool
-    GetOSKernelDescription (std::string &s);
+  bool GetpPacketSupported(lldb::tid_t tid);
 
-    ArchSpec
-    GetSystemArchitecture ();
+  bool GetxPacketSupported();
 
-    bool
-    GetHostname (std::string &s);
+  bool GetVAttachOrWaitSupported();
 
-    lldb::addr_t
-    GetShlibInfoAddr();
+  bool GetSyncThreadStateSupported();
 
-    bool
-    GetSupportsThreadSuffix ();
+  void ResetDiscoverableSettings(bool did_exec);
 
-    bool
-    GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info);
+  bool GetHostInfo(bool force = false);
 
-    uint32_t
-    FindProcesses (const ProcessInstanceInfoMatch &process_match_info,
-                   ProcessInstanceInfoList &process_infos);
+  bool GetDefaultThreadId(lldb::tid_t &tid);
 
-    bool
-    GetUserName (uint32_t uid, std::string &name);
-    
-    bool
-    GetGroupName (uint32_t gid, std::string &name);
+  bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update);
 
-    bool
-    HasFullVContSupport ()
-    {
-        return GetVContSupported ('A');
+  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);
+  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
-    GetThreadStopInfo (lldb::tid_t tid, 
-                       StringExtractorGDBRemote &response);
+  bool SetNonStopMode(const bool enable);
 
-    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;
-        }
-    }
+  void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send,
+                       uint32_t max_recv, bool json, Stream &strm);
 
-    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
+  // 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
-    SetNonStopMode (const bool enable);
+  bool SetCurrentThread(uint64_t tid);
 
-    void
-    TestPacketSpeed (const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, bool json, Stream &strm);
+  bool SetCurrentThreadForRun(uint64_t tid);
 
-    // 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
-    GetQXferAuxvReadSupported ();
+  bool GetQXferLibrariesReadSupported();
 
-    bool
-    GetQXferLibrariesReadSupported ();
+  bool GetQXferLibrariesSVR4ReadSupported();
 
-    bool
-    GetQXferLibrariesSVR4ReadSupported ();
+  uint64_t GetRemoteMaxPacketSize();
 
-    uint64_t
-    GetRemoteMaxPacketSize();
+  bool GetEchoSupported();
 
-    bool
-    GetEchoSupported ();
+  bool GetAugmentedLibrariesSVR4ReadSupported();
 
-    bool
-    GetAugmentedLibrariesSVR4ReadSupported ();
+  bool GetQXferFeaturesReadSupported();
 
-    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;
+  }
 
-    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);
 
-    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);
+  lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags,
+                           mode_t mode, Error &error);
 
-    Error
-    SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions);
+  bool CloseFile(lldb::user_id_t fd, Error &error);
 
-    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);
+  lldb::user_id_t GetFileSize(const FileSpec &file_spec);
 
-    Error
-    MakeDirectory(const FileSpec &file_spec, uint32_t mode);
+  Error GetFilePermissions(const FileSpec &file_spec,
+                           uint32_t &file_permissions);
 
-    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
+  Error SetFilePermissions(const FileSpec &file_spec,
+                           uint32_t file_permissions);
 
-    bool
-    CalculateMD5 (const FileSpec& file_spec, uint64_t &high, uint64_t &low);
+  uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst,
+                    uint64_t dst_len, Error &error);
 
-    lldb::DataBufferSP
-    ReadRegister(lldb::tid_t tid,
-                 uint32_t reg_num); // Must be the eRegisterKindProcessPlugin register number
+  uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src,
+                     uint64_t src_len, Error &error);
 
-    lldb::DataBufferSP
-    ReadAllRegisters(lldb::tid_t tid);
+  Error CreateSymlink(const FileSpec &src, const FileSpec &dst);
 
-    bool
-    WriteRegister(lldb::tid_t tid, uint32_t reg_num, // eRegisterKindProcessPlugin register number
-                  llvm::ArrayRef<uint8_t> data);
+  Error Unlink(const FileSpec &file_spec);
 
-    bool
-    WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
+  Error MakeDirectory(const FileSpec &file_spec, uint32_t mode);
 
-    bool
-    SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
+  bool GetFileExists(const FileSpec &file_spec);
 
-    bool
-    RestoreRegisterState (lldb::tid_t tid, uint32_t save_id);
+  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
-    SyncThreadState(lldb::tid_t tid);
+  bool CalculateMD5(const FileSpec &file_spec, uint64_t &high, uint64_t &low);
 
-    const char *
-    GetGDBServerProgramName();
-    
-    uint32_t
-    GetGDBServerProgramVersion();
+  lldb::DataBufferSP ReadRegister(
+      lldb::tid_t tid,
+      uint32_t
+          reg_num); // Must be the eRegisterKindProcessPlugin register number
 
-    bool
-    AvoidGPackets(ProcessGDBRemote *process);
+  lldb::DataBufferSP ReadAllRegisters(lldb::tid_t tid);
 
-    StructuredData::ObjectSP
-    GetThreadsInfo();
+  bool
+  WriteRegister(lldb::tid_t tid,
+                uint32_t reg_num, // eRegisterKindProcessPlugin register number
+                llvm::ArrayRef<uint8_t> data);
 
-    bool
-    GetThreadExtendedInfoSupported();
+  bool WriteAllRegisters(lldb::tid_t tid, llvm::ArrayRef<uint8_t> data);
 
-    bool
-    GetLoadedDynamicLibrariesInfosSupported();
+  bool SaveRegisterState(lldb::tid_t tid, uint32_t &save_id);
 
-    bool
-    GetSharedCacheInfoSupported();
+  bool RestoreRegisterState(lldb::tid_t tid, uint32_t save_id);
 
-    bool
-    GetModuleInfo (const FileSpec& module_file_spec,
-                   const ArchSpec& arch_spec,
-                   ModuleSpec &module_spec);
+  bool SyncThreadState(lldb::tid_t tid);
 
-    bool
-    ReadExtFeature (const lldb_private::ConstString object,
-                    const lldb_private::ConstString annex,
-                    std::string & out,
-                    lldb_private::Error & err);
+  const char *GetGDBServerProgramName();
 
-    void
-    ServeSymbolLookups(lldb_private::Process *process);
+  uint32_t GetGDBServerProgramVersion();
 
-    //------------------------------------------------------------------
-    /// 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;
-    }
+  bool AvoidGPackets(ProcessGDBRemote *process);
 
-    //------------------------------------------------------------------
-    /// 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();
+  StructuredData::ObjectSP GetThreadsInfo();
 
-    //------------------------------------------------------------------
-    /// 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);
+  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();
+
+  //------------------------------------------------------------------
+  /// 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;
+  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
+  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;
 
-    uint32_t m_num_supported_hardware_watchpoints;
+  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
 
-    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
+  uint32_t m_num_supported_hardware_watchpoints;
 
-    bool m_supported_async_json_packets_is_valid;
-    lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
+  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
-    GetCurrentProcessInfo (bool allow_lazy_pid = true);
+  bool m_supported_async_json_packets_is_valid;
+  lldb_private::StructuredData::ObjectSP m_supported_async_json_packets_sp;
 
-    bool
-    GetGDBServerVersion();
+  bool GetCurrentProcessInfo(bool allow_lazy_pid = true);
 
-    // 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 GetGDBServerVersion();
 
-    bool
-    DecodeProcessInfoResponse (StringExtractorGDBRemote &response, 
-                               ProcessInstanceInfo &process_info);
+  // 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);
 
-    void
-    OnRunPacketSent(bool first) override;
+  bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
+                                 ProcessInstanceInfo &process_info);
 
-    PacketResult
-    SendThreadSpecificPacketAndWaitForResponse(lldb::tid_t tid, StreamString &&payload,
-                                               StringExtractorGDBRemote &response, bool send_async);
+  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
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 58cb776..8ccab36 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -25,114 +25,99 @@
 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;
+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;
+  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_invalid:
+      error.SetErrorString("invalid packet");
+      quit = true;
+      break;
 
-        case StringExtractorGDBRemote::eServerPacketType_unimplemented:
-            packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
-            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;
-        }
+    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 ("");
-}
-
-
-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::SendUnimplementedResponse(const char *) {
+  // TODO: Log the packet we aren't handling...
+  return SendPacketNoLock("");
 }
 
 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::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::SendOKResponse ()
-{
-    return SendPacketNoLock ("OK");
+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);
 }
 
-bool
-GDBRemoteCommunicationServer::HandshakeWithClient()
-{
-    return GetAck() == PacketResult::Success;
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendOKResponse() {
+  return SendPacketNoLock("OK");
+}
+
+bool GDBRemoteCommunicationServer::HandshakeWithClient() {
+  return GetAck() == PacketResult::Success;
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 1d512bf..55a615a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -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 @@
 
 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)>;
+  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(const char *comm_name,
+                               const char *listener_name);
 
-    ~GDBRemoteCommunicationServer() override;
+  ~GDBRemoteCommunicationServer() override;
 
-    void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
-                               PacketHandler handler);
+  void
+  RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type,
+                        PacketHandler handler);
 
-    PacketResult
-    GetPacketAndSendResponse (uint32_t timeout_usec,
-                              Error &error,
-                              bool &interrupt, 
-                              bool &quit);
+  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 ();
+  // 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
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 5ae5627..f7ef2fe 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -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::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;
+GDBRemoteCommunicationServerCommon::Handle_qHostInfo(
+    StringExtractorGDBRemote &packet) {
+  StreamString response;
 
-    // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
+  // $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());
+  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(";");
-    }
+  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);
+  // 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;");
+  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;
-    }
+  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(';');
-        }
+  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(';');
-    }
+  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();
+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);
-}
-
-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)
-{
-#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__);
-#endif
-    return SendErrorResponse (5);
-
-}
-
-GDBRemoteCommunication::PacketResult
-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());
-        }
-    }
-#endif
-    return SendErrorResponse (6);
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("qSpeedTest:"));
-
+  ProcessInstanceInfoMatch match_info;
+  packet.SetFilePos(::strlen("qfProcessInfo"));
+  if (packet.GetChar() == ':') {
     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());
-        }
+    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);
     }
-    return SendErrorResponse (7);
+  }
+
+  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_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);
-}
-
-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;
-    }
+GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo(
+    StringExtractorGDBRemote &packet) {
+  if (m_proc_infos_index < m_proc_infos.GetSize()) {
     StreamString response;
-    response.PutChar('F');
-    response.Printf("%i", err);
-    if (save_errno)
-        response.Printf(",%i", save_errno);
+    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_vFile_pRead (StringExtractorGDBRemote &packet)
-{
-#ifdef _WIN32
-    // 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());
-            }
+GDBRemoteCommunicationServerCommon::Handle_qUserName(
+    StringExtractorGDBRemote &packet) {
+#if !defined(LLDB_DISABLE_POSIX)
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__);
 
-            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());
-        }
+  // 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());
     }
-    return SendErrorResponse(21);
-
+  }
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__);
 #endif
+  return SendErrorResponse(5);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
-{
-#ifdef _WIN32
-    return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite() unimplemented");
-#else
-    packet.SetFilePos(::strlen("vFile:pwrite:"));
-
-    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());
-        }
+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());
     }
-    return SendErrorResponse(27);
+  }
 #endif
+  return SendErrorResponse(6);
 }
 
 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()
+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());
+      }
+      return SendPacketNoLock(response.GetString());
     }
-    return SendErrorResponse(22);
+  }
+  return SendErrorResponse(7);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen("vFile:mode:"));
-    std::string path;
-    packet.GetHexByteString(path);
-    if (!path.empty())
-    {
+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 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));
+        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.PutChar(',');
-        if (retcode)
-            response.PutChar('1');
-        else
-            response.PutChar('0');
+        response.Printf("%i", fd);
+        if (save_errno)
+          response.Printf(",%i", save_errno);
         return SendPacketNoLock(response.GetString());
+      }
     }
-    return SendErrorResponse(24);
+  }
+  return SendErrorResponse(18);
 }
 
 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_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_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());
-        }
-    }
-    return SendErrorResponse(24);
-}
-
-
-GDBRemoteCommunication::PacketResult
-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);
-        }
+GDBRemoteCommunicationServerCommon::Handle_vFile_pRead(
+    StringExtractorGDBRemote &packet) {
+#ifdef _WIN32
+  // 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());
+      }
+
+      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(25);
-}
+  }
+  return SendErrorResponse(21);
 
-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);
-
-        StreamGDBRemote response;
-        response.Printf("F%u", error.GetError());
-
-        return SendPacketNoLock(response.GetString());
-    }
-    return SendErrorResponse(20);
-}
-
-GDBRemoteCommunication::PacketResult
-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);
-
-        StreamGDBRemote response;
-        response.Printf("F%u", error.GetError());
-
-        return SendPacketNoLock(response.GetString());
-    }
-    return SendErrorResponse(19);
-}
-
-GDBRemoteCommunication::PacketResult
-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+");
-#if defined(__linux__)
-    response.PutCString (";qXfer:auxv:read+");
 #endif
+}
 
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
+    StringExtractorGDBRemote &packet) {
+#ifdef _WIN32
+  return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_"
+                                   "vFile_pWrite() unimplemented");
+#else
+  packet.SetFilePos(::strlen("vFile:pwrite:"));
+
+  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());
+    }
+  }
+  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());
+  }
+  return SendErrorResponse(22);
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet)
-{
-    m_thread_suffix_supported = true;
-    return SendOKResponse();
+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_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);
+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
-        m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError);
-    return SendOKResponse ();
+      response.PutChar('0');
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(24);
 }
 
 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_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_QSetSTDIN (StringExtractorGDBRemote &packet)
-{
-    packet.SetFilePos(::strlen ("QSetSTDIN:"));
-    FileAction file_action;
+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());
+    }
+  }
+  return SendErrorResponse(24);
+}
+
+GDBRemoteCommunication::PacketResult
+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());
+  }
+  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);
-    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);
-}
-
-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);
-}
-
-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());
-}
-
-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);
-}
-
-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);
-}
-
-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);
-}
-
-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)
-            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;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    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("");
+    Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);
 
     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(';');
+    response.Printf("F%u", error.GetError());
 
     return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(20);
 }
 
-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(proc_triple.getTriple().c_str());
-        response.PutChar(';');
-    }
+GDBRemoteCommunication::PacketResult
+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);
+
+    StreamGDBRemote response;
+    response.Printf("F%u", error.GetError());
+
+    return SendPacketNoLock(response.GetString());
+  }
+  return SendErrorResponse(19);
 }
 
-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());
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerCommon::Handle_qSupported(
+    StringExtractorGDBRemote &packet) {
+  StreamGDBRemote response;
 
-    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);
+  // 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);
 
-        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(';');
+  response.PutCString(";QStartNoAckMode+");
+  response.PutCString(";QThreadSuffixSupported+");
+  response.PutCString(";QListThreadsInStopReply+");
+  response.PutCString(";qEcho+");
+#if defined(__linux__)
+  response.PutCString(";qXfer:auxv:read+");
 #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;");
-    }
+  return SendPacketNoLock(response.GetString());
 }
 
-FileSpec
-GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path,
-                                                   const ArchSpec& arch)
-{
-#ifdef __ANDROID__
-    return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
+GDBRemoteCommunication::PacketResult
+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();
+}
+
+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();
+}
+
+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;
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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());
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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)
+      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;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  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(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();
+#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());
 #else
-    return FileSpec(module_path.c_str(), true);
+    // 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;");
+  }
+}
+
+FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile(
+    const std::string &module_path, const ArchSpec &arch) {
+#ifdef __ANDROID__
+  return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
+#else
+  return FileSpec(module_path.c_str(), true);
 #endif
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index 7bb6726..d6be24a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -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 @@
 
 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
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 04720ac..bc01836 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -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 @@
 // 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();
+      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);
+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);
-                          });
+  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__);
+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 ();
+  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::SetLaunchFlags(
+    unsigned int launch_flags) {
+  m_process_launch_info.GetFlags().Set(launch_flags);
+  return Error();
 }
 
-Error
-GDBRemoteCommunicationServerLLGS::LaunchProcess ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+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__);
+  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 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);
+  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);
-    }
+  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;
-    }
-
-    // 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 ());
-
+  if (!error.Success()) {
+    fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
+            m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
     return error;
-}
+  }
 
-Error
-GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid)
-{
-    Error error;
-
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+  // 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, __FUNCTION__, pid);
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64
+          " setting up stdout/stderr redirection via $O gdb-remote commands",
+          __FUNCTION__, m_debugged_process_sp->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 ());
+    // 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());
+  }
 
-    // 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);
-    }
+  printf("Launched '%s' as process %" PRIu64 "...\n",
+         m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
+         m_process_launch_info.GetProcessID());
 
-    printf ("Attached to process %" PRIu64 "...\n", pid);
-
-    return error;
+  return error;
 }
 
-void
-GDBRemoteCommunicationServerLLGS::InitializeDelegate (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+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;
+  }
+
+  // Setup stdout/stderr mapping from inferior.
+  auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
+  if (terminal_fd >= 0) {
     if (log)
-    {
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s called with NativeProcessProtocol pid %" PRIu64 ", current state: %s",
-                __FUNCTION__,
-                process->GetID (),
-                StateAsCString (process->GetState ()));
-    }
+      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);
+  }
+
+  printf("Attached to process %" PRIu64 "...\n", pid);
+
+  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()));
+  }
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendWResponse (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::SendWResponse(
+    NativeProcessProtocol *process) {
+  assert(process && "process cannot be NULL");
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    // send W notification
-    ExitType exit_type = ExitType::eExitTypeInvalid;
-    int return_code = 0;
-    std::string exit_description;
+  // 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 ", failed to retrieve process exit status", __FUNCTION__, process->GetID ());
+  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());
 
-        StreamGDBRemote response;
-        response.PutChar ('E');
-        response.PutHex8 (GDBRemoteServerError::eErrorExitStatus);
-        return SendPacketNoLock(response.GetString());
+    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());
+
+    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;
     }
-    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 ());
+    response.PutChar(return_type_code);
 
-        StreamGDBRemote response;
+    // POSIX exit status limited to unsigned 8 bits.
+    response.PutHex8(return_code);
 
-        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);
-
-        // POSIX exit status limited to unsigned 8 bits.
-        response.PutHex8 (return_code);
-
-        return SendPacketNoLock(response.GetString());
-    }
+    return SendPacketNoLock(response.GetString());
+  }
 }
 
-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 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.
-    }
+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);
+  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);
     }
-    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));
+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;
+  NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
+  if (!reg_ctx_sp)
+    return nullptr;
 
-    JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
+  JSONObject::SP register_object_sp = std::make_shared<JSONObject>();
 
 #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;
+  // 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
-    };
+  // 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.
+  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
 
-        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;
-        }
-
-        if (reg_info_p->value_regs != nullptr)
-            continue; // Only expedite registers that are not contained in other registers.
-
-        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()));
+    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;
     }
 
-    return register_object_sp;
-}
+    if (reg_info_p->value_regs != nullptr)
+      continue; // Only expedite registers that are not contained in other
+                // registers.
 
-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)
-    {
-
-        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;
-
-        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,
+    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__,
-                    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));
-
-        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);
-        }
-
-        // TODO: Expedite interesting regions of inferior memory
+                    reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
+                    reg_num, error.AsCString());
+      continue;
     }
 
-    return threads_array_sp;
+    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;
 }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread (lldb::tid_t tid)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
+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;
+}
 
-    // Ensure we have a debugged process.
-    if (!m_debugged_process_sp || (m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID))
-        return SendErrorResponse (50);
+static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process,
+                                        bool abridged) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
-    if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s preparing packet for pid %" PRIu64 " tid %" PRIu64,
-                __FUNCTION__, m_debugged_process_sp->GetID (), tid);
+  JSONArray::SP threads_array_sp = std::make_shared<JSONArray>();
 
-    // Ensure we can get info on the given thread.
-    NativeThreadProtocolSP thread_sp (m_debugged_process_sp->GetThreadByID (tid));
-    if (!thread_sp)
-        return SendErrorResponse (51);
+  // 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 SendErrorResponse (52);
+    if (!thread_sp->GetStopReason(tid_stop_info, description))
+      return nullptr;
 
-    // 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);
+    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);
     }
 
-    // Print the signal number.
-    response.PutHex8 (signum & 0xff);
+    JSONObject::SP thread_obj_sp = std::make_shared<JSONObject>();
+    threads_array_sp->AppendObject(thread_obj_sp);
 
-    // Include the tid.
-    response.Printf ("thread:%" PRIx64 ";", tid);
+    if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp, abridged))
+      thread_obj_sp->SetObject("registers", registers_sp);
 
-    // 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 ();
+    thread_obj_sp->SetObject("tid", std::make_shared<JSONNumber>(tid));
+    if (signum != 0)
+      thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum));
 
-        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 (';');
-    }
+    const std::string thread_name = thread_sp->GetName();
+    if (!thread_name.empty())
+      thread_obj_sp->SetObject("name",
+                               std::make_shared<JSONString>(thread_name));
 
-    // 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());
-
-        }
-    }
-
-    //
-    // 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);
-
-            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 (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())
-    {
-        // 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 (';');
+      thread_obj_sp->SetObject("description",
+                               std::make_shared<JSONString>(description));
 
-        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 (';');
+    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());
+    }
+  }
+
+  //
+  // 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);
+
+      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());
+          }
         }
+      }
     }
+  }
 
-    return SendPacketNoLock (response.GetString());
+  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");
+void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited(
+    NativeProcessProtocol *process) {
+  assert(process && "process cannot be NULL");
 
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  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 called", __FUNCTION__);
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to send stop "
+                  "notification for PID %" PRIu64 ", state: eStateExited",
+                  __FUNCTION__, process->GetID());
+  }
 
-    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();
 
-    // 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;
+  // We are ready to exit the debug monitor.
+  m_exit_now = true;
 }
 
-void
-GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped (NativeProcessProtocol *process)
-{
-    assert (process && "process cannot be NULL");
+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__);
+  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;
+  // 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));
+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;
+
+  default:
+    if (log) {
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s didn't handle state "
+                  "change for pid %" PRIu64 ", new state: %s",
+                  __FUNCTION__, process->GetID(), StateAsCString(state));
     }
+    break;
+  }
 
-    switch (state)
-    {
-    case StateType::eStateRunning:
-        StartSTDIOForwarding();
-        break;
+  // Remember the previous state reported to us.
+  m_inferior_prev_state = state;
+}
 
-    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;
+void GDBRemoteCommunicationServerLLGS::DidExec(NativeProcessProtocol *process) {
+  ClearProcessSpecificData();
+}
 
-    case StateType::eStateExited:
-        // Same as above
-        SendProcessOutput();
-        StopSTDIOForwarding();
-        HandleInferiorState_Exited (process);
-        break;
+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;
+  }
+
+  StreamString response;
+  response.PutChar('O');
+  response.PutBytesAsRawHex8(buffer, len);
+
+  return SendPacketNoLock(response.GetString());
+}
+
+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;
+  }
+
+  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;
+  }
+
+  return Error();
+}
+
+void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
+  // Don't forward if not connected (e.g. when attaching).
+  if (!m_stdio_communication.IsConnected())
+    return;
+
+  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());
+  }
+}
+
+void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() {
+  m_stdio_handle_up.reset();
+}
+
+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;
+
+    case eConnectionStatusInterrupted:
+    case eConnectionStatusTimedOut:
+      return;
+    }
+  }
+}
+
+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);
+
+  lldb::pid_t pid = m_debugged_process_sp->GetID();
+
+  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
+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);
+
+  // 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);
+
+  NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread();
+  if (!thread_sp)
+    return SendErrorResponse(69);
+
+  StreamString response;
+  response.Printf("QC%" PRIx64, thread_sp->GetID());
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+  StopSTDIOForwarding();
+
+  if (!m_debugged_process_sp) {
+    if (log)
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s No debugged process found.",
+          __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());
+
+  // No OK response for kill packet.
+  // return SendOKResponse ();
+  return PacketResult::Success;
+}
+
+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();
+}
+
+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();
+}
+
+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());
+  }
+
+  return SendErrorResponse(14);
+}
+
+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 ();
-}
-
-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;
+      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");
     }
 
-    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
+    thread_actions.Append(thread_action);
+  }
 
-        if ((result != PacketResult::Success))
-        {
-            if(log)
-                log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s",
-                        __FUNCTION__, error.AsCString());
-            m_mainloop.RequestTermination();
-            break;
-        }
+  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;
 }
 
-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);
+}
+
+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::SendONotification (const char *buffer, uint32_t len)
-{
-    if ((buffer == nullptr) || (len == 0))
-    {
-        // Nothing to send.
-        return PacketResult::Success;
-    }
+GDBRemoteCommunicationServerLLGS::Handle_stop_reason(
+    StringExtractorGDBRemote &packet) {
+  // Handle the $? gdbremote command.
 
-    StreamString response;
-    response.PutChar ('O');
-    response.PutBytesAsRawHex8 (buffer, len);
+  // If no process, indicate error
+  if (!m_debugged_process_sp)
+    return SendErrorResponse(02);
 
-    return SendPacketNoLock (response.GetString());
-}
-
-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;
-    }
-
-    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;
-    }
-
-    return Error();
-}
-
-void
-GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding()
-{
-    // Don't forward if not connected (e.g. when attaching).
-    if (! m_stdio_communication.IsConnected())
-        return;
-
-    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());
-    }
-}
-
-void
-GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding()
-{
-    m_stdio_handle_up.reset();
-}
-
-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;
-
-        case eConnectionStatusInterrupted:
-        case eConnectionStatusTimedOut:
-            return;
-        }
-    }
+  return SendStopReasonForState(m_debugged_process_sp->GetState());
 }
 
 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::SendStopReasonForState(
+    lldb::StateType process_state) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
 
-    lldb::pid_t pid = m_debugged_process_sp->GetID ();
+  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
 
-    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
-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);
-
+  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.
-    lldb::tid_t tid = m_debugged_process_sp->GetCurrentThreadID ();
-    SetCurrentThreadID (tid);
+    SetCurrentThreadID(tid);
+    return SendStopReplyPacketForThread(tid);
+  }
 
-    NativeThreadProtocolSP thread_sp = m_debugged_process_sp->GetCurrentThread ();
-    if (!thread_sp)
-        return SendErrorResponse (69);
+  case eStateInvalid:
+  case eStateUnloaded:
+  case eStateExited:
+    return SendWResponse(m_debugged_process_sp.get());
 
-    StreamString response;
-    response.Printf ("QC%" PRIx64, thread_sp->GetID ());
-
-    return SendPacketNoLock (response.GetString());
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_k (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    StopSTDIOForwarding();
-
-    if (! m_debugged_process_sp)
-    {
-        if (log)
-            log->Printf("GDBRemoteCommunicationServerLLGS::%s No debugged process found.", __FUNCTION__);
-        return PacketResult::Success;
+  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;
+  }
 
-    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());
-
-    // No OK response for kill packet.
-    // return SendOKResponse ();
-    return PacketResult::Success;
+  return SendErrorResponse(0);
 }
 
 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 ();
-}
+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);
 
-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 ();
-}
+  // Ensure we have a thread.
+  NativeThreadProtocolSP thread_sp(m_debugged_process_sp->GetThreadAtIndex(0));
+  if (!thread_sp)
+    return SendErrorResponse(69);
 
-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());
+  // 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(';');
+  }
 
-    return SendErrorResponse(14);
+  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_C (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
+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 called", __FUNCTION__);
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s() no process (%s), "
+                  "returning OK",
+                  __FUNCTION__,
+                  m_debugged_process_sp ? "invalid process id"
+                                        : "null m_debugged_process_sp");
+    return SendOKResponse();
+  }
 
-    // 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);
+  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);
     }
+  }
 
-    // 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.");
+  // 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;
     }
-    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);
+    // 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;
-
-    // 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);
+    m_stdio_communication.Write(tmp, read, status, &error);
+    if (error.Fail()) {
+      return SendErrorResponse(0x15);
     }
-    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;
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_c (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_THREAD));
+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 called", __FUNCTION__);
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
 
-    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());
+  // 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);
+  }
 
-    // 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);
-    }
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerLLGS::%s stopped process %" PRIu64,
+                __FUNCTION__, m_debugged_process_sp->GetID());
 
-    // Build the ResumeActionList
-    ResumeActionList actions (StateType::eStateRunning, 0);
+  // No response required from stop all.
+  return PacketResult::Success;
+}
 
-    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);
-    }
+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 continued process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+      log->Printf(
+          "GDBRemoteCommunicationServerLLGS::%s failed, no process available",
+          __FUNCTION__);
+    return SendErrorResponse(0x15);
+  }
 
-    // No response required from continue.
-    return PacketResult::Success;
-}
+  // Parse out the memory address.
+  packet.SetFilePos(strlen("m"));
+  if (packet.GetBytesLeft() < 1)
+    return SendIllFormedResponse(packet, "Too short m packet");
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vCont_actions (StringExtractorGDBRemote &packet)
-{
-    StreamString response;
-    response.Printf("vCont;c;C;s;S");
+  // 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_vCont (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+  // 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 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:
-                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);
-    }
-
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s nothing to read: "
+                  "zero-length packet",
+                  __FUNCTION__);
     return SendOKResponse();
-}
+  }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_H (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+  // Allocate the response buffer.
+  std::string buf(byte_count, '\0');
+  if (buf.empty())
+    return SendErrorResponse(0x78);
 
-    // 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);
-    }
-
+  // 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 stopped process %" PRIu64, __FUNCTION__, m_debugged_process_sp->GetID ());
+      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);
+  }
 
-    // No response required from stop all.
+  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();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_memory_read(StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported(
+    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);
-    }
+  // 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.
 
-    // Parse out the memory address.
-    packet.SetFilePos (strlen("m"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short m packet");
+  // 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);
+  }
 
-    // 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);
+  // 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("");
+  }
 
-    // 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());
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_M (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo(
+    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);
+  // 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(';');
     }
 
-    // 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;
+    // Name
+    ConstString name = region_info.GetName();
+    if (name) {
+      response.PutCString("name:");
+      response.PutCStringAsRawHex8(name.AsCString());
+      response.PutChar(';');
     }
+  }
 
-    // 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 ();
+  return SendPacketNoLock(response.GetString());
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+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);
+  }
 
-    // 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.
+  // 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");
 
-    // 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);
-    }
+  bool want_breakpoint = true;
+  bool want_hardware = false;
+  uint32_t watch_flags = 0;
 
-    // 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 ("");
-    }
+  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");
+  }
 
-    return SendOKResponse();
+  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_qMemoryRegionInfo (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+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);
+  }
 
-    // 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 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");
 
-    // Parse out the memory address.
-    packet.SetFilePos (strlen("qMemoryRegionInfo:"));
-    if (packet.GetBytesLeft() < 1)
-        return SendIllFormedResponse(packet, "Too short qMemoryRegionInfo: packet");
+  bool want_breakpoint = true;
 
-    // Read the address.  Punting on validation.
-    const lldb::addr_t read_addr = packet.GetHexMaxU64(false, 0);
+  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");
+  }
 
-    StreamGDBRemote response;
+  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "Malformed z packet, expecting comma after stoppoint type");
 
-    // 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.
+  // 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);
 
-        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 ());
+  if ((packet.GetBytesLeft() < 1) || packet.GetChar() != ',')
+    return SendIllFormedResponse(
+        packet, "Malformed z packet, expecting comma after address");
 
-        // Permissions.
-        if (region_info.GetReadable () ||
-            region_info.GetWritable () ||
-            region_info.GetExecutable ())
-        {
-            // Write permissions info.
-            response.PutCString ("permissions:");
+  /*
+  // 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 (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());
+  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_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_s(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
 
-    // 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");
+  // 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);
+  }
 
-    bool want_breakpoint = true;
-    bool want_hardware = false;
-    uint32_t watch_flags = 0;
+  // 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);
 
-    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");
+  // 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};
 
-    if ((packet.GetBytesLeft() < 1) || packet.GetChar () != ',')
-        return SendIllFormedResponse(packet, "Malformed Z packet, expecting comma after stoppoint type");
+  // Setup the actions list.
+  ResumeActionList actions;
+  actions.Append(action);
 
-    // 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);
+  // 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);
+  }
 
-    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);
-    }
+  // No response here - the stop or exit will come from the resulting action.
+  return PacketResult::Success;
 }
 
 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.
+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));
+  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");
+  // 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");
+  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 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");
+  // 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);
-        }
+  // 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);
     }
 
-    // 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;
+    // 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);
     }
-    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;
+  // FIXME find out if/how I lock the stream here.
 
-        // 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');
-        }
+  StreamGDBRemote response;
+  bool done_with_buffer = false;
 
-        // Now write the data in encoded binary form.
-        response.PutEscapedBytes (m_active_auxv_buffer_sp->GetBytes () + auxv_offset, bytes_to_read);
+  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');
     }
 
-    if (done_with_buffer)
-        m_active_auxv_buffer_sp.reset ();
+    // Now write the data in encoded binary form.
+    response.PutEscapedBytes(m_active_auxv_buffer_sp->GetBytes() + auxv_offset,
+                             bytes_to_read);
+  }
 
-    return SendPacketNoLock(response.GetString());
+  if (done_with_buffer)
+    m_active_auxv_buffer_sp.reset();
+
+  return SendPacketNoLock(response.GetString());
 #else
-    return SendUnimplementedResponse ("not implemented on this platform");
+  return SendUnimplementedResponse("not implemented on this platform");
 #endif
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-    // Move past packet name.
-    packet.SetFilePos (strlen ("QSaveRegisterState"));
+  // 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");
-    }
+  // 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 (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);
-    }
+  // 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);
-    }
+  // 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");
+  // 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;
-    }
+  // 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());
+  // 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));
+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");
+  // 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);
+  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;
 
-    // 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");
-    }
+    // Remove it from the map.
+    m_saved_registers_map.erase(it);
+  }
 
-    // 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);
-    }
+  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);
+  }
 
-    // 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();
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_vAttach (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+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 ';'");
+  // 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);
+  // 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, "vAttach failed to parse the process id");
+      return SendIllFormedResponse(packet, "D failed to parse the process id");
+  }
 
-    // Attempt to attach.
+  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 attempting to attach to pid %" PRIu64, __FUNCTION__, pid);
+      log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to detach from "
+                  "pid %" PRIu64 ": %s\n",
+                  __FUNCTION__, m_debugged_process_sp->GetID(),
+                  error.AsCString());
+    return SendErrorResponse(0x01);
+  }
 
-    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 ());
+  return SendOKResponse();
 }
 
 GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_D (StringExtractorGDBRemote &packet)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
+GDBRemoteCommunicationServerLLGS::Handle_qThreadStopInfo(
+    StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-    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);
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_jThreadsInfo (StringExtractorGDBRemote &)
-{
-    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);
-
+  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 preparing packet for pid %" PRIu64,
+      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_jThreadsInfo(
+    StringExtractorGDBRemote &) {
+  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,
                 __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);
+  }
 
-    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());
+  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);
+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);
+  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());
+  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);
+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);
+  packet.SetFilePos(strlen("qFileLoadAddress:"));
+  if (packet.GetBytesLeft() == 0)
+    return SendErrorResponse(68);
 
-    std::string file_name;
-    packet.GetHexByteString(file_name);
+  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);
+  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
+  if (file_load_address == LLDB_INVALID_ADDRESS)
+    return SendErrorResponse(1); // File not loaded
 
-    StreamGDBRemote response;
-    response.PutHex64(file_load_address);
-    return SendPacketNoLock(response.GetString());
+  StreamGDBRemote response;
+  response.PutHex64(file_load_address);
+  return SendPacketNoLock(response.GetString());
 }
 
-void
-GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+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);
+  // 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 ());
-            }
-        }
+      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());
+      }
     }
+  }
 }
 
+NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix(
+    StringExtractorGDBRemote &packet) {
+  NativeThreadProtocolSP 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);
-
+  // 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;
-}
 
-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;
-}
+  // 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);
+  }
 
-uint32_t
-GDBRemoteCommunicationServerLLGS::GetNextSavedRegistersID ()
-{
-    std::lock_guard<std::mutex> guard(m_saved_registers_mutex);
-    return m_next_saved_registers_id++;
-}
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 
-void
-GDBRemoteCommunicationServerLLGS::ClearProcessSpecificData ()
-{
-    Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS|GDBR_LOG_PROCESS));
+  // Parse out the ';'.
+  if (packet.GetBytesLeft() < 1 || packet.GetChar() != ';') {
     if (log)
-        log->Printf ("GDBRemoteCommunicationServerLLGS::%s()", __FUNCTION__);
+      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;
+  }
 
-    // Clear any auxv cached data.
-    // *BSD impls should be able to do this too.
+  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;
+}
+
+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__);
+
+// 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);
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index caf6eb3..fa52cda 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -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 @@
 
 class ProcessGDBRemote;
 
-class GDBRemoteCommunicationServerLLGS :
-    public GDBRemoteCommunicationServerCommon,
-    public NativeProcessProtocol::NativeDelegate
-{
+class GDBRemoteCommunicationServerLLGS
+    : public GDBRemoteCommunicationServerCommon,
+      public NativeProcessProtocol::NativeDelegate {
 public:
-    //------------------------------------------------------------------
-    // Constructors and Destructors
-    //------------------------------------------------------------------
-    GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
+  //------------------------------------------------------------------
+  // 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 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);
+  //------------------------------------------------------------------
+  /// 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;
+  //------------------------------------------------------------------
+  /// 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);
+  //------------------------------------------------------------------
+  /// 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;
+  //------------------------------------------------------------------
+  // 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_
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index c9baed7..80d6b8a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -13,8 +13,8 @@
 
 // C Includes
 // C++ Includes
-#include <cstring>
 #include <chrono>
+#include <cstring>
 #include <mutex>
 #include <sstream>
 
@@ -47,550 +47,524 @@
 //----------------------------------------------------------------------
 // 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;
+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);
+  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;
-                          });
+  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()
-{
-}
+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).
+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();
 
-    // ignore the hostname send from the remote end, just use the ip address
-    // that we're currently communicating with as the hostname
+  // Spawn a new thread to accept the port that gets bound after
+  // binding to port 0 (zero).
 
-    // Spawn a debugserver and try to get the port it listens to.
-    ProcessLaunchInfo debugserver_launch_info;
-    if (hostname.empty())
-        hostname = "127.0.0.1";
+  // ignore the hostname send from the remote end, just use the ip address
+  // that we're currently communicating with as the hostname
 
-    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
-    if (log)
-        log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
+  // Spawn a debugserver and try to get the port it listens to.
+  ProcessLaunchInfo debugserver_launch_info;
+  if (hostname.empty())
+    hostname = "127.0.0.1";
 
-    // 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);
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+  if (log)
+    log->Printf("Launching debugserver with: %s:%u...", hostname.c_str(), port);
 
-    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);
+  // 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::ostringstream url;
-    // debugserver does not accept the URL scheme prefix.
+  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.
 #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;
-}
-
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
-{
-#ifdef _WIN32
-    return SendErrorResponse(9);
-#else
-    // Spawn a local debugserver as a platform so we can then attach or launch
-    // a process...
-
-    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() 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(';');
-    }
-
-    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());
-}
-
-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;
-    }
-
-    // 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;
-    }
-
-    // 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());
-}
-
-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());
-}
-
-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 ();
-}
-
-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();
-    }
-
-    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);
-
-        signal_array.Push(dictionary);
-    }
-
-    StreamString response;
-    signal_array.Dump(response);
-    return SendPacketNoLock(response.GetString());
-}
-
-bool
-GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
-{
+  pid = debugserver_launch_info.GetProcessID();
+  if (pid != LLDB_INVALID_PROCESS_ID) {
     std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-    FreePortForProcess(pid);
-    m_spawned_pids.erase(pid);
-    return true;
+    m_spawned_pids.insert(pid);
+    if (port > 0)
+      AssociatePortWithProcess(port, pid);
+  } else {
+    if (port > 0)
+      FreePort(port);
+  }
+  return error;
 }
 
-Error
-GDBRemoteCommunicationServerPlatform::LaunchProcess ()
-{
-    if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
-        return Error ("%s: no process command line specified to launch", __FUNCTION__);
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer(
+    StringExtractorGDBRemote &packet) {
+#ifdef _WIN32
+  return SendErrorResponse(9);
+#else
+  // Spawn a local debugserver as a platform so we can then attach or launch
+  // a process...
 
-    // 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);
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
+  if (log)
+    log->Printf("GDBRemoteCommunicationServerPlatform::%s() called",
+                __FUNCTION__);
 
-    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;
+  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(';');
+  }
+
+  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());
+}
+
+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);
     }
+  }
 
-    printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
+  // go ahead and attempt to kill the spawned process
+  if (KillSpawnedProcess(pid))
+    return SendOKResponse();
+  else
+    return SendErrorResponse(11);
+}
 
-    // 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)
+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) {
     {
-        // add to spawned pids
-        std::lock_guard<std::recursive_mutex> guard(m_spawned_pids_mutex);
-        m_spawned_pids.insert(pid);
+      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;
+  }
+
+  // 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());
+}
+
+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());
+}
+
+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();
+}
+
+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();
+  }
+
+  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);
+
+    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;
+  }
+
+  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);
+  }
+
+  return error;
 }
 
-void
-GDBRemoteCommunicationServerPlatform::SetPortMap (PortMap &&port_map)
-{
-    m_port_map = port_map;
+void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) {
+  m_port_map = port_map;
 }
 
-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
+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;
-        }
+  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;
+  }
+  return UINT16_MAX;
 }
 
-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::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;
+}
+
+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::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);
+  });
 
-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);
-    });
-
-    return g_domainsocket_dir;
+  return 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());
+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());
+  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);
+  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::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::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;
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 1f4d08c..472d86e3 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -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;
+  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);
+  // 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 ();
+  //----------------------------------------------------------------------
+  // 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 AssociatePortWithProcess(uint16_t port, lldb::pid_t pid);
 
-    bool
-    FreePort (uint16_t port);
+  bool FreePort(uint16_t port);
 
-    bool
-    FreePortForProcess (lldb::pid_t pid);
+  bool FreePortForProcess(lldb::pid_t pid);
 
-    void
-    SetPortOffset (uint16_t port_offset);
+  void SetPortOffset(uint16_t port_offset);
 
-    void
-    SetInferiorArguments (const lldb_private::Args& args);
+  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 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);
+  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
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 78e1956..27ce67d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -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 @@
 //----------------------------------------------------------------------
 // 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());
+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());
+  // 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();
-    }
+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);
+
+  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, llvm::ArrayRef<uint8_t> data)
-{
-    const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
-    if (reg_info == NULL)
-        return 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;
-}
-
-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);
-
-    DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val)));
-    DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*));
-
-    // 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 (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;
-    }
+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);
+
+  DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val)));
+  DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *));
+
+  // 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 (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()));
-    return false;
+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());
+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;
+  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());
 
-    InvalidateIfNeeded(false);
+  InvalidateIfNeeded(false);
 
-    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+  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);
-        }
+  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;
 
-        // Make sure we got a valid register value after reading it
-        if (!GetRegisterIsValid(reg))
-            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
 
-    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;
+    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;
+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);
+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});
+  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());
+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;
+  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 (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 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;
-}
 
-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());
+  // 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));
 
-    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());
-    }
-}
+  if (dst == NULL)
+    return false;
 
-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());
-    }
-}
-
-bool
-GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
-{
-    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());
-
-    const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == 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 (gdb_comm.SyncThreadState(m_thread.GetProtocolID()))
-            InvalidateAllRegisters();
+    if (lock) {
+      if (m_read_all_at_once) {
+        // Invalidate all register values
+        InvalidateIfNeeded(true);
 
-        if (use_g_packet && (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())))
-            return true;
+        // Set all registers in one packet
+        if (gdb_comm.WriteAllRegisters(
+                m_thread.GetProtocolID(),
+                {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
 
-        // 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
+          SetAllRegisterValid(false);
+          return true;
         }
-        data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize()));
-        return true;
-    }
-    else
-    {
+      } else {
+        bool success = true;
 
-        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());
-            }
+        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
-                log->Printf("error: failed to get packet sequence mutex, not sending read all registers");
+              success = SetPrimordialRegister(value_reg_info, gdb_comm);
+          }
+        } else {
+          // This is an actual register, write it
+          success = SetPrimordialRegister(reg_info, gdb_comm);
         }
-    }
 
-    data_sp.reset();
-    return false;
+        // 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::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
-{
-    if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
-        return false;
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+    RegisterCheckpoint &reg_checkpoint) {
+  ExecutionContext exe_ctx(CalculateThread());
 
-    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());
+  }
+}
+
+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)
-    {
-        // 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;
+bool GDBRemoteRegisterContext::ReadAllRegisterValues(
+    lldb::DataBufferSP &data_sp) {
+  ExecutionContext exe_ctx(CalculateThread());
 
-            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];
-
-                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");
-        }
-    }
+  Process *process = exe_ctx.GetProcessPtr();
+  Thread *thread = exe_ctx.GetThreadPtr();
+  if (process == NULL || thread == NULL)
     return false;
+
+  GDBRemoteCommunicationClient &gdb_comm(
+      ((ProcessGDBRemote *)process)->GetGDBRemote());
+
+  const bool use_g_packet =
+      gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == 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 {
+
+    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;
 
-uint32_t
-GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
-{
-    return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num);
+  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());
+
+  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 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];
+
+        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)
+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
-    };
+  // 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 @@
     { "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;
-                }
-            }
+  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;
+    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);
 
-        // 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.
+      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);
+            }
+          }
+        }
+      }
+    }
+  }
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index c1d8249..5b3e04e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -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 @@
 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 ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data);
 
-    bool
-    WriteRegisterBytes (const RegisterInfo *reg_info,
-                        DataExtractor &data, 
-                        uint32_t data_offset);
+  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, llvm::ArrayRef<uint8_t> data);
 
-    bool
-    PrivateSetRegisterValue (uint32_t reg, uint64_t val);
+  bool PrivateSetRegisterValue(uint32_t reg, uint64_t val);
 
-    void
-    SetAllRegisterValid (bool b);
+  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;
-    }
+    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(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());
+  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;
-    }
+    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;
+  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
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 3f7b64c..9e21e82 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -14,7 +14,7 @@
 #include <stdlib.h>
 #ifndef LLDB_DISABLE_POSIX
 #include <netinet/in.h>
-#include <sys/mman.h>       // for mmap
+#include <sys/mman.h> // for mmap
 #include <sys/socket.h>
 #endif
 #include <sys/stat.h>
@@ -28,11 +28,8 @@
 #include <sstream>
 
 #include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Interpreter/Args.h"
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/Debugger.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/FileSpec.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
@@ -42,6 +39,8 @@
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/Value.h"
 #include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileSpec.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostThread.h"
 #include "lldb/Host/StringConvert.h"
@@ -49,133 +48,111 @@
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/TimeValue.h"
 #include "lldb/Host/XML.h"
+#include "lldb/Interpreter/Args.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandObject.h"
 #include "lldb/Interpreter/CommandObjectMultiword.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/OptionGroupBoolean.h"
 #include "lldb/Interpreter/OptionGroupUInt64.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/Property.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ABI.h"
 #include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/SystemRuntime.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/TargetList.h"
 #include "lldb/Target/ThreadPlanCallFunction.h"
-#include "lldb/Target/SystemRuntime.h"
 #include "lldb/Utility/CleanUp.h"
 #include "lldb/Utility/PseudoTerminal.h"
 
 // Project includes
-#include "lldb/Host/Host.h"
+#include "GDBRemoteRegisterContext.h"
+#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
 #include "Plugins/Process/Utility/StopInfoMachException.h"
-#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
-#include "Utility/StringExtractorGDBRemote.h"
-#include "GDBRemoteRegisterContext.h"
 #include "ProcessGDBRemote.h"
 #include "ProcessGDBRemoteLog.h"
 #include "ThreadGDBRemote.h"
+#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Host/Host.h"
 
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 
-#define DEBUGSERVER_BASENAME    "debugserver"
+#define DEBUGSERVER_BASENAME "debugserver"
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::process_gdb_remote;
 
-namespace lldb
-{
-    // Provide a function that can easily dump the packet history if we know a
-    // ProcessGDBRemote * value (which we can get from logs or from debugging).
-    // We need the function in the lldb namespace so it makes it into the final
-    // executable since the LLDB shared library only exports stuff in the lldb
-    // namespace. This allows you to attach with a debugger and call this
-    // function and get the packet history dumped to a file.
-    void
-    DumpProcessGDBRemotePacketHistory (void *p, const char *path)
-    {
-        StreamFile strm;
-        Error error (strm.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate));
-        if (error.Success())
-            ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory (strm);
-    }
+namespace lldb {
+// Provide a function that can easily dump the packet history if we know a
+// ProcessGDBRemote * value (which we can get from logs or from debugging).
+// We need the function in the lldb namespace so it makes it into the final
+// executable since the LLDB shared library only exports stuff in the lldb
+// namespace. This allows you to attach with a debugger and call this
+// function and get the packet history dumped to a file.
+void DumpProcessGDBRemotePacketHistory(void *p, const char *path) {
+  StreamFile strm;
+  Error error(strm.GetFile().Open(path, File::eOpenOptionWrite |
+                                            File::eOpenOptionCanCreate));
+  if (error.Success())
+    ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm);
+}
 }
 
 namespace {
 
-    static PropertyDefinition
-    g_properties[] =
-    {
-        { "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, NULL, "Specify the default packet timeout in seconds." },
-        { "target-definition-file" , OptionValue::eTypeFileSpec , true, 0 , NULL, NULL, "The file that provides the description for remote target registers." },
-        {  NULL            , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL  }
-    };
+static PropertyDefinition g_properties[] = {
+    {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, NULL,
+     "Specify the default packet timeout in seconds."},
+    {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, NULL,
+     "The file that provides the description for remote target registers."},
+    {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
 
-    enum
-    {
-        ePropertyPacketTimeout,
-        ePropertyTargetDefinitionFile
-    };
+enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile };
 
-    class PluginProperties : public Properties
-    {
-    public:
+class PluginProperties : public Properties {
+public:
+  static ConstString GetSettingName() {
+    return ProcessGDBRemote::GetPluginNameStatic();
+  }
 
-        static ConstString
-        GetSettingName ()
-        {
-            return ProcessGDBRemote::GetPluginNameStatic();
-        }
+  PluginProperties() : Properties() {
+    m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
+    m_collection_sp->Initialize(g_properties);
+  }
 
-        PluginProperties() :
-        Properties ()
-        {
-            m_collection_sp.reset (new OptionValueProperties(GetSettingName()));
-            m_collection_sp->Initialize(g_properties);
-        }
+  virtual ~PluginProperties() {}
 
-        virtual
-        ~PluginProperties()
-        {
-        }
+  uint64_t GetPacketTimeout() {
+    const uint32_t idx = ePropertyPacketTimeout;
+    return m_collection_sp->GetPropertyAtIndexAsUInt64(
+        NULL, idx, g_properties[idx].default_uint_value);
+  }
 
-        uint64_t
-        GetPacketTimeout()
-        {
-            const uint32_t idx = ePropertyPacketTimeout;
-            return m_collection_sp->GetPropertyAtIndexAsUInt64(NULL, idx, g_properties[idx].default_uint_value);
-        }
+  bool SetPacketTimeout(uint64_t timeout) {
+    const uint32_t idx = ePropertyPacketTimeout;
+    return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
+  }
 
-        bool
-        SetPacketTimeout(uint64_t timeout)
-        {
-            const uint32_t idx = ePropertyPacketTimeout;
-            return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, timeout);
-        }
+  FileSpec GetTargetDefinitionFile() const {
+    const uint32_t idx = ePropertyTargetDefinitionFile;
+    return m_collection_sp->GetPropertyAtIndexAsFileSpec(NULL, idx);
+  }
+};
 
-        FileSpec
-        GetTargetDefinitionFile () const
-        {
-            const uint32_t idx = ePropertyTargetDefinitionFile;
-            return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
-        }
-    };
+typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
 
-    typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
-
-    static const ProcessKDPPropertiesSP &
-    GetGlobalPluginProperties()
-    {
-        static ProcessKDPPropertiesSP g_settings_sp;
-        if (!g_settings_sp)
-            g_settings_sp.reset (new PluginProperties ());
-        return g_settings_sp;
-    }
+static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
+  static ProcessKDPPropertiesSP g_settings_sp;
+  if (!g_settings_sp)
+    g_settings_sp.reset(new PluginProperties());
+  return g_settings_sp;
+}
 
 } // anonymous namespace end
 
@@ -183,3870 +160,3561 @@
 // ephemeral port from the kernel and make sure we reserve it before passing
 // it to debugserver.
 
-#if defined (__APPLE__)
-#define LOW_PORT    (IPPORT_RESERVED)
-#define HIGH_PORT   (IPPORT_HIFIRSTAUTO)
+#if defined(__APPLE__)
+#define LOW_PORT (IPPORT_RESERVED)
+#define HIGH_PORT (IPPORT_HIFIRSTAUTO)
 #else
-#define LOW_PORT    (1024u)
-#define HIGH_PORT   (49151u)
+#define LOW_PORT (1024u)
+#define HIGH_PORT (49151u)
 #endif
 
-#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
+#if defined(__APPLE__) &&                                                      \
+    (defined(__arm__) || defined(__arm64__) || defined(__aarch64__))
 static bool rand_initialized = false;
 
-static inline uint16_t
-get_random_port ()
-{
-    if (!rand_initialized)
-    {
-        time_t seed = time(NULL);
+static inline uint16_t get_random_port() {
+  if (!rand_initialized) {
+    time_t seed = time(NULL);
 
-        rand_initialized = true;
-        srand(seed);
-    }
-    return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
+    rand_initialized = true;
+    srand(seed);
+  }
+  return (rand() % (HIGH_PORT - LOW_PORT)) + LOW_PORT;
 }
 #endif
 
-ConstString
-ProcessGDBRemote::GetPluginNameStatic()
-{
-    static ConstString g_name("gdb-remote");
-    return g_name;
+ConstString ProcessGDBRemote::GetPluginNameStatic() {
+  static ConstString g_name("gdb-remote");
+  return g_name;
 }
 
-const char *
-ProcessGDBRemote::GetPluginDescriptionStatic()
-{
-    return "GDB Remote protocol based debugging plug-in.";
+const char *ProcessGDBRemote::GetPluginDescriptionStatic() {
+  return "GDB Remote protocol based debugging plug-in.";
 }
 
-void
-ProcessGDBRemote::Terminate()
-{
-    PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance);
+void ProcessGDBRemote::Terminate() {
+  PluginManager::UnregisterPlugin(ProcessGDBRemote::CreateInstance);
 }
 
-
 lldb::ProcessSP
-ProcessGDBRemote::CreateInstance (lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec *crash_file_path)
-{
-    lldb::ProcessSP process_sp;
-    if (crash_file_path == NULL)
-        process_sp.reset (new ProcessGDBRemote (target_sp, listener_sp));
-    return process_sp;
+ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp,
+                                 ListenerSP listener_sp,
+                                 const FileSpec *crash_file_path) {
+  lldb::ProcessSP process_sp;
+  if (crash_file_path == NULL)
+    process_sp.reset(new ProcessGDBRemote(target_sp, listener_sp));
+  return process_sp;
 }
 
-bool
-ProcessGDBRemote::CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_name)
-{
-    if (plugin_specified_by_name)
-        return true;
-
-    // For now we are just making sure the file exists for a given module
-    Module *exe_module = target_sp->GetExecutableModulePointer();
-    if (exe_module)
-    {
-        ObjectFile *exe_objfile = exe_module->GetObjectFile();
-        // We can't debug core files...
-        switch (exe_objfile->GetType())
-        {
-            case ObjectFile::eTypeInvalid:
-            case ObjectFile::eTypeCoreFile:
-            case ObjectFile::eTypeDebugInfo:
-            case ObjectFile::eTypeObjectFile:
-            case ObjectFile::eTypeSharedLibrary:
-            case ObjectFile::eTypeStubLibrary:
-            case ObjectFile::eTypeJIT:
-                return false;
-            case ObjectFile::eTypeExecutable:
-            case ObjectFile::eTypeDynamicLinker:
-            case ObjectFile::eTypeUnknown:
-                break;
-        }
-        return exe_module->GetFileSpec().Exists();
-    }
-    // However, if there is no executable module, we return true since we might be preparing to attach.
+bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp,
+                                bool plugin_specified_by_name) {
+  if (plugin_specified_by_name)
     return true;
+
+  // For now we are just making sure the file exists for a given module
+  Module *exe_module = target_sp->GetExecutableModulePointer();
+  if (exe_module) {
+    ObjectFile *exe_objfile = exe_module->GetObjectFile();
+    // We can't debug core files...
+    switch (exe_objfile->GetType()) {
+    case ObjectFile::eTypeInvalid:
+    case ObjectFile::eTypeCoreFile:
+    case ObjectFile::eTypeDebugInfo:
+    case ObjectFile::eTypeObjectFile:
+    case ObjectFile::eTypeSharedLibrary:
+    case ObjectFile::eTypeStubLibrary:
+    case ObjectFile::eTypeJIT:
+      return false;
+    case ObjectFile::eTypeExecutable:
+    case ObjectFile::eTypeDynamicLinker:
+    case ObjectFile::eTypeUnknown:
+      break;
+    }
+    return exe_module->GetFileSpec().Exists();
+  }
+  // However, if there is no executable module, we return true since we might be
+  // preparing to attach.
+  return true;
 }
 
 //----------------------------------------------------------------------
 // ProcessGDBRemote constructor
 //----------------------------------------------------------------------
-ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, ListenerSP listener_sp)
-    : Process(target_sp, listener_sp),
-      m_flags(0),
-      m_gdb_comm(),
-      m_debugserver_pid(LLDB_INVALID_PROCESS_ID),
-      m_last_stop_packet_mutex(),
+ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp,
+                                   ListenerSP listener_sp)
+    : Process(target_sp, listener_sp), m_flags(0), m_gdb_comm(),
+      m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(),
       m_register_info(),
       m_async_broadcaster(NULL, "lldb.process.gdb-remote.async-broadcaster"),
-      m_async_listener_sp(Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
-      m_async_thread_state_mutex(),
-      m_thread_ids(),
-      m_thread_pcs(),
-      m_jstopinfo_sp(),
-      m_jthreadsinfo_sp(),
-      m_continue_c_tids(),
-      m_continue_C_tids(),
-      m_continue_s_tids(),
-      m_continue_S_tids(),
-      m_max_memory_size(0),
-      m_remote_stub_max_memory_size(0),
-      m_addr_to_mmap_size(),
-      m_thread_create_bp_sp(),
-      m_waiting_for_attach(false),
-      m_destroy_tried_resuming(false),
-      m_command_sp(),
-      m_breakpoint_pc_offset(0),
-      m_initial_tid(LLDB_INVALID_THREAD_ID)
-{
-    m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
-    m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, "async thread continue");
-    m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit, "async thread did exit");
+      m_async_listener_sp(
+          Listener::MakeListener("lldb.process.gdb-remote.async-listener")),
+      m_async_thread_state_mutex(), m_thread_ids(), m_thread_pcs(),
+      m_jstopinfo_sp(), m_jthreadsinfo_sp(), m_continue_c_tids(),
+      m_continue_C_tids(), m_continue_s_tids(), m_continue_S_tids(),
+      m_max_memory_size(0), m_remote_stub_max_memory_size(0),
+      m_addr_to_mmap_size(), m_thread_create_bp_sp(),
+      m_waiting_for_attach(false), m_destroy_tried_resuming(false),
+      m_command_sp(), m_breakpoint_pc_offset(0),
+      m_initial_tid(LLDB_INVALID_THREAD_ID) {
+  m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
+                                   "async thread should exit");
+  m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
+                                   "async thread continue");
+  m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit,
+                                   "async thread did exit");
 
-    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC));
 
-    const uint32_t async_event_mask = eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
+  const uint32_t async_event_mask =
+      eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
 
-    if (m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, async_event_mask) != async_event_mask)
-    {
-        if (log)
-            log->Printf("ProcessGDBRemote::%s failed to listen for m_async_broadcaster events", __FUNCTION__);
-    }
+  if (m_async_listener_sp->StartListeningForEvents(
+          &m_async_broadcaster, async_event_mask) != async_event_mask) {
+    if (log)
+      log->Printf("ProcessGDBRemote::%s failed to listen for "
+                  "m_async_broadcaster events",
+                  __FUNCTION__);
+  }
 
-    const uint32_t gdb_event_mask =
-        Communication::eBroadcastBitReadThreadDidExit | GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
-    if (m_async_listener_sp->StartListeningForEvents(&m_gdb_comm, gdb_event_mask) != gdb_event_mask)
-    {
-        if (log)
-            log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events", __FUNCTION__);
-    }
+  const uint32_t gdb_event_mask =
+      Communication::eBroadcastBitReadThreadDidExit |
+      GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify;
+  if (m_async_listener_sp->StartListeningForEvents(
+          &m_gdb_comm, gdb_event_mask) != gdb_event_mask) {
+    if (log)
+      log->Printf("ProcessGDBRemote::%s failed to listen for m_gdb_comm events",
+                  __FUNCTION__);
+  }
 
-    const uint64_t timeout_seconds = GetGlobalPluginProperties()->GetPacketTimeout();
-    if (timeout_seconds > 0)
-        m_gdb_comm.SetPacketTimeout(timeout_seconds);
+  const uint64_t timeout_seconds =
+      GetGlobalPluginProperties()->GetPacketTimeout();
+  if (timeout_seconds > 0)
+    m_gdb_comm.SetPacketTimeout(timeout_seconds);
 }
 
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
-ProcessGDBRemote::~ProcessGDBRemote()
-{
-    //  m_mach_process.UnregisterNotificationCallbacks (this);
-    Clear();
-    // We need to call finalize on the process before destroying ourselves
-    // to make sure all of the broadcaster cleanup goes as planned. If we
-    // destruct this class, then Process::~Process() might have problems
-    // trying to fully destroy the broadcaster.
-    Finalize();
+ProcessGDBRemote::~ProcessGDBRemote() {
+  //  m_mach_process.UnregisterNotificationCallbacks (this);
+  Clear();
+  // We need to call finalize on the process before destroying ourselves
+  // to make sure all of the broadcaster cleanup goes as planned. If we
+  // destruct this class, then Process::~Process() might have problems
+  // trying to fully destroy the broadcaster.
+  Finalize();
 
-    // The general Finalize is going to try to destroy the process and that SHOULD
-    // shut down the async thread.  However, if we don't kill it it will get stranded and
-    // its connection will go away so when it wakes up it will crash.  So kill it for sure here.
-    StopAsyncThread();
-    KillDebugserverProcess();
+  // The general Finalize is going to try to destroy the process and that SHOULD
+  // shut down the async thread.  However, if we don't kill it it will get
+  // stranded and
+  // its connection will go away so when it wakes up it will crash.  So kill it
+  // for sure here.
+  StopAsyncThread();
+  KillDebugserverProcess();
 }
 
 //----------------------------------------------------------------------
 // PluginInterface
 //----------------------------------------------------------------------
-ConstString
-ProcessGDBRemote::GetPluginName()
-{
-    return GetPluginNameStatic();
-}
+ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); }
 
-uint32_t
-ProcessGDBRemote::GetPluginVersion()
-{
-    return 1;
-}
+uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; }
 
-bool
-ProcessGDBRemote::ParsePythonTargetDefinition(const FileSpec &target_definition_fspec)
-{
-    ScriptInterpreter *interpreter = GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
-    Error error;
-    StructuredData::ObjectSP module_object_sp(interpreter->LoadPluginModule(target_definition_fspec, error));
-    if (module_object_sp)
-    {
-        StructuredData::DictionarySP target_definition_sp(
-            interpreter->GetDynamicSettings(module_object_sp, &GetTarget(), "gdb-server-target-definition", error));
+bool ProcessGDBRemote::ParsePythonTargetDefinition(
+    const FileSpec &target_definition_fspec) {
+  ScriptInterpreter *interpreter =
+      GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+  Error error;
+  StructuredData::ObjectSP module_object_sp(
+      interpreter->LoadPluginModule(target_definition_fspec, error));
+  if (module_object_sp) {
+    StructuredData::DictionarySP target_definition_sp(
+        interpreter->GetDynamicSettings(module_object_sp, &GetTarget(),
+                                        "gdb-server-target-definition", error));
 
-        if (target_definition_sp)
-        {
-            StructuredData::ObjectSP target_object(target_definition_sp->GetValueForKey("host-info"));
-            if (target_object)
-            {
-                if (auto host_info_dict = target_object->GetAsDictionary())
-                {
-                    StructuredData::ObjectSP triple_value = host_info_dict->GetValueForKey("triple");
-                    if (auto triple_string_value = triple_value->GetAsString())
-                    {
-                        std::string triple_string = triple_string_value->GetValue();
-                        ArchSpec host_arch(triple_string.c_str());
-                        if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture()))
-                        {
-                            GetTarget().SetArchitecture(host_arch);
-                        }
-                    }
-                }
+    if (target_definition_sp) {
+      StructuredData::ObjectSP target_object(
+          target_definition_sp->GetValueForKey("host-info"));
+      if (target_object) {
+        if (auto host_info_dict = target_object->GetAsDictionary()) {
+          StructuredData::ObjectSP triple_value =
+              host_info_dict->GetValueForKey("triple");
+          if (auto triple_string_value = triple_value->GetAsString()) {
+            std::string triple_string = triple_string_value->GetValue();
+            ArchSpec host_arch(triple_string.c_str());
+            if (!host_arch.IsCompatibleMatch(GetTarget().GetArchitecture())) {
+              GetTarget().SetArchitecture(host_arch);
             }
-            m_breakpoint_pc_offset = 0;
-            StructuredData::ObjectSP breakpoint_pc_offset_value = target_definition_sp->GetValueForKey("breakpoint-pc-offset");
-            if (breakpoint_pc_offset_value)
-            {
-                if (auto breakpoint_pc_int_value = breakpoint_pc_offset_value->GetAsInteger())
-                    m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
-            }
-
-            if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture()) > 0)
-            {
-                return true;
-            }
+          }
         }
+      }
+      m_breakpoint_pc_offset = 0;
+      StructuredData::ObjectSP breakpoint_pc_offset_value =
+          target_definition_sp->GetValueForKey("breakpoint-pc-offset");
+      if (breakpoint_pc_offset_value) {
+        if (auto breakpoint_pc_int_value =
+                breakpoint_pc_offset_value->GetAsInteger())
+          m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
+      }
+
+      if (m_register_info.SetRegisterInfo(*target_definition_sp,
+                                          GetTarget().GetArchitecture()) > 0) {
+        return true;
+      }
     }
-    return false;
+  }
+  return false;
 }
 
-// If the remote stub didn't give us eh_frame or DWARF register numbers for a register,
+// If the remote stub didn't give us eh_frame or DWARF register numbers for a
+// register,
 // see if the ABI can provide them.
 // DWARF and eh_frame register numbers are defined as a part of the ABI.
-static void
-AugmentRegisterInfoViaABI (RegisterInfo &reg_info, ConstString reg_name, ABISP abi_sp)
-{
-    if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM
-        || reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM)
-    {
-        if (abi_sp)
-        {
-            RegisterInfo abi_reg_info;
-            if (abi_sp->GetRegisterInfoByName (reg_name, abi_reg_info))
+static void AugmentRegisterInfoViaABI(RegisterInfo &reg_info,
+                                      ConstString reg_name, ABISP abi_sp) {
+  if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM ||
+      reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) {
+    if (abi_sp) {
+      RegisterInfo abi_reg_info;
+      if (abi_sp->GetRegisterInfoByName(reg_name, abi_reg_info)) {
+        if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
+            abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM) {
+          reg_info.kinds[eRegisterKindEHFrame] =
+              abi_reg_info.kinds[eRegisterKindEHFrame];
+        }
+        if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
+            abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) {
+          reg_info.kinds[eRegisterKindDWARF] =
+              abi_reg_info.kinds[eRegisterKindDWARF];
+        }
+        if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
+            abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) {
+          reg_info.kinds[eRegisterKindGeneric] =
+              abi_reg_info.kinds[eRegisterKindGeneric];
+        }
+      }
+    }
+  }
+}
+
+static size_t SplitCommaSeparatedRegisterNumberString(
+    const llvm::StringRef &comma_separated_regiter_numbers,
+    std::vector<uint32_t> &regnums, int base) {
+  regnums.clear();
+  std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+  value_pair.second = comma_separated_regiter_numbers;
+  do {
+    value_pair = value_pair.second.split(',');
+    if (!value_pair.first.empty()) {
+      uint32_t reg = StringConvert::ToUInt32(value_pair.first.str().c_str(),
+                                             LLDB_INVALID_REGNUM, base);
+      if (reg != LLDB_INVALID_REGNUM)
+        regnums.push_back(reg);
+    }
+  } while (!value_pair.second.empty());
+  return regnums.size();
+}
+
+void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
+  if (!force && m_register_info.GetNumRegisters() > 0)
+    return;
+
+  m_register_info.Clear();
+
+  // Check if qHostInfo specified a specific packet timeout for this connection.
+  // If so then lets update our setting so the user knows what the timeout is
+  // and can see it.
+  const uint32_t host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
+  if (host_packet_timeout) {
+    GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout);
+  }
+
+  // Register info search order:
+  //     1 - Use the target definition python file if one is specified.
+  //     2 - If the target definition doesn't have any of the info from the
+  //     target.xml (registers) then proceed to read the target.xml.
+  //     3 - Fall back on the qRegisterInfo packets.
+
+  FileSpec target_definition_fspec =
+      GetGlobalPluginProperties()->GetTargetDefinitionFile();
+  if (!target_definition_fspec.Exists()) {
+    // If the filename doesn't exist, it may be a ~ not having been expanded -
+    // try to resolve it.
+    target_definition_fspec.ResolvePath();
+  }
+  if (target_definition_fspec) {
+    // See if we can get register definitions from a python file
+    if (ParsePythonTargetDefinition(target_definition_fspec)) {
+      return;
+    } else {
+      StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
+      stream_sp->Printf("ERROR: target description file %s failed to parse.\n",
+                        target_definition_fspec.GetPath().c_str());
+    }
+  }
+
+  const ArchSpec &target_arch = GetTarget().GetArchitecture();
+  const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+  const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+  // Use the process' architecture instead of the host arch, if available
+  ArchSpec arch_to_use;
+  if (remote_process_arch.IsValid())
+    arch_to_use = remote_process_arch;
+  else
+    arch_to_use = remote_host_arch;
+
+  if (!arch_to_use.IsValid())
+    arch_to_use = target_arch;
+
+  if (GetGDBServerRegisterInfo(arch_to_use))
+    return;
+
+  char packet[128];
+  uint32_t reg_offset = 0;
+  uint32_t reg_num = 0;
+  for (StringExtractorGDBRemote::ResponseType response_type =
+           StringExtractorGDBRemote::eResponse;
+       response_type == StringExtractorGDBRemote::eResponse; ++reg_num) {
+    const int packet_len =
+        ::snprintf(packet, sizeof(packet), "qRegisterInfo%x", reg_num);
+    assert(packet_len < (int)sizeof(packet));
+    StringExtractorGDBRemote response;
+    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response,
+                                                false) ==
+        GDBRemoteCommunication::PacketResult::Success) {
+      response_type = response.GetResponseType();
+      if (response_type == StringExtractorGDBRemote::eResponse) {
+        llvm::StringRef name;
+        llvm::StringRef value;
+        ConstString reg_name;
+        ConstString alt_name;
+        ConstString set_name;
+        std::vector<uint32_t> value_regs;
+        std::vector<uint32_t> invalidate_regs;
+        std::vector<uint8_t> dwarf_opcode_bytes;
+        RegisterInfo reg_info = {
+            NULL,          // Name
+            NULL,          // Alt name
+            0,             // byte size
+            reg_offset,    // offset
+            eEncodingUint, // encoding
+            eFormatHex,    // format
             {
-                if (reg_info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM &&
-                    abi_reg_info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM)
-                {
-                    reg_info.kinds[eRegisterKindEHFrame] = abi_reg_info.kinds[eRegisterKindEHFrame];
-                }
-                if (reg_info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM &&
-                    abi_reg_info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM)
-                {
-                    reg_info.kinds[eRegisterKindDWARF] = abi_reg_info.kinds[eRegisterKindDWARF];
-                }
-                if (reg_info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM &&
-                    abi_reg_info.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
-                {
-                    reg_info.kinds[eRegisterKindGeneric] = abi_reg_info.kinds[eRegisterKindGeneric];
-                }
+                LLDB_INVALID_REGNUM, // eh_frame reg num
+                LLDB_INVALID_REGNUM, // DWARF reg num
+                LLDB_INVALID_REGNUM, // generic reg num
+                reg_num,             // process plugin reg num
+                reg_num              // native register number
+            },
+            NULL,
+            NULL,
+            NULL, // Dwarf expression opcode bytes pointer
+            0     // Dwarf expression opcode bytes length
+        };
+
+        while (response.GetNameColonValue(name, value)) {
+          if (name.equals("name")) {
+            reg_name.SetString(value);
+          } else if (name.equals("alt-name")) {
+            alt_name.SetString(value);
+          } else if (name.equals("bitsize")) {
+            value.getAsInteger(0, reg_info.byte_size);
+            reg_info.byte_size /= CHAR_BIT;
+          } else if (name.equals("offset")) {
+            if (value.getAsInteger(0, reg_offset))
+              reg_offset = UINT32_MAX;
+          } else if (name.equals("encoding")) {
+            const Encoding encoding = Args::StringToEncoding(value);
+            if (encoding != eEncodingInvalid)
+              reg_info.encoding = encoding;
+          } else if (name.equals("format")) {
+            Format format = eFormatInvalid;
+            if (Args::StringToFormat(value.str().c_str(), format, NULL)
+                    .Success())
+              reg_info.format = format;
+            else {
+              reg_info.format =
+                  llvm::StringSwitch<Format>(value)
+                      .Case("binary", eFormatBinary)
+                      .Case("decimal", eFormatDecimal)
+                      .Case("hex", eFormatHex)
+                      .Case("float", eFormatFloat)
+                      .Case("vector-sint8", eFormatVectorOfSInt8)
+                      .Case("vector-uint8", eFormatVectorOfUInt8)
+                      .Case("vector-sint16", eFormatVectorOfSInt16)
+                      .Case("vector-uint16", eFormatVectorOfUInt16)
+                      .Case("vector-sint32", eFormatVectorOfSInt32)
+                      .Case("vector-uint32", eFormatVectorOfUInt32)
+                      .Case("vector-float32", eFormatVectorOfFloat32)
+                      .Case("vector-uint128", eFormatVectorOfUInt128)
+                      .Default(eFormatInvalid);
             }
+          } else if (name.equals("set")) {
+            set_name.SetString(value);
+          } else if (name.equals("gcc") || name.equals("ehframe")) {
+            if (value.getAsInteger(0, reg_info.kinds[eRegisterKindEHFrame]))
+              reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
+          } else if (name.equals("dwarf")) {
+            if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF]))
+              reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
+          } else if (name.equals("generic")) {
+            reg_info.kinds[eRegisterKindGeneric] =
+                Args::StringToGenericRegister(value);
+          } else if (name.equals("container-regs")) {
+            SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
+          } else if (name.equals("invalidate-regs")) {
+            SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
+          } else if (name.equals("dynamic_size_dwarf_expr_bytes")) {
+            size_t dwarf_opcode_len = value.size() / 2;
+            assert(dwarf_opcode_len > 0);
+
+            dwarf_opcode_bytes.resize(dwarf_opcode_len);
+            reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
+
+            StringExtractor opcode_extractor(value);
+            uint32_t ret_val =
+                opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+            assert(dwarf_opcode_len == ret_val);
+
+            reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
+          }
         }
+
+        reg_info.byte_offset = reg_offset;
+        assert(reg_info.byte_size != 0);
+        reg_offset += reg_info.byte_size;
+        if (!value_regs.empty()) {
+          value_regs.push_back(LLDB_INVALID_REGNUM);
+          reg_info.value_regs = value_regs.data();
+        }
+        if (!invalidate_regs.empty()) {
+          invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+          reg_info.invalidate_regs = invalidate_regs.data();
+        }
+
+        // We have to make a temporary ABI here, and not use the GetABI because
+        // this code
+        // gets called in DidAttach, when the target architecture (and
+        // consequently the ABI we'll get from
+        // the process) may be wrong.
+        ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
+
+        AugmentRegisterInfoViaABI(reg_info, reg_name, abi_to_use);
+
+        m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+      } else {
+        break; // ensure exit before reg_num is incremented
+      }
+    } else {
+      break;
     }
+  }
+
+  if (m_register_info.GetNumRegisters() > 0) {
+    m_register_info.Finalize(GetTarget().GetArchitecture());
+    return;
+  }
+
+  // We didn't get anything if the accumulated reg_num is zero.  See if we are
+  // debugging ARM and fill with a hard coded register set until we can get an
+  // updated debugserver down on the devices.
+  // On the other hand, if the accumulated reg_num is positive, see if we can
+  // add composite registers to the existing primordial ones.
+  bool from_scratch = (m_register_info.GetNumRegisters() == 0);
+
+  if (!target_arch.IsValid()) {
+    if (arch_to_use.IsValid() &&
+        (arch_to_use.GetMachine() == llvm::Triple::arm ||
+         arch_to_use.GetMachine() == llvm::Triple::thumb) &&
+        arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
+      m_register_info.HardcodeARMRegisters(from_scratch);
+  } else if (target_arch.GetMachine() == llvm::Triple::arm ||
+             target_arch.GetMachine() == llvm::Triple::thumb) {
+    m_register_info.HardcodeARMRegisters(from_scratch);
+  }
+
+  // At this point, we can finalize our register info.
+  m_register_info.Finalize(GetTarget().GetArchitecture());
 }
 
-static size_t
-SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_regiter_numbers, std::vector<uint32_t> &regnums, int base)
-{
-    regnums.clear();
-    std::pair<llvm::StringRef, llvm::StringRef> value_pair;
-    value_pair.second = comma_separated_regiter_numbers;
-    do
-    {
-        value_pair = value_pair.second.split(',');
-        if (!value_pair.first.empty())
-        {
-            uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, base);
-            if (reg != LLDB_INVALID_REGNUM)
-                regnums.push_back (reg);
-        }
-    } while (!value_pair.second.empty());
-    return regnums.size();
+Error ProcessGDBRemote::WillLaunch(Module *module) {
+  return WillLaunchOrAttach();
 }
 
-
-void
-ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
-{
-    if (!force && m_register_info.GetNumRegisters() > 0)
-        return;
-
-    m_register_info.Clear();
-
-    // Check if qHostInfo specified a specific packet timeout for this connection.
-    // If so then lets update our setting so the user knows what the timeout is
-    // and can see it.
-    const uint32_t host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
-    if (host_packet_timeout)
-    {
-        GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout);
-    }
-
-    // Register info search order:
-    //     1 - Use the target definition python file if one is specified.
-    //     2 - If the target definition doesn't have any of the info from the target.xml (registers) then proceed to read the target.xml.
-    //     3 - Fall back on the qRegisterInfo packets.
-
-    FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();
-    if (!target_definition_fspec.Exists())
-    {
-        // If the filename doesn't exist, it may be a ~ not having been expanded - try to resolve it.
-        target_definition_fspec.ResolvePath();
-    }
-    if (target_definition_fspec)
-    {
-        // See if we can get register definitions from a python file
-        if (ParsePythonTargetDefinition (target_definition_fspec))
-        {
-            return;
-        }
-        else
-        {
-            StreamSP stream_sp = GetTarget().GetDebugger().GetAsyncOutputStream();
-            stream_sp->Printf ("ERROR: target description file %s failed to parse.\n", target_definition_fspec.GetPath().c_str());
-        }
-    }
-
-    const ArchSpec &target_arch = GetTarget().GetArchitecture();
-    const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
-    const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
-
-    // Use the process' architecture instead of the host arch, if available
-    ArchSpec arch_to_use;
-    if (remote_process_arch.IsValid ())
-        arch_to_use = remote_process_arch;
-    else
-        arch_to_use = remote_host_arch;
-    
-    if (!arch_to_use.IsValid())
-        arch_to_use = target_arch;
-
-    if (GetGDBServerRegisterInfo (arch_to_use))
-        return;
-
-    char packet[128];
-    uint32_t reg_offset = 0;
-    uint32_t reg_num = 0;
-    for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse;
-         response_type == StringExtractorGDBRemote::eResponse;
-         ++reg_num)
-    {
-        const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
-        assert (packet_len < (int)sizeof(packet));
-        StringExtractorGDBRemote response;
-        if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
-        {
-            response_type = response.GetResponseType();
-            if (response_type == StringExtractorGDBRemote::eResponse)
-            {
-                llvm::StringRef name;
-                llvm::StringRef value;
-                ConstString reg_name;
-                ConstString alt_name;
-                ConstString set_name;
-                std::vector<uint32_t> value_regs;
-                std::vector<uint32_t> invalidate_regs;
-                std::vector<uint8_t> dwarf_opcode_bytes;
-                RegisterInfo reg_info = { NULL,                 // Name
-                    NULL,                 // Alt name
-                    0,                    // byte size
-                    reg_offset,           // offset
-                    eEncodingUint,        // encoding
-                    eFormatHex,           // format
-                    {
-                        LLDB_INVALID_REGNUM, // eh_frame reg num
-                        LLDB_INVALID_REGNUM, // DWARF reg num
-                        LLDB_INVALID_REGNUM, // generic reg num
-                        reg_num,             // process plugin reg num
-                        reg_num           // native register number
-                    },
-                    NULL,
-                    NULL,
-                    NULL, // Dwarf expression opcode bytes pointer
-                    0     // Dwarf expression opcode bytes length
-                };
-
-                while (response.GetNameColonValue(name, value))
-                {
-                    if (name.equals("name"))
-                    {
-                        reg_name.SetString(value);
-                    }
-                    else if (name.equals("alt-name"))
-                    {
-                        alt_name.SetString(value);
-                    }
-                    else if (name.equals("bitsize"))
-                    {
-                        value.getAsInteger(0, reg_info.byte_size);
-                        reg_info.byte_size /= CHAR_BIT;
-                    }
-                    else if (name.equals("offset"))
-                    {
-                        if (value.getAsInteger(0, reg_offset))
-                            reg_offset = UINT32_MAX;
-                    }
-                    else if (name.equals("encoding"))
-                    {
-                        const Encoding encoding = Args::StringToEncoding(value);
-                        if (encoding != eEncodingInvalid)
-                            reg_info.encoding = encoding;
-                    }
-                    else if (name.equals("format"))
-                    {
-                        Format format = eFormatInvalid;
-                        if (Args::StringToFormat(value.str().c_str(), format, NULL).Success())
-                            reg_info.format = format;
-                        else
-                        {
-                            reg_info.format = llvm::StringSwitch<Format>(value)
-                                                  .Case("binary", eFormatBinary)
-                                                  .Case("decimal", eFormatDecimal)
-                                                  .Case("hex", eFormatHex)
-                                                  .Case("float", eFormatFloat)
-                                                  .Case("vector-sint8", eFormatVectorOfSInt8)
-                                                  .Case("vector-uint8", eFormatVectorOfUInt8)
-                                                  .Case("vector-sint16", eFormatVectorOfSInt16)
-                                                  .Case("vector-uint16", eFormatVectorOfUInt16)
-                                                  .Case("vector-sint32", eFormatVectorOfSInt32)
-                                                  .Case("vector-uint32", eFormatVectorOfUInt32)
-                                                  .Case("vector-float32", eFormatVectorOfFloat32)
-                                                  .Case("vector-uint128", eFormatVectorOfUInt128)
-                                                  .Default(eFormatInvalid);
-                        }
-                    }
-                    else if (name.equals("set"))
-                    {
-                        set_name.SetString(value);
-                    }
-                    else if (name.equals("gcc") || name.equals("ehframe"))
-                    {
-                        if (value.getAsInteger(0, reg_info.kinds[eRegisterKindEHFrame]))
-                            reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM;
-                    }
-                    else if (name.equals("dwarf"))
-                    {
-                        if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF]))
-                            reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM;
-                    }
-                    else if (name.equals("generic"))
-                    {
-                        reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value);
-                    }
-                    else if (name.equals("container-regs"))
-                    {
-                        SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
-                    }
-                    else if (name.equals("invalidate-regs"))
-                    {
-                        SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
-                    }
-                    else if (name.equals("dynamic_size_dwarf_expr_bytes"))
-                    {
-                        size_t dwarf_opcode_len = value.size() / 2;
-                        assert(dwarf_opcode_len > 0);
-
-                        dwarf_opcode_bytes.resize(dwarf_opcode_len);
-                        reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
-
-                        StringExtractor opcode_extractor(value);
-                        uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
-                        assert(dwarf_opcode_len == ret_val);
-
-                        reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
-                    }
-                }
-
-                reg_info.byte_offset = reg_offset;
-                assert (reg_info.byte_size != 0);
-                reg_offset += reg_info.byte_size;
-                if (!value_regs.empty())
-                {
-                    value_regs.push_back(LLDB_INVALID_REGNUM);
-                    reg_info.value_regs = value_regs.data();
-                }
-                if (!invalidate_regs.empty())
-                {
-                    invalidate_regs.push_back(LLDB_INVALID_REGNUM);
-                    reg_info.invalidate_regs = invalidate_regs.data();
-                }
-
-                // We have to make a temporary ABI here, and not use the GetABI because this code
-                // gets called in DidAttach, when the target architecture (and consequently the ABI we'll get from
-                // the process) may be wrong.
-                ABISP abi_to_use = ABI::FindPlugin(arch_to_use);
-
-                AugmentRegisterInfoViaABI (reg_info, reg_name, abi_to_use);
-
-                m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
-            }
-            else
-            {
-                break;  // ensure exit before reg_num is incremented
-            }
-        }
-        else
-        {
-            break;
-        }
-    }
-
-    if (m_register_info.GetNumRegisters() > 0)
-    {
-        m_register_info.Finalize(GetTarget().GetArchitecture());
-        return;
-    }
-
-    // We didn't get anything if the accumulated reg_num is zero.  See if we are
-    // debugging ARM and fill with a hard coded register set until we can get an
-    // updated debugserver down on the devices.
-    // On the other hand, if the accumulated reg_num is positive, see if we can
-    // add composite registers to the existing primordial ones.
-    bool from_scratch = (m_register_info.GetNumRegisters() == 0);
-
-    if (!target_arch.IsValid())
-    {
-        if (arch_to_use.IsValid()
-              && (arch_to_use.GetMachine() == llvm::Triple::arm || arch_to_use.GetMachine() == llvm::Triple::thumb)
-              && arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple)
-            m_register_info.HardcodeARMRegisters(from_scratch);
-    }
-    else if (target_arch.GetMachine() == llvm::Triple::arm
-            || target_arch.GetMachine() == llvm::Triple::thumb)
-    {
-        m_register_info.HardcodeARMRegisters(from_scratch);
-    }
-
-    // At this point, we can finalize our register info.
-    m_register_info.Finalize (GetTarget().GetArchitecture());
+Error ProcessGDBRemote::WillAttachToProcessWithID(lldb::pid_t pid) {
+  return WillLaunchOrAttach();
 }
 
-Error
-ProcessGDBRemote::WillLaunch (Module* module)
-{
-    return WillLaunchOrAttach ();
+Error ProcessGDBRemote::WillAttachToProcessWithName(const char *process_name,
+                                                    bool wait_for_launch) {
+  return WillLaunchOrAttach();
 }
 
-Error
-ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid)
-{
-    return WillLaunchOrAttach ();
-}
+Error ProcessGDBRemote::DoConnectRemote(Stream *strm, const char *remote_url) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  Error error(WillLaunchOrAttach());
 
-Error
-ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch)
-{
-    return WillLaunchOrAttach ();
-}
-
-Error
-ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    Error error (WillLaunchOrAttach ());
-
-    if (error.Fail())
-        return error;
-
-    error = ConnectToDebugserver (remote_url);
-
-    if (error.Fail())
-        return error;
-    StartAsyncThread ();
-
-    lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
-    if (pid == LLDB_INVALID_PROCESS_ID)
-    {
-        // We don't have a valid process ID, so note that we are connected
-        // and could now request to launch or attach, or get remote process
-        // listings...
-        SetPrivateState (eStateConnected);
-    }
-    else
-    {
-        // We have a valid process
-        SetID (pid);
-        GetThreadList();
-        StringExtractorGDBRemote response;
-        if (m_gdb_comm.GetStopReply(response))
-        {
-            SetLastStopPacket(response);
-
-            // '?' Packets must be handled differently in non-stop mode
-            if (GetTarget().GetNonStopModeEnabled())
-                HandleStopReplySequence();
-
-            Target &target = GetTarget();
-            if (!target.GetArchitecture().IsValid())
-            {
-                if (m_gdb_comm.GetProcessArchitecture().IsValid())
-                {
-                    target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
-                }
-                else
-                {
-                    target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
-                }
-            }
-
-            const StateType state = SetThreadStopInfo (response);
-            if (state != eStateInvalid)
-            {
-                SetPrivateState (state);
-            }
-            else
-                error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
-        }
-        else
-            error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
-    }
-
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalizing target architecture initial triple: %s (GetTarget().GetArchitecture().IsValid() %s, m_gdb_comm.GetHostArchitecture().IsValid(): %s)", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str (), GetTarget ().GetArchitecture ().IsValid () ? "true" : "false", m_gdb_comm.GetHostArchitecture ().IsValid () ? "true" : "false");
-
-
-    if (error.Success()
-        && !GetTarget().GetArchitecture().IsValid()
-        && m_gdb_comm.GetHostArchitecture().IsValid())
-    {
-        // Prefer the *process'* architecture over that of the *host*, if available.
-        if (m_gdb_comm.GetProcessArchitecture().IsValid())
-            GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
-        else
-            GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
-    }
-
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ());
-
-    if (error.Success())
-    {
-        PlatformSP platform_sp = GetTarget().GetPlatform();
-        if (platform_sp && platform_sp->IsConnected())
-            SetUnixSignals(platform_sp->GetUnixSignals());
-        else
-            SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));
-    }
-
+  if (error.Fail())
     return error;
+
+  error = ConnectToDebugserver(remote_url);
+
+  if (error.Fail())
+    return error;
+  StartAsyncThread();
+
+  lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+  if (pid == LLDB_INVALID_PROCESS_ID) {
+    // We don't have a valid process ID, so note that we are connected
+    // and could now request to launch or attach, or get remote process
+    // listings...
+    SetPrivateState(eStateConnected);
+  } else {
+    // We have a valid process
+    SetID(pid);
+    GetThreadList();
+    StringExtractorGDBRemote response;
+    if (m_gdb_comm.GetStopReply(response)) {
+      SetLastStopPacket(response);
+
+      // '?' Packets must be handled differently in non-stop mode
+      if (GetTarget().GetNonStopModeEnabled())
+        HandleStopReplySequence();
+
+      Target &target = GetTarget();
+      if (!target.GetArchitecture().IsValid()) {
+        if (m_gdb_comm.GetProcessArchitecture().IsValid()) {
+          target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+        } else {
+          target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+        }
+      }
+
+      const StateType state = SetThreadStopInfo(response);
+      if (state != eStateInvalid) {
+        SetPrivateState(state);
+      } else
+        error.SetErrorStringWithFormat("Process %" PRIu64
+                                       " was reported after connecting to "
+                                       "'%s', but state was not stopped: %s",
+                                       pid, remote_url, StateAsCString(state));
+    } else
+      error.SetErrorStringWithFormat("Process %" PRIu64
+                                     " was reported after connecting to '%s', "
+                                     "but no stop reply packet was received",
+                                     pid, remote_url);
+  }
+
+  if (log)
+    log->Printf("ProcessGDBRemote::%s pid %" PRIu64
+                ": normalizing target architecture initial triple: %s "
+                "(GetTarget().GetArchitecture().IsValid() %s, "
+                "m_gdb_comm.GetHostArchitecture().IsValid(): %s)",
+                __FUNCTION__, GetID(),
+                GetTarget().GetArchitecture().GetTriple().getTriple().c_str(),
+                GetTarget().GetArchitecture().IsValid() ? "true" : "false",
+                m_gdb_comm.GetHostArchitecture().IsValid() ? "true" : "false");
+
+  if (error.Success() && !GetTarget().GetArchitecture().IsValid() &&
+      m_gdb_comm.GetHostArchitecture().IsValid()) {
+    // Prefer the *process'* architecture over that of the *host*, if available.
+    if (m_gdb_comm.GetProcessArchitecture().IsValid())
+      GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+    else
+      GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
+  }
+
+  if (log)
+    log->Printf("ProcessGDBRemote::%s pid %" PRIu64
+                ": normalized target architecture triple: %s",
+                __FUNCTION__, GetID(),
+                GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
+
+  if (error.Success()) {
+    PlatformSP platform_sp = GetTarget().GetPlatform();
+    if (platform_sp && platform_sp->IsConnected())
+      SetUnixSignals(platform_sp->GetUnixSignals());
+    else
+      SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture()));
+  }
+
+  return error;
 }
 
-Error
-ProcessGDBRemote::WillLaunchOrAttach ()
-{
-    Error error;
-    m_stdio_communication.Clear ();
-    return error;
+Error ProcessGDBRemote::WillLaunchOrAttach() {
+  Error error;
+  m_stdio_communication.Clear();
+  return error;
 }
 
 //----------------------------------------------------------------------
 // Process Control
 //----------------------------------------------------------------------
-Error
-ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    Error error;
+Error ProcessGDBRemote::DoLaunch(Module *exe_module,
+                                 ProcessLaunchInfo &launch_info) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  Error error;
 
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s() entered", __FUNCTION__);
+  if (log)
+    log->Printf("ProcessGDBRemote::%s() entered", __FUNCTION__);
 
-    uint32_t launch_flags = launch_info.GetFlags().Get();
-    FileSpec stdin_file_spec{};
-    FileSpec stdout_file_spec{};
-    FileSpec stderr_file_spec{};
-    FileSpec working_dir = launch_info.GetWorkingDirectory();
+  uint32_t launch_flags = launch_info.GetFlags().Get();
+  FileSpec stdin_file_spec{};
+  FileSpec stdout_file_spec{};
+  FileSpec stderr_file_spec{};
+  FileSpec working_dir = launch_info.GetWorkingDirectory();
 
-    const FileAction *file_action;
-    file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
-    if (file_action)
-    {
-        if (file_action->GetAction() == FileAction::eFileActionOpen)
-            stdin_file_spec = file_action->GetFileSpec();
-    }
-    file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
-    if (file_action)
-    {
-        if (file_action->GetAction() == FileAction::eFileActionOpen)
-            stdout_file_spec = file_action->GetFileSpec();
-    }
-    file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
-    if (file_action)
-    {
-        if (file_action->GetAction() == FileAction::eFileActionOpen)
-            stderr_file_spec = file_action->GetFileSpec();
-    }
+  const FileAction *file_action;
+  file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
+  if (file_action) {
+    if (file_action->GetAction() == FileAction::eFileActionOpen)
+      stdin_file_spec = file_action->GetFileSpec();
+  }
+  file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
+  if (file_action) {
+    if (file_action->GetAction() == FileAction::eFileActionOpen)
+      stdout_file_spec = file_action->GetFileSpec();
+  }
+  file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
+  if (file_action) {
+    if (file_action->GetAction() == FileAction::eFileActionOpen)
+      stderr_file_spec = file_action->GetFileSpec();
+  }
 
-    if (log)
-    {
-        if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
-            log->Printf ("ProcessGDBRemote::%s provided with STDIO paths via launch_info: stdin=%s, stdout=%s, stderr=%s",
-                         __FUNCTION__,
-                          stdin_file_spec ?  stdin_file_spec.GetCString() : "<null>",
-                         stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
-                         stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
-        else
-            log->Printf ("ProcessGDBRemote::%s no STDIO paths given via launch_info", __FUNCTION__);
-    }
-
-    const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
-    if (stdin_file_spec || disable_stdio)
-    {
-        // the inferior will be reading stdin from the specified file
-        // or stdio is completely disabled
-        m_stdin_forward = false;
-    }
+  if (log) {
+    if (stdin_file_spec || stdout_file_spec || stderr_file_spec)
+      log->Printf("ProcessGDBRemote::%s provided with STDIO paths via "
+                  "launch_info: stdin=%s, stdout=%s, stderr=%s",
+                  __FUNCTION__,
+                  stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+                  stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+                  stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
     else
-    {
-        m_stdin_forward = true;
-    }
+      log->Printf("ProcessGDBRemote::%s no STDIO paths given via launch_info",
+                  __FUNCTION__);
+  }
 
-    //  ::LogSetBitMask (GDBR_LOG_DEFAULT);
-    //  ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
-    //  ::LogSetLogFile ("/dev/stdout");
+  const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
+  if (stdin_file_spec || disable_stdio) {
+    // the inferior will be reading stdin from the specified file
+    // or stdio is completely disabled
+    m_stdin_forward = false;
+  } else {
+    m_stdin_forward = true;
+  }
 
-    ObjectFile * object_file = exe_module->GetObjectFile();
-    if (object_file)
-    {
-        error = EstablishConnectionIfNeeded (launch_info);
-        if (error.Success())
-        {
-            lldb_utility::PseudoTerminal pty;
-            const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
+  //  ::LogSetBitMask (GDBR_LOG_DEFAULT);
+  //  ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE |
+  //  LLDB_LOG_OPTION_PREPEND_TIMESTAMP |
+  //  LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
+  //  ::LogSetLogFile ("/dev/stdout");
 
-            PlatformSP platform_sp (GetTarget().GetPlatform());
-            if (disable_stdio)
-            {
-                // set to /dev/null unless redirected to a file above
-                if (!stdin_file_spec)
-                    stdin_file_spec.SetFile(FileSystem::DEV_NULL, false);
-                if (!stdout_file_spec)
-                    stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
-                if (!stderr_file_spec)
-                    stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
-            }
-            else if (platform_sp && platform_sp->IsHost())
-            {
-                // If the debugserver is local and we aren't disabling STDIO, lets use
-                // a pseudo terminal to instead of relying on the 'O' packets for stdio
-                // since 'O' packets can really slow down debugging if the inferior
-                // does a lot of output.
-                if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
-                        pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0))
-                {
-                    FileSpec slave_name{pty.GetSlaveName(NULL, 0), false};
+  ObjectFile *object_file = exe_module->GetObjectFile();
+  if (object_file) {
+    error = EstablishConnectionIfNeeded(launch_info);
+    if (error.Success()) {
+      lldb_utility::PseudoTerminal pty;
+      const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0;
 
-                    if (!stdin_file_spec)
-                        stdin_file_spec = slave_name;
+      PlatformSP platform_sp(GetTarget().GetPlatform());
+      if (disable_stdio) {
+        // set to /dev/null unless redirected to a file above
+        if (!stdin_file_spec)
+          stdin_file_spec.SetFile(FileSystem::DEV_NULL, false);
+        if (!stdout_file_spec)
+          stdout_file_spec.SetFile(FileSystem::DEV_NULL, false);
+        if (!stderr_file_spec)
+          stderr_file_spec.SetFile(FileSystem::DEV_NULL, false);
+      } else if (platform_sp && platform_sp->IsHost()) {
+        // If the debugserver is local and we aren't disabling STDIO, lets use
+        // a pseudo terminal to instead of relying on the 'O' packets for stdio
+        // since 'O' packets can really slow down debugging if the inferior
+        // does a lot of output.
+        if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) &&
+            pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, NULL, 0)) {
+          FileSpec slave_name{pty.GetSlaveName(NULL, 0), false};
 
-                    if (!stdout_file_spec)
-                        stdout_file_spec = slave_name;
+          if (!stdin_file_spec)
+            stdin_file_spec = slave_name;
 
-                    if (!stderr_file_spec)
-                        stderr_file_spec = slave_name;
-                }
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s adjusted STDIO paths for local platform (IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
-                                 __FUNCTION__,
-                                  stdin_file_spec ?  stdin_file_spec.GetCString() : "<null>",
-                                 stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
-                                 stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
-            }
+          if (!stdout_file_spec)
+            stdout_file_spec = slave_name;
 
-            if (log)
-                log->Printf ("ProcessGDBRemote::%s final STDIO paths after all adjustments: stdin=%s, stdout=%s, stderr=%s",
-                             __FUNCTION__,
-                              stdin_file_spec ?  stdin_file_spec.GetCString() : "<null>",
-                             stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
-                             stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
-
-            if (stdin_file_spec)
-                m_gdb_comm.SetSTDIN(stdin_file_spec);
-            if (stdout_file_spec)
-                m_gdb_comm.SetSTDOUT(stdout_file_spec);
-            if (stderr_file_spec)
-                m_gdb_comm.SetSTDERR(stderr_file_spec);
-
-            m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR);
-            m_gdb_comm.SetDetachOnError (launch_flags & eLaunchFlagDetachOnError);
-
-            m_gdb_comm.SendLaunchArchPacket (GetTarget().GetArchitecture().GetArchitectureName());
-
-            const char * launch_event_data = launch_info.GetLaunchEventData();
-            if (launch_event_data != NULL && *launch_event_data != '\0')
-                m_gdb_comm.SendLaunchEventDataPacket (launch_event_data);
-
-            if (working_dir)
-            {
-                m_gdb_comm.SetWorkingDir (working_dir);
-            }
-
-            // Send the environment and the program + arguments after we connect
-            const Args &environment = launch_info.GetEnvironmentEntries();
-            if (environment.GetArgumentCount())
-            {
-                size_t num_environment_entries = environment.GetArgumentCount();
-                for (size_t i=0; i<num_environment_entries; ++i)
-                {
-                    const char *env_entry = environment.GetArgumentAtIndex(i);
-                    if (env_entry == NULL || m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
-                        break;
-                }
-            }
-
-            {
-                // Scope for the scoped timeout object
-                GDBRemoteCommunication::ScopedTimeout timeout (m_gdb_comm, 10);
-
-                int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info);
-                if (arg_packet_err == 0)
-                {
-                    std::string error_str;
-                    if (m_gdb_comm.GetLaunchSuccess (error_str))
-                    {
-                        SetID (m_gdb_comm.GetCurrentProcessID ());
-                    }
-                    else
-                    {
-                        error.SetErrorString (error_str.c_str());
-                    }
-                }
-                else
-                {
-                    error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err);
-                }
-            }
-
-            if (GetID() == LLDB_INVALID_PROCESS_ID)
-            {
-                if (log)
-                    log->Printf("failed to connect to debugserver: %s", error.AsCString());
-                KillDebugserverProcess ();
-                return error;
-            }
-
-            StringExtractorGDBRemote response;
-            if (m_gdb_comm.GetStopReply(response))
-            {
-                SetLastStopPacket(response);
-                // '?' Packets must be handled differently in non-stop mode
-                if (GetTarget().GetNonStopModeEnabled())
-                    HandleStopReplySequence();
-
-                const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
-
-                if (process_arch.IsValid())
-                {
-                    GetTarget().MergeArchitecture(process_arch);
-                }
-                else
-                {
-                    const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();
-                    if (host_arch.IsValid())
-                        GetTarget().MergeArchitecture(host_arch);
-                }
-
-                SetPrivateState (SetThreadStopInfo (response));
-
-                if (!disable_stdio)
-                {
-                    if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd)
-                        SetSTDIOFileDescriptor (pty.ReleaseMasterFileDescriptor());
-                }
-            }
+          if (!stderr_file_spec)
+            stderr_file_spec = slave_name;
         }
-        else
-        {
-            if (log)
-                log->Printf("failed to connect to debugserver: %s", error.AsCString());
-        }
-    }
-    else
-    {
-        // Set our user ID to an invalid process ID.
-        SetID(LLDB_INVALID_PROCESS_ID);
-        error.SetErrorStringWithFormat ("failed to get object file from '%s' for arch %s",
-                                        exe_module->GetFileSpec().GetFilename().AsCString(),
-                                        exe_module->GetArchitecture().GetArchitectureName());
-    }
-    return error;
-
-}
-
-
-Error
-ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
-{
-    Error error;
-    // Only connect if we have a valid connect URL
-    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-
-    if (connect_url && connect_url[0])
-    {
         if (log)
-            log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__, connect_url);
-        std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
-        if (conn_ap.get())
-        {
-            const uint32_t max_retry_count = 50;
-            uint32_t retry_count = 0;
-            while (!m_gdb_comm.IsConnected())
-            {
-                if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
-                {
-                    m_gdb_comm.SetConnection (conn_ap.release());
-                    break;
-                }
-                else if (error.WasInterrupted())
-                {
-                    // If we were interrupted, don't keep retrying.
-                    break;
-                }
+          log->Printf(
+              "ProcessGDBRemote::%s adjusted STDIO paths for local platform "
+              "(IsHost() is true) using slave: stdin=%s, stdout=%s, stderr=%s",
+              __FUNCTION__,
+              stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+              stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+              stderr_file_spec ? stderr_file_spec.GetCString() : "<null>");
+      }
 
-                retry_count++;
+      if (log)
+        log->Printf("ProcessGDBRemote::%s final STDIO paths after all "
+                    "adjustments: stdin=%s, stdout=%s, stderr=%s",
+                    __FUNCTION__,
+                    stdin_file_spec ? stdin_file_spec.GetCString() : "<null>",
+                    stdout_file_spec ? stdout_file_spec.GetCString() : "<null>",
+                    stderr_file_spec ? stderr_file_spec.GetCString()
+                                     : "<null>");
 
-                if (retry_count >= max_retry_count)
-                    break;
+      if (stdin_file_spec)
+        m_gdb_comm.SetSTDIN(stdin_file_spec);
+      if (stdout_file_spec)
+        m_gdb_comm.SetSTDOUT(stdout_file_spec);
+      if (stderr_file_spec)
+        m_gdb_comm.SetSTDERR(stderr_file_spec);
 
-                usleep (100000);
-            }
-        }
-    }
+      m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR);
+      m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError);
 
-    if (!m_gdb_comm.IsConnected())
-    {
-        if (error.Success())
-            error.SetErrorString("not connected to remote gdb server");
-        return error;
-    }
+      m_gdb_comm.SendLaunchArchPacket(
+          GetTarget().GetArchitecture().GetArchitectureName());
 
+      const char *launch_event_data = launch_info.GetLaunchEventData();
+      if (launch_event_data != NULL && *launch_event_data != '\0')
+        m_gdb_comm.SendLaunchEventDataPacket(launch_event_data);
 
-    // Start the communications read thread so all incoming data can be
-    // parsed into packets and queued as they arrive.
-    if (GetTarget().GetNonStopModeEnabled())
-        m_gdb_comm.StartReadThread();
+      if (working_dir) {
+        m_gdb_comm.SetWorkingDir(working_dir);
+      }
 
-    // We always seem to be able to open a connection to a local port
-    // so we need to make sure we can then send data to it. If we can't
-    // then we aren't actually connected to anything, so try and do the
-    // handshake with the remote GDB server and make sure that goes
-    // alright.
-    if (!m_gdb_comm.HandshakeWithServer (&error))
-    {
-        m_gdb_comm.Disconnect();
-        if (error.Success())
-            error.SetErrorString("not connected to remote gdb server");
-        return error;
-    }
-
-    // Send $QNonStop:1 packet on startup if required
-    if (GetTarget().GetNonStopModeEnabled())
-        GetTarget().SetNonStopModeEnabled (m_gdb_comm.SetNonStopMode(true));
-
-    m_gdb_comm.GetEchoSupported ();
-    m_gdb_comm.GetThreadSuffixSupported ();
-    m_gdb_comm.GetListThreadsInStopReplySupported ();
-    m_gdb_comm.GetHostInfo ();
-    m_gdb_comm.GetVContSupported ('c');
-    m_gdb_comm.GetVAttachOrWaitSupported();
-
-    // Ask the remote server for the default thread id
-    if (GetTarget().GetNonStopModeEnabled())
-        m_gdb_comm.GetDefaultThreadId(m_initial_tid);
-
-
-    size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
-    for (size_t idx = 0; idx < num_cmds; idx++)
-    {
-        StringExtractorGDBRemote response;
-        m_gdb_comm.SendPacketAndWaitForResponse (GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
-    }
-    return error;
-}
-
-void
-ProcessGDBRemote::DidLaunchOrAttach (ArchSpec& process_arch)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__);
-    if (GetID() != LLDB_INVALID_PROCESS_ID)
-    {
-        BuildDynamicRegisterInfo (false);
-
-        // See if the GDB server supports the qHostInfo information
-
-
-        // See if the GDB server supports the qProcessInfo packet, if so
-        // prefer that over the Host information as it will be more specific
-        // to our process.
-
-        const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
-        if (remote_process_arch.IsValid())
-        {
-            process_arch = remote_process_arch;
-            if (log)
-                log->Printf ("ProcessGDBRemote::%s gdb-remote had process architecture, using %s %s",
-                             __FUNCTION__,
-                             process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
-                             process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
-        }
-        else
-        {
-            process_arch = m_gdb_comm.GetHostArchitecture();
-            if (log)
-                log->Printf ("ProcessGDBRemote::%s gdb-remote did not have process architecture, using gdb-remote host architecture %s %s",
-                             __FUNCTION__,
-                             process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
-                             process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
-        }
-
-        if (process_arch.IsValid())
-        {
-            const ArchSpec &target_arch = GetTarget().GetArchitecture();
-            if (target_arch.IsValid())
-            {
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s analyzing target arch, currently %s %s",
-                                 __FUNCTION__,
-                                 target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
-                                 target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
-
-                // If the remote host is ARM and we have apple as the vendor, then
-                // ARM executables and shared libraries can have mixed ARM architectures.
-                // You can have an armv6 executable, and if the host is armv7, then the
-                // system will load the best possible architecture for all shared libraries
-                // it has, so we really need to take the remote host architecture as our
-                // defacto architecture in this case.
-
-                if ((process_arch.GetMachine() == llvm::Triple::arm || process_arch.GetMachine() == llvm::Triple::thumb)
-                    && process_arch.GetTriple().getVendor() == llvm::Triple::Apple)
-                {
-                    GetTarget().SetArchitecture (process_arch);
-                    if (log)
-                        log->Printf ("ProcessGDBRemote::%s remote process is ARM/Apple, setting target arch to %s %s",
-                                     __FUNCTION__,
-                                     process_arch.GetArchitectureName () ? process_arch.GetArchitectureName () : "<null>",
-                                     process_arch.GetTriple().getTriple ().c_str() ? process_arch.GetTriple().getTriple ().c_str() : "<null>");
-                }
-                else
-                {
-                    // Fill in what is missing in the triple
-                    const llvm::Triple &remote_triple = process_arch.GetTriple();
-                    llvm::Triple new_target_triple = target_arch.GetTriple();
-                    if (new_target_triple.getVendorName().size() == 0)
-                    {
-                        new_target_triple.setVendor (remote_triple.getVendor());
-
-                        if (new_target_triple.getOSName().size() == 0)
-                        {
-                            new_target_triple.setOS (remote_triple.getOS());
-
-                            if (new_target_triple.getEnvironmentName().size() == 0)
-                                new_target_triple.setEnvironment (remote_triple.getEnvironment());
-                        }
-
-                        ArchSpec new_target_arch = target_arch;
-                        new_target_arch.SetTriple(new_target_triple);
-                        GetTarget().SetArchitecture(new_target_arch);
-                    }
-                }
-
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s final target arch after adjustments for remote architecture: %s %s",
-                                 __FUNCTION__,
-                                 target_arch.GetArchitectureName () ? target_arch.GetArchitectureName () : "<null>",
-                                 target_arch.GetTriple().getTriple ().c_str() ? target_arch.GetTriple().getTriple ().c_str() : "<null>");
-            }
-            else
-            {
-                // The target doesn't have a valid architecture yet, set it from
-                // the architecture we got from the remote GDB server
-                GetTarget().SetArchitecture (process_arch);
-            }
-        }
-
-        // Find out which StructuredDataPlugins are supported by the
-        // debug monitor.  These plugins transmit data over async $J packets.
-        auto supported_packets_array =
-            m_gdb_comm.GetSupportedStructuredDataPlugins();
-        if (supported_packets_array)
-            MapSupportedStructuredDataPlugins(*supported_packets_array);
-    }
-}
-
-void
-ProcessGDBRemote::DidLaunch ()
-{
-    ArchSpec process_arch;
-    DidLaunchOrAttach (process_arch);
-}
-
-Error
-ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    Error error;
-
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s()", __FUNCTION__);
-
-    // Clear out and clean up from any current state
-    Clear();
-    if (attach_pid != LLDB_INVALID_PROCESS_ID)
-    {
-        error = EstablishConnectionIfNeeded (attach_info);
-        if (error.Success())
-        {
-            m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
-            char packet[64];
-            const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
-            SetID (attach_pid);
-            m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
-        }
-        else
-            SetExitStatus (-1, error.AsCString());
-    }
-
-    return error;
-}
-
-Error
-ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
-{
-    Error error;
-    // Clear out and clean up from any current state
-    Clear();
-
-    if (process_name && process_name[0])
-    {
-        error = EstablishConnectionIfNeeded (attach_info);
-        if (error.Success())
-        {
-            StreamString packet;
-
-            m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
-
-            if (attach_info.GetWaitForLaunch())
-            {
-                if (!m_gdb_comm.GetVAttachOrWaitSupported())
-                {
-                    packet.PutCString ("vAttachWait");
-                }
-                else
-                {
-                    if (attach_info.GetIgnoreExisting())
-                        packet.PutCString("vAttachWait");
-                    else
-                        packet.PutCString ("vAttachOrWait");
-                }
-            }
-            else
-                packet.PutCString("vAttachName");
-            packet.PutChar(';');
-            packet.PutBytesAsRawHex8(process_name, strlen(process_name), endian::InlHostByteOrder(), endian::InlHostByteOrder());
-
-            m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize()));
-
-        }
-        else
-            SetExitStatus (-1, error.AsCString());
-    }
-    return error;
-}
-
-void
-ProcessGDBRemote::DidExit ()
-{
-    // When we exit, disconnect from the GDB server communications
-    m_gdb_comm.Disconnect();
-}
-
-void
-ProcessGDBRemote::DidAttach (ArchSpec &process_arch)
-{
-    // If you can figure out what the architecture is, fill it in here.
-    process_arch.Clear();
-    DidLaunchOrAttach (process_arch);
-}
-
-
-Error
-ProcessGDBRemote::WillResume ()
-{
-    m_continue_c_tids.clear();
-    m_continue_C_tids.clear();
-    m_continue_s_tids.clear();
-    m_continue_S_tids.clear();
-    m_jstopinfo_sp.reset();
-    m_jthreadsinfo_sp.reset();
-    return Error();
-}
-
-Error
-ProcessGDBRemote::DoResume ()
-{
-    Error error;
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("ProcessGDBRemote::Resume()");
-
-    ListenerSP listener_sp (Listener::MakeListener("gdb-remote.resume-packet-sent"));
-    if (listener_sp->StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
-    {
-        listener_sp->StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
-
-        const size_t num_threads = GetThreadList().GetSize();
-
-        StreamString continue_packet;
-        bool continue_packet_error = false;
-        if (m_gdb_comm.HasAnyVContSupport ())
-        {
-            if (!GetTarget().GetNonStopModeEnabled() &&
-                (m_continue_c_tids.size() == num_threads ||
-                (m_continue_c_tids.empty() &&
-                 m_continue_C_tids.empty() &&
-                 m_continue_s_tids.empty() &&
-                 m_continue_S_tids.empty())))
-            {
-                // All threads are continuing, just send a "c" packet
-                continue_packet.PutCString ("c");
-            }
-            else
-            {
-                continue_packet.PutCString ("vCont");
-
-                if (!m_continue_c_tids.empty())
-                {
-                    if (m_gdb_comm.GetVContSupported ('c'))
-                    {
-                        for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
-                            continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
-                    }
-                    else
-                        continue_packet_error = true;
-                }
-
-                if (!continue_packet_error && !m_continue_C_tids.empty())
-                {
-                    if (m_gdb_comm.GetVContSupported ('C'))
-                    {
-                        for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
-                            continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
-                    }
-                    else
-                        continue_packet_error = true;
-                }
-
-                if (!continue_packet_error && !m_continue_s_tids.empty())
-                {
-                    if (m_gdb_comm.GetVContSupported ('s'))
-                    {
-                        for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
-                            continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
-                    }
-                    else
-                        continue_packet_error = true;
-                }
-
-                if (!continue_packet_error && !m_continue_S_tids.empty())
-                {
-                    if (m_gdb_comm.GetVContSupported ('S'))
-                    {
-                        for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
-                            continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
-                    }
-                    else
-                        continue_packet_error = true;
-                }
-
-                if (continue_packet_error)
-                    continue_packet.GetString().clear();
-            }
-        }
-        else
-            continue_packet_error = true;
-
-        if (continue_packet_error)
-        {
-            // Either no vCont support, or we tried to use part of the vCont
-            // packet that wasn't supported by the remote GDB server.
-            // We need to try and make a simple packet that can do our continue
-            const size_t num_continue_c_tids = m_continue_c_tids.size();
-            const size_t num_continue_C_tids = m_continue_C_tids.size();
-            const size_t num_continue_s_tids = m_continue_s_tids.size();
-            const size_t num_continue_S_tids = m_continue_S_tids.size();
-            if (num_continue_c_tids > 0)
-            {
-                if (num_continue_c_tids == num_threads)
-                {
-                    // All threads are resuming...
-                    m_gdb_comm.SetCurrentThreadForRun (-1);
-                    continue_packet.PutChar ('c');
-                    continue_packet_error = false;
-                }
-                else if (num_continue_c_tids == 1 &&
-                         num_continue_C_tids == 0 &&
-                         num_continue_s_tids == 0 &&
-                         num_continue_S_tids == 0 )
-                {
-                    // Only one thread is continuing
-                    m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front());
-                    continue_packet.PutChar ('c');
-                    continue_packet_error = false;
-                }
-            }
-
-            if (continue_packet_error && num_continue_C_tids > 0)
-            {
-                if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
-                    num_continue_C_tids > 0 &&
-                    num_continue_s_tids == 0 &&
-                    num_continue_S_tids == 0 )
-                {
-                    const int continue_signo = m_continue_C_tids.front().second;
-                    // Only one thread is continuing
-                    if (num_continue_C_tids > 1)
-                    {
-                        // More that one thread with a signal, yet we don't have
-                        // vCont support and we are being asked to resume each
-                        // thread with a signal, we need to make sure they are
-                        // all the same signal, or we can't issue the continue
-                        // accurately with the current support...
-                        if (num_continue_C_tids > 1)
-                        {
-                            continue_packet_error = false;
-                            for (size_t i=1; i<m_continue_C_tids.size(); ++i)
-                            {
-                                if (m_continue_C_tids[i].second != continue_signo)
-                                    continue_packet_error = true;
-                            }
-                        }
-                        if (!continue_packet_error)
-                            m_gdb_comm.SetCurrentThreadForRun (-1);
-                    }
-                    else
-                    {
-                        // Set the continue thread ID
-                        continue_packet_error = false;
-                        m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first);
-                    }
-                    if (!continue_packet_error)
-                    {
-                        // Add threads continuing with the same signo...
-                        continue_packet.Printf("C%2.2x", continue_signo);
-                    }
-                }
-            }
-
-            if (continue_packet_error && num_continue_s_tids > 0)
-            {
-                if (num_continue_s_tids == num_threads)
-                {
-                    // All threads are resuming...
-                    m_gdb_comm.SetCurrentThreadForRun (-1);
-
-                    // If in Non-Stop-Mode use vCont when stepping
-                    if (GetTarget().GetNonStopModeEnabled())
-                    {
-                        if (m_gdb_comm.GetVContSupported('s'))
-                            continue_packet.PutCString("vCont;s");
-                        else
-                            continue_packet.PutChar('s');
-                    }
-                    else
-                        continue_packet.PutChar('s');
-
-                    continue_packet_error = false;
-                }
-                else if (num_continue_c_tids == 0 &&
-                         num_continue_C_tids == 0 &&
-                         num_continue_s_tids == 1 &&
-                         num_continue_S_tids == 0 )
-                {
-                    // Only one thread is stepping
-                    m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front());
-                    continue_packet.PutChar ('s');
-                    continue_packet_error = false;
-                }
-            }
-
-            if (!continue_packet_error && num_continue_S_tids > 0)
-            {
-                if (num_continue_S_tids == num_threads)
-                {
-                    const int step_signo = m_continue_S_tids.front().second;
-                    // Are all threads trying to step with the same signal?
-                    continue_packet_error = false;
-                    if (num_continue_S_tids > 1)
-                    {
-                        for (size_t i=1; i<num_threads; ++i)
-                        {
-                            if (m_continue_S_tids[i].second != step_signo)
-                                continue_packet_error = true;
-                        }
-                    }
-                    if (!continue_packet_error)
-                    {
-                        // Add threads stepping with the same signo...
-                        m_gdb_comm.SetCurrentThreadForRun (-1);
-                        continue_packet.Printf("S%2.2x", step_signo);
-                    }
-                }
-                else if (num_continue_c_tids == 0 &&
-                         num_continue_C_tids == 0 &&
-                         num_continue_s_tids == 0 &&
-                         num_continue_S_tids == 1 )
-                {
-                    // Only one thread is stepping with signal
-                    m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first);
-                    continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
-                    continue_packet_error = false;
-                }
-            }
-        }
-
-        if (continue_packet_error)
-        {
-            error.SetErrorString ("can't make continue packet for this resume");
-        }
-        else
-        {
-            EventSP event_sp;
-            if (!m_async_thread.IsJoinable())
-            {
-                error.SetErrorString ("Trying to resume but the async thread is dead.");
-                if (log)
-                    log->Printf ("ProcessGDBRemote::DoResume: Trying to resume but the async thread is dead.");
-                return error;
-            }
-
-            m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
-
-            if (listener_sp->WaitForEvent(std::chrono::seconds(5), event_sp) == false)
-            {
-                error.SetErrorString("Resume timed out.");
-                if (log)
-                    log->Printf ("ProcessGDBRemote::DoResume: Resume timed out.");
-            }
-            else if (event_sp->BroadcasterIs (&m_async_broadcaster))
-            {
-                error.SetErrorString ("Broadcast continue, but the async thread was killed before we got an ack back.");
-                if (log)
-                    log->Printf ("ProcessGDBRemote::DoResume: Broadcast continue, but the async thread was killed before we got an ack back.");
-                return error;
-            }
-        }
-    }
-
-    return error;
-}
-
-void
-ProcessGDBRemote::HandleStopReplySequence ()
-{
-    while(true)
-    {
-        // Send vStopped
-        StringExtractorGDBRemote response;
-        m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
-
-        // OK represents end of signal list
-        if (response.IsOKResponse())
+      // Send the environment and the program + arguments after we connect
+      const Args &environment = launch_info.GetEnvironmentEntries();
+      if (environment.GetArgumentCount()) {
+        size_t num_environment_entries = environment.GetArgumentCount();
+        for (size_t i = 0; i < num_environment_entries; ++i) {
+          const char *env_entry = environment.GetArgumentAtIndex(i);
+          if (env_entry == NULL ||
+              m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
             break;
+        }
+      }
 
-        // If not OK or a normal packet we have a problem
-        if (!response.IsNormalResponse())
-            break;
+      {
+        // Scope for the scoped timeout object
+        GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm, 10);
 
+        int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info);
+        if (arg_packet_err == 0) {
+          std::string error_str;
+          if (m_gdb_comm.GetLaunchSuccess(error_str)) {
+            SetID(m_gdb_comm.GetCurrentProcessID());
+          } else {
+            error.SetErrorString(error_str.c_str());
+          }
+        } else {
+          error.SetErrorStringWithFormat("'A' packet returned an error: %i",
+                                         arg_packet_err);
+        }
+      }
+
+      if (GetID() == LLDB_INVALID_PROCESS_ID) {
+        if (log)
+          log->Printf("failed to connect to debugserver: %s",
+                      error.AsCString());
+        KillDebugserverProcess();
+        return error;
+      }
+
+      StringExtractorGDBRemote response;
+      if (m_gdb_comm.GetStopReply(response)) {
         SetLastStopPacket(response);
+        // '?' Packets must be handled differently in non-stop mode
+        if (GetTarget().GetNonStopModeEnabled())
+          HandleStopReplySequence();
+
+        const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
+
+        if (process_arch.IsValid()) {
+          GetTarget().MergeArchitecture(process_arch);
+        } else {
+          const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture();
+          if (host_arch.IsValid())
+            GetTarget().MergeArchitecture(host_arch);
+        }
+
+        SetPrivateState(SetThreadStopInfo(response));
+
+        if (!disable_stdio) {
+          if (pty.GetMasterFileDescriptor() !=
+              lldb_utility::PseudoTerminal::invalid_fd)
+            SetSTDIOFileDescriptor(pty.ReleaseMasterFileDescriptor());
+        }
+      }
+    } else {
+      if (log)
+        log->Printf("failed to connect to debugserver: %s", error.AsCString());
     }
+  } else {
+    // Set our user ID to an invalid process ID.
+    SetID(LLDB_INVALID_PROCESS_ID);
+    error.SetErrorStringWithFormat(
+        "failed to get object file from '%s' for arch %s",
+        exe_module->GetFileSpec().GetFilename().AsCString(),
+        exe_module->GetArchitecture().GetArchitectureName());
+  }
+  return error;
 }
 
-void
-ProcessGDBRemote::ClearThreadIDList ()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-    m_thread_ids.clear();
-    m_thread_pcs.clear();
+Error ProcessGDBRemote::ConnectToDebugserver(const char *connect_url) {
+  Error error;
+  // Only connect if we have a valid connect URL
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+  if (connect_url && connect_url[0]) {
+    if (log)
+      log->Printf("ProcessGDBRemote::%s Connecting to %s", __FUNCTION__,
+                  connect_url);
+    std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+        new ConnectionFileDescriptor());
+    if (conn_ap.get()) {
+      const uint32_t max_retry_count = 50;
+      uint32_t retry_count = 0;
+      while (!m_gdb_comm.IsConnected()) {
+        if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess) {
+          m_gdb_comm.SetConnection(conn_ap.release());
+          break;
+        } else if (error.WasInterrupted()) {
+          // If we were interrupted, don't keep retrying.
+          break;
+        }
+
+        retry_count++;
+
+        if (retry_count >= max_retry_count)
+          break;
+
+        usleep(100000);
+      }
+    }
+  }
+
+  if (!m_gdb_comm.IsConnected()) {
+    if (error.Success())
+      error.SetErrorString("not connected to remote gdb server");
+    return error;
+  }
+
+  // Start the communications read thread so all incoming data can be
+  // parsed into packets and queued as they arrive.
+  if (GetTarget().GetNonStopModeEnabled())
+    m_gdb_comm.StartReadThread();
+
+  // We always seem to be able to open a connection to a local port
+  // so we need to make sure we can then send data to it. If we can't
+  // then we aren't actually connected to anything, so try and do the
+  // handshake with the remote GDB server and make sure that goes
+  // alright.
+  if (!m_gdb_comm.HandshakeWithServer(&error)) {
+    m_gdb_comm.Disconnect();
+    if (error.Success())
+      error.SetErrorString("not connected to remote gdb server");
+    return error;
+  }
+
+  // Send $QNonStop:1 packet on startup if required
+  if (GetTarget().GetNonStopModeEnabled())
+    GetTarget().SetNonStopModeEnabled(m_gdb_comm.SetNonStopMode(true));
+
+  m_gdb_comm.GetEchoSupported();
+  m_gdb_comm.GetThreadSuffixSupported();
+  m_gdb_comm.GetListThreadsInStopReplySupported();
+  m_gdb_comm.GetHostInfo();
+  m_gdb_comm.GetVContSupported('c');
+  m_gdb_comm.GetVAttachOrWaitSupported();
+
+  // Ask the remote server for the default thread id
+  if (GetTarget().GetNonStopModeEnabled())
+    m_gdb_comm.GetDefaultThreadId(m_initial_tid);
+
+  size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
+  for (size_t idx = 0; idx < num_cmds; idx++) {
+    StringExtractorGDBRemote response;
+    m_gdb_comm.SendPacketAndWaitForResponse(
+        GetExtraStartupCommands().GetArgumentAtIndex(idx), response, false);
+  }
+  return error;
+}
+
+void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+  if (GetID() != LLDB_INVALID_PROCESS_ID) {
+    BuildDynamicRegisterInfo(false);
+
+    // See if the GDB server supports the qHostInfo information
+
+    // See if the GDB server supports the qProcessInfo packet, if so
+    // prefer that over the Host information as it will be more specific
+    // to our process.
+
+    const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+    if (remote_process_arch.IsValid()) {
+      process_arch = remote_process_arch;
+      if (log)
+        log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, "
+                    "using %s %s",
+                    __FUNCTION__, process_arch.GetArchitectureName()
+                                      ? process_arch.GetArchitectureName()
+                                      : "<null>",
+                    process_arch.GetTriple().getTriple().c_str()
+                        ? process_arch.GetTriple().getTriple().c_str()
+                        : "<null>");
+    } else {
+      process_arch = m_gdb_comm.GetHostArchitecture();
+      if (log)
+        log->Printf("ProcessGDBRemote::%s gdb-remote did not have process "
+                    "architecture, using gdb-remote host architecture %s %s",
+                    __FUNCTION__, process_arch.GetArchitectureName()
+                                      ? process_arch.GetArchitectureName()
+                                      : "<null>",
+                    process_arch.GetTriple().getTriple().c_str()
+                        ? process_arch.GetTriple().getTriple().c_str()
+                        : "<null>");
+    }
+
+    if (process_arch.IsValid()) {
+      const ArchSpec &target_arch = GetTarget().GetArchitecture();
+      if (target_arch.IsValid()) {
+        if (log)
+          log->Printf(
+              "ProcessGDBRemote::%s analyzing target arch, currently %s %s",
+              __FUNCTION__, target_arch.GetArchitectureName()
+                                ? target_arch.GetArchitectureName()
+                                : "<null>",
+              target_arch.GetTriple().getTriple().c_str()
+                  ? target_arch.GetTriple().getTriple().c_str()
+                  : "<null>");
+
+        // If the remote host is ARM and we have apple as the vendor, then
+        // ARM executables and shared libraries can have mixed ARM
+        // architectures.
+        // You can have an armv6 executable, and if the host is armv7, then the
+        // system will load the best possible architecture for all shared
+        // libraries
+        // it has, so we really need to take the remote host architecture as our
+        // defacto architecture in this case.
+
+        if ((process_arch.GetMachine() == llvm::Triple::arm ||
+             process_arch.GetMachine() == llvm::Triple::thumb) &&
+            process_arch.GetTriple().getVendor() == llvm::Triple::Apple) {
+          GetTarget().SetArchitecture(process_arch);
+          if (log)
+            log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, "
+                        "setting target arch to %s %s",
+                        __FUNCTION__, process_arch.GetArchitectureName()
+                                          ? process_arch.GetArchitectureName()
+                                          : "<null>",
+                        process_arch.GetTriple().getTriple().c_str()
+                            ? process_arch.GetTriple().getTriple().c_str()
+                            : "<null>");
+        } else {
+          // Fill in what is missing in the triple
+          const llvm::Triple &remote_triple = process_arch.GetTriple();
+          llvm::Triple new_target_triple = target_arch.GetTriple();
+          if (new_target_triple.getVendorName().size() == 0) {
+            new_target_triple.setVendor(remote_triple.getVendor());
+
+            if (new_target_triple.getOSName().size() == 0) {
+              new_target_triple.setOS(remote_triple.getOS());
+
+              if (new_target_triple.getEnvironmentName().size() == 0)
+                new_target_triple.setEnvironment(
+                    remote_triple.getEnvironment());
+            }
+
+            ArchSpec new_target_arch = target_arch;
+            new_target_arch.SetTriple(new_target_triple);
+            GetTarget().SetArchitecture(new_target_arch);
+          }
+        }
+
+        if (log)
+          log->Printf("ProcessGDBRemote::%s final target arch after "
+                      "adjustments for remote architecture: %s %s",
+                      __FUNCTION__, target_arch.GetArchitectureName()
+                                        ? target_arch.GetArchitectureName()
+                                        : "<null>",
+                      target_arch.GetTriple().getTriple().c_str()
+                          ? target_arch.GetTriple().getTriple().c_str()
+                          : "<null>");
+      } else {
+        // The target doesn't have a valid architecture yet, set it from
+        // the architecture we got from the remote GDB server
+        GetTarget().SetArchitecture(process_arch);
+      }
+    }
+
+    // Find out which StructuredDataPlugins are supported by the
+    // debug monitor.  These plugins transmit data over async $J packets.
+    auto supported_packets_array =
+        m_gdb_comm.GetSupportedStructuredDataPlugins();
+    if (supported_packets_array)
+      MapSupportedStructuredDataPlugins(*supported_packets_array);
+  }
+}
+
+void ProcessGDBRemote::DidLaunch() {
+  ArchSpec process_arch;
+  DidLaunchOrAttach(process_arch);
+}
+
+Error ProcessGDBRemote::DoAttachToProcessWithID(
+    lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  Error error;
+
+  if (log)
+    log->Printf("ProcessGDBRemote::%s()", __FUNCTION__);
+
+  // Clear out and clean up from any current state
+  Clear();
+  if (attach_pid != LLDB_INVALID_PROCESS_ID) {
+    error = EstablishConnectionIfNeeded(attach_info);
+    if (error.Success()) {
+      m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
+
+      char packet[64];
+      const int packet_len =
+          ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
+      SetID(attach_pid);
+      m_async_broadcaster.BroadcastEvent(
+          eBroadcastBitAsyncContinue, new EventDataBytes(packet, packet_len));
+    } else
+      SetExitStatus(-1, error.AsCString());
+  }
+
+  return error;
+}
+
+Error ProcessGDBRemote::DoAttachToProcessWithName(
+    const char *process_name, const ProcessAttachInfo &attach_info) {
+  Error error;
+  // Clear out and clean up from any current state
+  Clear();
+
+  if (process_name && process_name[0]) {
+    error = EstablishConnectionIfNeeded(attach_info);
+    if (error.Success()) {
+      StreamString packet;
+
+      m_gdb_comm.SetDetachOnError(attach_info.GetDetachOnError());
+
+      if (attach_info.GetWaitForLaunch()) {
+        if (!m_gdb_comm.GetVAttachOrWaitSupported()) {
+          packet.PutCString("vAttachWait");
+        } else {
+          if (attach_info.GetIgnoreExisting())
+            packet.PutCString("vAttachWait");
+          else
+            packet.PutCString("vAttachOrWait");
+        }
+      } else
+        packet.PutCString("vAttachName");
+      packet.PutChar(';');
+      packet.PutBytesAsRawHex8(process_name, strlen(process_name),
+                               endian::InlHostByteOrder(),
+                               endian::InlHostByteOrder());
+
+      m_async_broadcaster.BroadcastEvent(
+          eBroadcastBitAsyncContinue,
+          new EventDataBytes(packet.GetData(), packet.GetSize()));
+
+    } else
+      SetExitStatus(-1, error.AsCString());
+  }
+  return error;
+}
+
+void ProcessGDBRemote::DidExit() {
+  // When we exit, disconnect from the GDB server communications
+  m_gdb_comm.Disconnect();
+}
+
+void ProcessGDBRemote::DidAttach(ArchSpec &process_arch) {
+  // If you can figure out what the architecture is, fill it in here.
+  process_arch.Clear();
+  DidLaunchOrAttach(process_arch);
+}
+
+Error ProcessGDBRemote::WillResume() {
+  m_continue_c_tids.clear();
+  m_continue_C_tids.clear();
+  m_continue_s_tids.clear();
+  m_continue_S_tids.clear();
+  m_jstopinfo_sp.reset();
+  m_jthreadsinfo_sp.reset();
+  return Error();
+}
+
+Error ProcessGDBRemote::DoResume() {
+  Error error;
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("ProcessGDBRemote::Resume()");
+
+  ListenerSP listener_sp(
+      Listener::MakeListener("gdb-remote.resume-packet-sent"));
+  if (listener_sp->StartListeningForEvents(
+          &m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent)) {
+    listener_sp->StartListeningForEvents(
+        &m_async_broadcaster,
+        ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit);
+
+    const size_t num_threads = GetThreadList().GetSize();
+
+    StreamString continue_packet;
+    bool continue_packet_error = false;
+    if (m_gdb_comm.HasAnyVContSupport()) {
+      if (!GetTarget().GetNonStopModeEnabled() &&
+          (m_continue_c_tids.size() == num_threads ||
+           (m_continue_c_tids.empty() && m_continue_C_tids.empty() &&
+            m_continue_s_tids.empty() && m_continue_S_tids.empty()))) {
+        // All threads are continuing, just send a "c" packet
+        continue_packet.PutCString("c");
+      } else {
+        continue_packet.PutCString("vCont");
+
+        if (!m_continue_c_tids.empty()) {
+          if (m_gdb_comm.GetVContSupported('c')) {
+            for (tid_collection::const_iterator
+                     t_pos = m_continue_c_tids.begin(),
+                     t_end = m_continue_c_tids.end();
+                 t_pos != t_end; ++t_pos)
+              continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
+          } else
+            continue_packet_error = true;
+        }
+
+        if (!continue_packet_error && !m_continue_C_tids.empty()) {
+          if (m_gdb_comm.GetVContSupported('C')) {
+            for (tid_sig_collection::const_iterator
+                     s_pos = m_continue_C_tids.begin(),
+                     s_end = m_continue_C_tids.end();
+                 s_pos != s_end; ++s_pos)
+              continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second,
+                                     s_pos->first);
+          } else
+            continue_packet_error = true;
+        }
+
+        if (!continue_packet_error && !m_continue_s_tids.empty()) {
+          if (m_gdb_comm.GetVContSupported('s')) {
+            for (tid_collection::const_iterator
+                     t_pos = m_continue_s_tids.begin(),
+                     t_end = m_continue_s_tids.end();
+                 t_pos != t_end; ++t_pos)
+              continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
+          } else
+            continue_packet_error = true;
+        }
+
+        if (!continue_packet_error && !m_continue_S_tids.empty()) {
+          if (m_gdb_comm.GetVContSupported('S')) {
+            for (tid_sig_collection::const_iterator
+                     s_pos = m_continue_S_tids.begin(),
+                     s_end = m_continue_S_tids.end();
+                 s_pos != s_end; ++s_pos)
+              continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second,
+                                     s_pos->first);
+          } else
+            continue_packet_error = true;
+        }
+
+        if (continue_packet_error)
+          continue_packet.GetString().clear();
+      }
+    } else
+      continue_packet_error = true;
+
+    if (continue_packet_error) {
+      // Either no vCont support, or we tried to use part of the vCont
+      // packet that wasn't supported by the remote GDB server.
+      // We need to try and make a simple packet that can do our continue
+      const size_t num_continue_c_tids = m_continue_c_tids.size();
+      const size_t num_continue_C_tids = m_continue_C_tids.size();
+      const size_t num_continue_s_tids = m_continue_s_tids.size();
+      const size_t num_continue_S_tids = m_continue_S_tids.size();
+      if (num_continue_c_tids > 0) {
+        if (num_continue_c_tids == num_threads) {
+          // All threads are resuming...
+          m_gdb_comm.SetCurrentThreadForRun(-1);
+          continue_packet.PutChar('c');
+          continue_packet_error = false;
+        } else if (num_continue_c_tids == 1 && num_continue_C_tids == 0 &&
+                   num_continue_s_tids == 0 && num_continue_S_tids == 0) {
+          // Only one thread is continuing
+          m_gdb_comm.SetCurrentThreadForRun(m_continue_c_tids.front());
+          continue_packet.PutChar('c');
+          continue_packet_error = false;
+        }
+      }
+
+      if (continue_packet_error && num_continue_C_tids > 0) {
+        if ((num_continue_C_tids + num_continue_c_tids) == num_threads &&
+            num_continue_C_tids > 0 && num_continue_s_tids == 0 &&
+            num_continue_S_tids == 0) {
+          const int continue_signo = m_continue_C_tids.front().second;
+          // Only one thread is continuing
+          if (num_continue_C_tids > 1) {
+            // More that one thread with a signal, yet we don't have
+            // vCont support and we are being asked to resume each
+            // thread with a signal, we need to make sure they are
+            // all the same signal, or we can't issue the continue
+            // accurately with the current support...
+            if (num_continue_C_tids > 1) {
+              continue_packet_error = false;
+              for (size_t i = 1; i < m_continue_C_tids.size(); ++i) {
+                if (m_continue_C_tids[i].second != continue_signo)
+                  continue_packet_error = true;
+              }
+            }
+            if (!continue_packet_error)
+              m_gdb_comm.SetCurrentThreadForRun(-1);
+          } else {
+            // Set the continue thread ID
+            continue_packet_error = false;
+            m_gdb_comm.SetCurrentThreadForRun(m_continue_C_tids.front().first);
+          }
+          if (!continue_packet_error) {
+            // Add threads continuing with the same signo...
+            continue_packet.Printf("C%2.2x", continue_signo);
+          }
+        }
+      }
+
+      if (continue_packet_error && num_continue_s_tids > 0) {
+        if (num_continue_s_tids == num_threads) {
+          // All threads are resuming...
+          m_gdb_comm.SetCurrentThreadForRun(-1);
+
+          // If in Non-Stop-Mode use vCont when stepping
+          if (GetTarget().GetNonStopModeEnabled()) {
+            if (m_gdb_comm.GetVContSupported('s'))
+              continue_packet.PutCString("vCont;s");
+            else
+              continue_packet.PutChar('s');
+          } else
+            continue_packet.PutChar('s');
+
+          continue_packet_error = false;
+        } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
+                   num_continue_s_tids == 1 && num_continue_S_tids == 0) {
+          // Only one thread is stepping
+          m_gdb_comm.SetCurrentThreadForRun(m_continue_s_tids.front());
+          continue_packet.PutChar('s');
+          continue_packet_error = false;
+        }
+      }
+
+      if (!continue_packet_error && num_continue_S_tids > 0) {
+        if (num_continue_S_tids == num_threads) {
+          const int step_signo = m_continue_S_tids.front().second;
+          // Are all threads trying to step with the same signal?
+          continue_packet_error = false;
+          if (num_continue_S_tids > 1) {
+            for (size_t i = 1; i < num_threads; ++i) {
+              if (m_continue_S_tids[i].second != step_signo)
+                continue_packet_error = true;
+            }
+          }
+          if (!continue_packet_error) {
+            // Add threads stepping with the same signo...
+            m_gdb_comm.SetCurrentThreadForRun(-1);
+            continue_packet.Printf("S%2.2x", step_signo);
+          }
+        } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 &&
+                   num_continue_s_tids == 0 && num_continue_S_tids == 1) {
+          // Only one thread is stepping with signal
+          m_gdb_comm.SetCurrentThreadForRun(m_continue_S_tids.front().first);
+          continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
+          continue_packet_error = false;
+        }
+      }
+    }
+
+    if (continue_packet_error) {
+      error.SetErrorString("can't make continue packet for this resume");
+    } else {
+      EventSP event_sp;
+      if (!m_async_thread.IsJoinable()) {
+        error.SetErrorString("Trying to resume but the async thread is dead.");
+        if (log)
+          log->Printf("ProcessGDBRemote::DoResume: Trying to resume but the "
+                      "async thread is dead.");
+        return error;
+      }
+
+      m_async_broadcaster.BroadcastEvent(
+          eBroadcastBitAsyncContinue,
+          new EventDataBytes(continue_packet.GetData(),
+                             continue_packet.GetSize()));
+
+      if (listener_sp->WaitForEvent(std::chrono::seconds(5), event_sp) ==
+          false) {
+        error.SetErrorString("Resume timed out.");
+        if (log)
+          log->Printf("ProcessGDBRemote::DoResume: Resume timed out.");
+      } else if (event_sp->BroadcasterIs(&m_async_broadcaster)) {
+        error.SetErrorString("Broadcast continue, but the async thread was "
+                             "killed before we got an ack back.");
+        if (log)
+          log->Printf("ProcessGDBRemote::DoResume: Broadcast continue, but the "
+                      "async thread was killed before we got an ack back.");
+        return error;
+      }
+    }
+  }
+
+  return error;
+}
+
+void ProcessGDBRemote::HandleStopReplySequence() {
+  while (true) {
+    // Send vStopped
+    StringExtractorGDBRemote response;
+    m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+
+    // OK represents end of signal list
+    if (response.IsOKResponse())
+      break;
+
+    // If not OK or a normal packet we have a problem
+    if (!response.IsNormalResponse())
+      break;
+
+    SetLastStopPacket(response);
+  }
+}
+
+void ProcessGDBRemote::ClearThreadIDList() {
+  std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+  m_thread_ids.clear();
+  m_thread_pcs.clear();
 }
 
 size_t
-ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue (std::string &value)
-{
-    m_thread_ids.clear();
-    m_thread_pcs.clear();
-    size_t comma_pos;
-    lldb::tid_t tid;
-    while ((comma_pos = value.find(',')) != std::string::npos)
-    {
-        value[comma_pos] = '\0';
-        // thread in big endian hex
-        tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
-        if (tid != LLDB_INVALID_THREAD_ID)
-            m_thread_ids.push_back (tid);
-        value.erase(0, comma_pos + 1);
-    }
-    tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue(std::string &value) {
+  m_thread_ids.clear();
+  m_thread_pcs.clear();
+  size_t comma_pos;
+  lldb::tid_t tid;
+  while ((comma_pos = value.find(',')) != std::string::npos) {
+    value[comma_pos] = '\0';
+    // thread in big endian hex
+    tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
     if (tid != LLDB_INVALID_THREAD_ID)
-        m_thread_ids.push_back (tid);
-    return m_thread_ids.size();
+      m_thread_ids.push_back(tid);
+    value.erase(0, comma_pos + 1);
+  }
+  tid = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_THREAD_ID, 16);
+  if (tid != LLDB_INVALID_THREAD_ID)
+    m_thread_ids.push_back(tid);
+  return m_thread_ids.size();
 }
 
 size_t
-ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue (std::string &value)
-{
-    m_thread_pcs.clear();
-    size_t comma_pos;
-    lldb::addr_t pc;
-    while ((comma_pos = value.find(',')) != std::string::npos)
-    {
-        value[comma_pos] = '\0';
-        pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
-        if (pc != LLDB_INVALID_ADDRESS)
-            m_thread_pcs.push_back (pc);
-        value.erase(0, comma_pos + 1);
-    }
-    pc = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_ADDRESS, 16);
-    if (pc != LLDB_INVALID_THREAD_ID)
-        m_thread_pcs.push_back (pc);
-    return m_thread_pcs.size();
+ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) {
+  m_thread_pcs.clear();
+  size_t comma_pos;
+  lldb::addr_t pc;
+  while ((comma_pos = value.find(',')) != std::string::npos) {
+    value[comma_pos] = '\0';
+    pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
+    if (pc != LLDB_INVALID_ADDRESS)
+      m_thread_pcs.push_back(pc);
+    value.erase(0, comma_pos + 1);
+  }
+  pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16);
+  if (pc != LLDB_INVALID_THREAD_ID)
+    m_thread_pcs.push_back(pc);
+  return m_thread_pcs.size();
 }
 
-bool
-ProcessGDBRemote::UpdateThreadIDList ()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+bool ProcessGDBRemote::UpdateThreadIDList() {
+  std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
 
-    if (m_jthreadsinfo_sp)
-    {
-        // If we have the JSON threads info, we can get the thread list from that
-        StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
-        if (thread_infos && thread_infos->GetSize() > 0)
-        {
-            m_thread_ids.clear();
-            m_thread_pcs.clear();
-            thread_infos->ForEach([this](StructuredData::Object* object) -> bool {
-                StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
-                if (thread_dict)
-                {
-                    // Set the thread stop info from the JSON dictionary
-                    SetThreadStopInfo (thread_dict);
-                    lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-                    if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
-                        m_thread_ids.push_back(tid);
-                }
-                return true; // Keep iterating through all thread_info objects
-            });
+  if (m_jthreadsinfo_sp) {
+    // If we have the JSON threads info, we can get the thread list from that
+    StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
+    if (thread_infos && thread_infos->GetSize() > 0) {
+      m_thread_ids.clear();
+      m_thread_pcs.clear();
+      thread_infos->ForEach([this](StructuredData::Object *object) -> bool {
+        StructuredData::Dictionary *thread_dict = object->GetAsDictionary();
+        if (thread_dict) {
+          // Set the thread stop info from the JSON dictionary
+          SetThreadStopInfo(thread_dict);
+          lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+          if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid))
+            m_thread_ids.push_back(tid);
         }
-        if (!m_thread_ids.empty())
-            return true;
+        return true; // Keep iterating through all thread_info objects
+      });
     }
-    else
-    {
-        // See if we can get the thread IDs from the current stop reply packets
-        // that might contain a "threads" key/value pair
+    if (!m_thread_ids.empty())
+      return true;
+  } else {
+    // See if we can get the thread IDs from the current stop reply packets
+    // that might contain a "threads" key/value pair
 
-        // Lock the thread stack while we access it
-        //Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
-        std::unique_lock<std::recursive_mutex> stop_stack_lock(m_last_stop_packet_mutex, std::defer_lock);
-        if (stop_stack_lock.try_lock())
-        {
-            // Get the number of stop packets on the stack
-            int nItems = m_stop_packet_stack.size();
-            // Iterate over them
-            for (int i = 0; i < nItems; i++)
-            {
-                // Get the thread stop info
-                StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
-                const std::string &stop_info_str = stop_info.GetStringRef();
+    // Lock the thread stack while we access it
+    // Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex);
+    std::unique_lock<std::recursive_mutex> stop_stack_lock(
+        m_last_stop_packet_mutex, std::defer_lock);
+    if (stop_stack_lock.try_lock()) {
+      // Get the number of stop packets on the stack
+      int nItems = m_stop_packet_stack.size();
+      // Iterate over them
+      for (int i = 0; i < nItems; i++) {
+        // Get the thread stop info
+        StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i];
+        const std::string &stop_info_str = stop_info.GetStringRef();
 
-                m_thread_pcs.clear();
-                const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
-                if (thread_pcs_pos != std::string::npos)
-                {
-                    const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
-                    const size_t end = stop_info_str.find(';', start);
-                    if (end != std::string::npos)
-                    {
-                        std::string value = stop_info_str.substr(start, end - start);
-                        UpdateThreadPCsFromStopReplyThreadsValue(value);
-                    }
-                }
-
-                const size_t threads_pos = stop_info_str.find(";threads:");
-                if (threads_pos != std::string::npos)
-                {
-                    const size_t start = threads_pos + strlen(";threads:");
-                    const size_t end = stop_info_str.find(';', start);
-                    if (end != std::string::npos)
-                    {
-                        std::string value = stop_info_str.substr(start, end - start);
-                        if (UpdateThreadIDsFromStopReplyThreadsValue(value))
-                            return true;
-                    }
-                }
-            }
+        m_thread_pcs.clear();
+        const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:");
+        if (thread_pcs_pos != std::string::npos) {
+          const size_t start = thread_pcs_pos + strlen(";thread-pcs:");
+          const size_t end = stop_info_str.find(';', start);
+          if (end != std::string::npos) {
+            std::string value = stop_info_str.substr(start, end - start);
+            UpdateThreadPCsFromStopReplyThreadsValue(value);
+          }
         }
-    }
 
-    bool sequence_mutex_unavailable = false;
-    m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable);
-    if (sequence_mutex_unavailable)
-    {
-        return false; // We just didn't get the list
+        const size_t threads_pos = stop_info_str.find(";threads:");
+        if (threads_pos != std::string::npos) {
+          const size_t start = threads_pos + strlen(";threads:");
+          const size_t end = stop_info_str.find(';', start);
+          if (end != std::string::npos) {
+            std::string value = stop_info_str.substr(start, end - start);
+            if (UpdateThreadIDsFromStopReplyThreadsValue(value))
+              return true;
+          }
+        }
+      }
+    }
+  }
+
+  bool sequence_mutex_unavailable = false;
+  m_gdb_comm.GetCurrentThreadIDs(m_thread_ids, sequence_mutex_unavailable);
+  if (sequence_mutex_unavailable) {
+    return false; // We just didn't get the list
+  }
+  return true;
+}
+
+bool ProcessGDBRemote::UpdateThreadList(ThreadList &old_thread_list,
+                                        ThreadList &new_thread_list) {
+  // locker will keep a mutex locked until it goes out of scope
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_THREAD));
+  if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+    log->Printf("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__,
+                GetID());
+
+  size_t num_thread_ids = m_thread_ids.size();
+  // The "m_thread_ids" thread ID list should always be updated after each stop
+  // reply packet, but in case it isn't, update it here.
+  if (num_thread_ids == 0) {
+    if (!UpdateThreadIDList())
+      return false;
+    num_thread_ids = m_thread_ids.size();
+  }
+
+  ThreadList old_thread_list_copy(old_thread_list);
+  if (num_thread_ids > 0) {
+    for (size_t i = 0; i < num_thread_ids; ++i) {
+      tid_t tid = m_thread_ids[i];
+      ThreadSP thread_sp(
+          old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
+      if (!thread_sp) {
+        thread_sp.reset(new ThreadGDBRemote(*this, tid));
+        if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+          log->Printf("ProcessGDBRemote::%s Making new thread: %p for thread "
+                      "ID: 0x%" PRIx64 ".\n",
+                      __FUNCTION__, static_cast<void *>(thread_sp.get()),
+                      thread_sp->GetID());
+      } else {
+        if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
+          log->Printf("ProcessGDBRemote::%s Found old thread: %p for thread "
+                      "ID: 0x%" PRIx64 ".\n",
+                      __FUNCTION__, static_cast<void *>(thread_sp.get()),
+                      thread_sp->GetID());
+      }
+      // The m_thread_pcs vector has pc values in big-endian order, not
+      // target-endian, unlike most
+      // of the register read/write packets in gdb-remote protocol.
+      // Early in the process startup, we may not yet have set the process
+      // ByteOrder so we ignore these;
+      // they are a performance improvement over fetching thread register values
+      // individually, the
+      // method we will fall back to if needed.
+      if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() &&
+          GetByteOrder() != eByteOrderInvalid) {
+        ThreadGDBRemote *gdb_thread =
+            static_cast<ThreadGDBRemote *>(thread_sp.get());
+        RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
+        if (reg_ctx_sp) {
+          uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber(
+              eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
+          if (pc_regnum != LLDB_INVALID_REGNUM) {
+            gdb_thread->PrivateSetRegisterValue(pc_regnum, m_thread_pcs[i]);
+          }
+        }
+      }
+      new_thread_list.AddThreadSortedByIndexID(thread_sp);
+    }
+  }
+
+  // Whatever that is left in old_thread_list_copy are not
+  // present in new_thread_list. Remove non-existent threads from internal id
+  // table.
+  size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
+  for (size_t i = 0; i < old_num_thread_ids; i++) {
+    ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
+    if (old_thread_sp) {
+      lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
+      m_thread_id_to_index_id_map.erase(old_thread_id);
+    }
+  }
+
+  return true;
+}
+
+bool ProcessGDBRemote::GetThreadStopInfoFromJSON(
+    ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp) {
+  // See if we got thread stop infos for all threads via the "jThreadsInfo"
+  // packet
+  if (thread_infos_sp) {
+    StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();
+    if (thread_infos) {
+      lldb::tid_t tid;
+      const size_t n = thread_infos->GetSize();
+      for (size_t i = 0; i < n; ++i) {
+        StructuredData::Dictionary *thread_dict =
+            thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+        if (thread_dict) {
+          if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>(
+                  "tid", tid, LLDB_INVALID_THREAD_ID)) {
+            if (tid == thread->GetID())
+              return (bool)SetThreadStopInfo(thread_dict);
+          }
+        }
+      }
+    }
+  }
+  return false;
+}
+
+bool ProcessGDBRemote::CalculateThreadStopInfo(ThreadGDBRemote *thread) {
+  // See if we got thread stop infos for all threads via the "jThreadsInfo"
+  // packet
+  if (GetThreadStopInfoFromJSON(thread, m_jthreadsinfo_sp))
+    return true;
+
+  // See if we got thread stop info for any threads valid stop info reasons
+  // threads
+  // via the "jstopinfo" packet stop reply packet key/value pair?
+  if (m_jstopinfo_sp) {
+    // If we have "jstopinfo" then we have stop descriptions for all threads
+    // that have stop reasons, and if there is no entry for a thread, then
+    // it has no stop reason.
+    thread->GetRegisterContext()->InvalidateIfNeeded(true);
+    if (!GetThreadStopInfoFromJSON(thread, m_jstopinfo_sp)) {
+      thread->SetStopInfo(StopInfoSP());
     }
     return true;
+  }
+
+  // Fall back to using the qThreadStopInfo packet
+  StringExtractorGDBRemote stop_packet;
+  if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
+    return SetThreadStopInfo(stop_packet) == eStateStopped;
+  return false;
 }
 
-bool
-ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
-{
-    // locker will keep a mutex locked until it goes out of scope
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
-    if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
-        log->Printf ("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
-    size_t num_thread_ids = m_thread_ids.size();
-    // The "m_thread_ids" thread ID list should always be updated after each stop
-    // reply packet, but in case it isn't, update it here.
-    if (num_thread_ids == 0)
+ThreadSP ProcessGDBRemote::SetThreadStopInfo(
+    lldb::tid_t tid, ExpeditedRegisterMap &expedited_register_map,
+    uint8_t signo, const std::string &thread_name, const std::string &reason,
+    const std::string &description, uint32_t exc_type,
+    const std::vector<addr_t> &exc_data, addr_t thread_dispatch_qaddr,
+    bool queue_vars_valid, // Set to true if queue_name, queue_kind and
+                           // queue_serial are valid
+    LazyBool associated_with_dispatch_queue, addr_t dispatch_queue_t,
+    std::string &queue_name, QueueKind queue_kind, uint64_t queue_serial) {
+  ThreadSP thread_sp;
+  if (tid != LLDB_INVALID_THREAD_ID) {
+    // Scope for "locker" below
     {
-        if (!UpdateThreadIDList ())
-            return false;
-        num_thread_ids = m_thread_ids.size();
+      // m_thread_list_real does have its own mutex, but we need to
+      // hold onto the mutex between the call to
+      // m_thread_list_real.FindThreadByID(...)
+      // and the m_thread_list_real.AddThread(...) so it doesn't change on us
+      std::lock_guard<std::recursive_mutex> guard(
+          m_thread_list_real.GetMutex());
+      thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
+
+      if (!thread_sp) {
+        // Create the thread if we need to
+        thread_sp.reset(new ThreadGDBRemote(*this, tid));
+        m_thread_list_real.AddThread(thread_sp);
+      }
     }
 
-    ThreadList old_thread_list_copy(old_thread_list);
-    if (num_thread_ids > 0)
-    {
-        for (size_t i=0; i<num_thread_ids; ++i)
-        {
-            tid_t tid = m_thread_ids[i];
-            ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByProtocolID(tid, false));
-            if (!thread_sp)
-            {
-                thread_sp.reset (new ThreadGDBRemote (*this, tid));
-                if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
-                    log->Printf(
-                            "ProcessGDBRemote::%s Making new thread: %p for thread ID: 0x%" PRIx64 ".\n",
-                            __FUNCTION__, static_cast<void*>(thread_sp.get()),
-                            thread_sp->GetID());
-            }
-            else
-            {
-                if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
-                    log->Printf(
-                           "ProcessGDBRemote::%s Found old thread: %p for thread ID: 0x%" PRIx64 ".\n",
-                           __FUNCTION__, static_cast<void*>(thread_sp.get()),
-                           thread_sp->GetID());
-            }
-            // The m_thread_pcs vector has pc values in big-endian order, not target-endian, unlike most
-            // of the register read/write packets in gdb-remote protocol.
-            // Early in the process startup, we may not yet have set the process ByteOrder so we ignore these;
-            // they are a performance improvement over fetching thread register values individually, the
-            // method we will fall back to if needed.
-            if (m_thread_ids.size() == m_thread_pcs.size() && thread_sp.get() && GetByteOrder() != eByteOrderInvalid)
-            {
-                ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
-                RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
-                if (reg_ctx_sp)
-                {
-                    uint32_t pc_regnum = reg_ctx_sp->ConvertRegisterKindToRegisterNumber
-                                                                   (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
-                    if (pc_regnum != LLDB_INVALID_REGNUM)
-                    {
-                        gdb_thread->PrivateSetRegisterValue (pc_regnum, m_thread_pcs[i]);
-                    }
+    if (thread_sp) {
+      ThreadGDBRemote *gdb_thread =
+          static_cast<ThreadGDBRemote *>(thread_sp.get());
+      gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+
+      for (const auto &pair : expedited_register_map) {
+        StringExtractor reg_value_extractor;
+        reg_value_extractor.GetStringRef() = pair.second;
+        DataBufferSP buffer_sp(new DataBufferHeap(
+            reg_value_extractor.GetStringRef().size() / 2, 0));
+        reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
+        gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
+      }
+
+      thread_sp->SetName(thread_name.empty() ? NULL : thread_name.c_str());
+
+      gdb_thread->SetThreadDispatchQAddr(thread_dispatch_qaddr);
+      // Check if the GDB server was able to provide the queue name, kind and
+      // serial number
+      if (queue_vars_valid)
+        gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind,
+                                 queue_serial, dispatch_queue_t,
+                                 associated_with_dispatch_queue);
+      else
+        gdb_thread->ClearQueueInfo();
+
+      gdb_thread->SetAssociatedWithLibdispatchQueue(
+          associated_with_dispatch_queue);
+
+      if (dispatch_queue_t != LLDB_INVALID_ADDRESS)
+        gdb_thread->SetQueueLibdispatchQueueAddress(dispatch_queue_t);
+
+      // Make sure we update our thread stop reason just once
+      if (!thread_sp->StopInfoIsUpToDate()) {
+        thread_sp->SetStopInfo(StopInfoSP());
+        // If there's a memory thread backed by this thread, we need to use it
+        // to calcualte StopInfo.
+        ThreadSP memory_thread_sp =
+            m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
+        if (memory_thread_sp)
+          thread_sp = memory_thread_sp;
+
+        if (exc_type != 0) {
+          const size_t exc_data_size = exc_data.size();
+
+          thread_sp->SetStopInfo(
+              StopInfoMachException::CreateStopReasonWithMachException(
+                  *thread_sp, exc_type, exc_data_size,
+                  exc_data_size >= 1 ? exc_data[0] : 0,
+                  exc_data_size >= 2 ? exc_data[1] : 0,
+                  exc_data_size >= 3 ? exc_data[2] : 0));
+        } else {
+          bool handled = false;
+          bool did_exec = false;
+          if (!reason.empty()) {
+            if (reason.compare("trace") == 0) {
+              addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+              lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+                                                      ->GetBreakpointSiteList()
+                                                      .FindByAddress(pc);
+
+              // If the current pc is a breakpoint site then the StopInfo should
+              // be set to Breakpoint
+              // Otherwise, it will be set to Trace.
+              if (bp_site_sp &&
+                  bp_site_sp->ValidForThisThread(thread_sp.get())) {
+                thread_sp->SetStopInfo(
+                    StopInfo::CreateStopReasonWithBreakpointSiteID(
+                        *thread_sp, bp_site_sp->GetID()));
+              } else
+                thread_sp->SetStopInfo(
+                    StopInfo::CreateStopReasonToTrace(*thread_sp));
+              handled = true;
+            } else if (reason.compare("breakpoint") == 0) {
+              addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+              lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+                                                      ->GetBreakpointSiteList()
+                                                      .FindByAddress(pc);
+              if (bp_site_sp) {
+                // If the breakpoint is for this thread, then we'll report the
+                // hit, but if it is for another thread,
+                // we can just report no reason.  We don't need to worry about
+                // stepping over the breakpoint here, that
+                // will be taken care of when the thread resumes and notices
+                // that there's a breakpoint under the pc.
+                handled = true;
+                if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+                  thread_sp->SetStopInfo(
+                      StopInfo::CreateStopReasonWithBreakpointSiteID(
+                          *thread_sp, bp_site_sp->GetID()));
+                } else {
+                  StopInfoSP invalid_stop_info_sp;
+                  thread_sp->SetStopInfo(invalid_stop_info_sp);
                 }
-            }
-            new_thread_list.AddThreadSortedByIndexID (thread_sp);
-        }
-    }
-
-    // Whatever that is left in old_thread_list_copy are not
-    // present in new_thread_list. Remove non-existent threads from internal id table.
-    size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
-    for (size_t i=0; i<old_num_thread_ids; i++)
-    {
-        ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
-        if (old_thread_sp)
-        {
-            lldb::tid_t old_thread_id = old_thread_sp->GetProtocolID();
-            m_thread_id_to_index_id_map.erase(old_thread_id);
-        }
-    }
-
-    return true;
-}
-
-
-bool
-ProcessGDBRemote::GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp)
-{
-    // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
-    if (thread_infos_sp)
-    {
-        StructuredData::Array *thread_infos = thread_infos_sp->GetAsArray();
-        if (thread_infos)
-        {
-            lldb::tid_t tid;
-            const size_t n = thread_infos->GetSize();
-            for (size_t i=0; i<n; ++i)
-            {
-                StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
-                if (thread_dict)
-                {
-                    if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid, LLDB_INVALID_THREAD_ID))
-                    {
-                        if (tid == thread->GetID())
-                            return (bool)SetThreadStopInfo(thread_dict);
-                    }
+              }
+            } else if (reason.compare("trap") == 0) {
+              // Let the trap just use the standard signal stop reason below...
+            } else if (reason.compare("watchpoint") == 0) {
+              StringExtractor desc_extractor(description.c_str());
+              addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+              uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+              addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+              watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+              if (wp_addr != LLDB_INVALID_ADDRESS) {
+                WatchpointSP wp_sp;
+                ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
+                if ((core >= ArchSpec::kCore_mips_first &&
+                     core <= ArchSpec::kCore_mips_last) ||
+                    (core >= ArchSpec::eCore_arm_generic &&
+                     core <= ArchSpec::eCore_arm_aarch64))
+                  wp_sp = GetTarget().GetWatchpointList().FindByAddress(
+                      wp_hit_addr);
+                if (!wp_sp)
+                  wp_sp =
+                      GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+                if (wp_sp) {
+                  wp_sp->SetHardwareIndex(wp_index);
+                  watch_id = wp_sp->GetID();
                 }
+              }
+              if (watch_id == LLDB_INVALID_WATCH_ID) {
+                Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+                    GDBR_LOG_WATCHPOINTS));
+                if (log)
+                  log->Printf("failed to find watchpoint");
+              }
+              thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID(
+                  *thread_sp, watch_id, wp_hit_addr));
+              handled = true;
+            } else if (reason.compare("exception") == 0) {
+              thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
+                  *thread_sp, description.c_str()));
+              handled = true;
+            } else if (reason.compare("exec") == 0) {
+              did_exec = true;
+              thread_sp->SetStopInfo(
+                  StopInfo::CreateStopReasonWithExec(*thread_sp));
+              handled = true;
             }
-        }
-    }
-    return false;
-}
+          } else if (!signo) {
+            addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+            lldb::BreakpointSiteSP bp_site_sp =
+                thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(
+                    pc);
 
-bool
-ProcessGDBRemote::CalculateThreadStopInfo (ThreadGDBRemote *thread)
-{
-    // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
-    if (GetThreadStopInfoFromJSON (thread, m_jthreadsinfo_sp))
-        return true;
-
-    // See if we got thread stop info for any threads valid stop info reasons threads
-    // via the "jstopinfo" packet stop reply packet key/value pair?
-    if (m_jstopinfo_sp)
-    {
-        // If we have "jstopinfo" then we have stop descriptions for all threads
-        // that have stop reasons, and if there is no entry for a thread, then
-        // it has no stop reason.
-        thread->GetRegisterContext()->InvalidateIfNeeded(true);
-        if (!GetThreadStopInfoFromJSON (thread, m_jstopinfo_sp))
-        {
-            thread->SetStopInfo (StopInfoSP());
-        }
-        return true;
-    }
-
-    // Fall back to using the qThreadStopInfo packet
-    StringExtractorGDBRemote stop_packet;
-    if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
-        return SetThreadStopInfo (stop_packet) == eStateStopped;
-    return false;
-}
-
-
-ThreadSP
-ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
-                                     ExpeditedRegisterMap &expedited_register_map,
-                                     uint8_t signo,
-                                     const std::string &thread_name,
-                                     const std::string &reason,
-                                     const std::string &description,
-                                     uint32_t exc_type,
-                                     const std::vector<addr_t> &exc_data,
-                                     addr_t thread_dispatch_qaddr,
-                                     bool queue_vars_valid, // Set to true if queue_name, queue_kind and queue_serial are valid
-                                     LazyBool associated_with_dispatch_queue,
-                                     addr_t dispatch_queue_t,
-                                     std::string &queue_name,
-                                     QueueKind queue_kind,
-                                     uint64_t queue_serial)
-{
-    ThreadSP thread_sp;
-    if (tid != LLDB_INVALID_THREAD_ID)
-    {
-        // Scope for "locker" below
-        {
-            // m_thread_list_real does have its own mutex, but we need to
-            // hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
-            // and the m_thread_list_real.AddThread(...) so it doesn't change on us
-            std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
-            thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
-
-            if (!thread_sp)
-            {
-                // Create the thread if we need to
-                thread_sp.reset (new ThreadGDBRemote (*this, tid));
-                m_thread_list_real.AddThread(thread_sp);
+            // If the current pc is a breakpoint site then the StopInfo should
+            // be set to Breakpoint
+            // even though the remote stub did not set it as such. This can
+            // happen when
+            // the thread is involuntarily interrupted (e.g. due to stops on
+            // other
+            // threads) just as it is about to execute the breakpoint
+            // instruction.
+            if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get())) {
+              thread_sp->SetStopInfo(
+                  StopInfo::CreateStopReasonWithBreakpointSiteID(
+                      *thread_sp, bp_site_sp->GetID()));
+              handled = true;
             }
-        }
+          }
 
-        if (thread_sp)
-        {
-            ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
-            gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+          if (!handled && signo && did_exec == false) {
+            if (signo == SIGTRAP) {
+              // Currently we are going to assume SIGTRAP means we are either
+              // hitting a breakpoint or hardware single stepping.
+              handled = true;
+              addr_t pc = thread_sp->GetRegisterContext()->GetPC() +
+                          m_breakpoint_pc_offset;
+              lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()
+                                                      ->GetBreakpointSiteList()
+                                                      .FindByAddress(pc);
 
-            for (const auto &pair : expedited_register_map)
-            {
-                StringExtractor reg_value_extractor;
-                reg_value_extractor.GetStringRef() = pair.second;
-                DataBufferSP buffer_sp(new DataBufferHeap(reg_value_extractor.GetStringRef().size() / 2, 0));
-                reg_value_extractor.GetHexBytes(buffer_sp->GetData(), '\xcc');
-                gdb_thread->PrivateSetRegisterValue(pair.first, buffer_sp->GetData());
-            }
-
-            thread_sp->SetName (thread_name.empty() ? NULL : thread_name.c_str());
-
-            gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
-            // Check if the GDB server was able to provide the queue name, kind and serial number
-            if (queue_vars_valid)
-                gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial, dispatch_queue_t, associated_with_dispatch_queue);
-            else
-                gdb_thread->ClearQueueInfo();
-
-            gdb_thread->SetAssociatedWithLibdispatchQueue (associated_with_dispatch_queue);
-
-            if (dispatch_queue_t != LLDB_INVALID_ADDRESS)
-                gdb_thread->SetQueueLibdispatchQueueAddress (dispatch_queue_t);
-
-            // Make sure we update our thread stop reason just once
-            if (!thread_sp->StopInfoIsUpToDate())
-            {
-                thread_sp->SetStopInfo (StopInfoSP());
-                // If there's a memory thread backed by this thread, we need to use it to calcualte StopInfo.
-                ThreadSP memory_thread_sp = m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID());
-                if (memory_thread_sp)
-                    thread_sp = memory_thread_sp;
-
-                if (exc_type != 0)
-                {
-                    const size_t exc_data_size = exc_data.size();
-
-                    thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
-                                                                                                      exc_type,
-                                                                                                      exc_data_size,
-                                                                                                      exc_data_size >= 1 ? exc_data[0] : 0,
-                                                                                                      exc_data_size >= 2 ? exc_data[1] : 0,
-                                                                                                      exc_data_size >= 3 ? exc_data[2] : 0));
+              if (bp_site_sp) {
+                // If the breakpoint is for this thread, then we'll report the
+                // hit, but if it is for another thread,
+                // we can just report no reason.  We don't need to worry about
+                // stepping over the breakpoint here, that
+                // will be taken care of when the thread resumes and notices
+                // that there's a breakpoint under the pc.
+                if (bp_site_sp->ValidForThisThread(thread_sp.get())) {
+                  if (m_breakpoint_pc_offset != 0)
+                    thread_sp->GetRegisterContext()->SetPC(pc);
+                  thread_sp->SetStopInfo(
+                      StopInfo::CreateStopReasonWithBreakpointSiteID(
+                          *thread_sp, bp_site_sp->GetID()));
+                } else {
+                  StopInfoSP invalid_stop_info_sp;
+                  thread_sp->SetStopInfo(invalid_stop_info_sp);
                 }
+              } else {
+                // If we were stepping then assume the stop was the result of
+                // the trace.  If we were
+                // not stepping then report the SIGTRAP.
+                // FIXME: We are still missing the case where we single step
+                // over a trap instruction.
+                if (thread_sp->GetTemporaryResumeState() == eStateStepping)
+                  thread_sp->SetStopInfo(
+                      StopInfo::CreateStopReasonToTrace(*thread_sp));
                 else
-                {
-                    bool handled = false;
-                    bool did_exec = false;
-                    if (!reason.empty())
-                    {
-                        if (reason.compare("trace") == 0)
-                        {
-                            addr_t pc = thread_sp->GetRegisterContext()->GetPC();
-                            lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
-                            // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
-                            // Otherwise, it will be set to Trace.
-                            if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
-                            {
-                                thread_sp->SetStopInfo(
-                                    StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
-                            }
-                            else
-                              thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
-                            handled = true;
-                        }
-                        else if (reason.compare("breakpoint") == 0)
-                        {
-                            addr_t pc = thread_sp->GetRegisterContext()->GetPC();
-                            lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-                            if (bp_site_sp)
-                            {
-                                // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
-                                // we can just report no reason.  We don't need to worry about stepping over the breakpoint here, that
-                                // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
-                                handled = true;
-                                if (bp_site_sp->ValidForThisThread (thread_sp.get()))
-                                {
-                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
-                                }
-                                else
-                                {
-                                    StopInfoSP invalid_stop_info_sp;
-                                    thread_sp->SetStopInfo (invalid_stop_info_sp);
-                                }
-                            }
-                        }
-                        else if (reason.compare("trap") == 0)
-                        {
-                            // Let the trap just use the standard signal stop reason below...
-                        }
-                        else if (reason.compare("watchpoint") == 0)
-                        {
-                            StringExtractor desc_extractor(description.c_str());
-                            addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
-                            uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
-                            addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
-                            watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
-                            if (wp_addr != LLDB_INVALID_ADDRESS)
-                            {
-                                WatchpointSP wp_sp;
-                                ArchSpec::Core core = GetTarget().GetArchitecture().GetCore();
-                                if ((core >= ArchSpec::kCore_mips_first && core <= ArchSpec::kCore_mips_last) ||
-                                    (core >= ArchSpec::eCore_arm_generic && core <= ArchSpec::eCore_arm_aarch64))
-                                    wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr);
-                                if (!wp_sp)
-                                    wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
-                                if (wp_sp)
-                                {
-                                    wp_sp->SetHardwareIndex(wp_index);
-                                    watch_id = wp_sp->GetID();
-                                }
-                            }
-                            if (watch_id == LLDB_INVALID_WATCH_ID)
-                            {
-                                Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
-                                if (log) log->Printf ("failed to find watchpoint");
-                            }
-                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id, wp_hit_addr));
-                            handled = true;
-                        }
-                        else if (reason.compare("exception") == 0)
-                        {
-                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
-                            handled = true;
-                        }
-                        else if (reason.compare("exec") == 0)
-                        {
-                            did_exec = true;
-                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
-                            handled = true;
-                        }
-                    }
-                    else if (!signo)
-                    {
-                        addr_t pc = thread_sp->GetRegisterContext()->GetPC();
-                        lldb::BreakpointSiteSP bp_site_sp =
-                            thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
-                        // If the current pc is a breakpoint site then the StopInfo should be set to Breakpoint
-                        // even though the remote stub did not set it as such. This can happen when
-                        // the thread is involuntarily interrupted (e.g. due to stops on other
-                        // threads) just as it is about to execute the breakpoint instruction.
-                        if (bp_site_sp && bp_site_sp->ValidForThisThread(thread_sp.get()))
-                        {
-                            thread_sp->SetStopInfo(
-                                StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp, bp_site_sp->GetID()));
-                            handled = true;
-                        }
-                    }
-
-                    if (!handled && signo && did_exec == false)
-                    {
-                        if (signo == SIGTRAP)
-                        {
-                            // Currently we are going to assume SIGTRAP means we are either
-                            // hitting a breakpoint or hardware single stepping.
-                            handled = true;
-                            addr_t pc = thread_sp->GetRegisterContext()->GetPC() + m_breakpoint_pc_offset;
-                            lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
-                            if (bp_site_sp)
-                            {
-                                // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
-                                // we can just report no reason.  We don't need to worry about stepping over the breakpoint here, that
-                                // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
-                                if (bp_site_sp->ValidForThisThread (thread_sp.get()))
-                                {
-                                    if(m_breakpoint_pc_offset != 0)
-                                        thread_sp->GetRegisterContext()->SetPC(pc);
-                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
-                                }
-                                else
-                                {
-                                    StopInfoSP invalid_stop_info_sp;
-                                    thread_sp->SetStopInfo (invalid_stop_info_sp);
-                                }
-                            }
-                            else
-                            {
-                                // If we were stepping then assume the stop was the result of the trace.  If we were
-                                // not stepping then report the SIGTRAP.
-                                // FIXME: We are still missing the case where we single step over a trap instruction.
-                                if (thread_sp->GetTemporaryResumeState() == eStateStepping)
-                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
-                                else
-                                    thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo, description.c_str()));
-                            }
-                        }
-                        if (!handled)
-                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo, description.c_str()));
-                    }
-
-                    if (!description.empty())
-                    {
-                        lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
-                        if (stop_info_sp)
-                        {
-                            const char *stop_info_desc = stop_info_sp->GetDescription();
-                            if (!stop_info_desc || !stop_info_desc[0])
-                                stop_info_sp->SetDescription (description.c_str());
-                        }
-                        else
-                        {
-                            thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
-                        }
-                    }
-                }
+                  thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+                      *thread_sp, signo, description.c_str()));
+              }
             }
+            if (!handled)
+              thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithSignal(
+                  *thread_sp, signo, description.c_str()));
+          }
+
+          if (!description.empty()) {
+            lldb::StopInfoSP stop_info_sp(thread_sp->GetStopInfo());
+            if (stop_info_sp) {
+              const char *stop_info_desc = stop_info_sp->GetDescription();
+              if (!stop_info_desc || !stop_info_desc[0])
+                stop_info_sp->SetDescription(description.c_str());
+            } else {
+              thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException(
+                  *thread_sp, description.c_str()));
+            }
+          }
         }
+      }
     }
-    return thread_sp;
+  }
+  return thread_sp;
 }
 
 lldb::ThreadSP
-ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict)
-{
-    static ConstString g_key_tid("tid");
-    static ConstString g_key_name("name");
-    static ConstString g_key_reason("reason");
-    static ConstString g_key_metype("metype");
-    static ConstString g_key_medata("medata");
-    static ConstString g_key_qaddr("qaddr");
-    static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
-    static ConstString g_key_associated_with_dispatch_queue("associated_with_dispatch_queue");
-    static ConstString g_key_queue_name("qname");
-    static ConstString g_key_queue_kind("qkind");
-    static ConstString g_key_queue_serial_number("qserialnum");
-    static ConstString g_key_registers("registers");
-    static ConstString g_key_memory("memory");
-    static ConstString g_key_address("address");
-    static ConstString g_key_bytes("bytes");
-    static ConstString g_key_description("description");
-    static ConstString g_key_signal("signal");
+ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) {
+  static ConstString g_key_tid("tid");
+  static ConstString g_key_name("name");
+  static ConstString g_key_reason("reason");
+  static ConstString g_key_metype("metype");
+  static ConstString g_key_medata("medata");
+  static ConstString g_key_qaddr("qaddr");
+  static ConstString g_key_dispatch_queue_t("dispatch_queue_t");
+  static ConstString g_key_associated_with_dispatch_queue(
+      "associated_with_dispatch_queue");
+  static ConstString g_key_queue_name("qname");
+  static ConstString g_key_queue_kind("qkind");
+  static ConstString g_key_queue_serial_number("qserialnum");
+  static ConstString g_key_registers("registers");
+  static ConstString g_key_memory("memory");
+  static ConstString g_key_address("address");
+  static ConstString g_key_bytes("bytes");
+  static ConstString g_key_description("description");
+  static ConstString g_key_signal("signal");
 
+  // Stop with signal and thread info
+  lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+  uint8_t signo = 0;
+  std::string value;
+  std::string thread_name;
+  std::string reason;
+  std::string description;
+  uint32_t exc_type = 0;
+  std::vector<addr_t> exc_data;
+  addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
+  ExpeditedRegisterMap expedited_register_map;
+  bool queue_vars_valid = false;
+  addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
+  LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
+  std::string queue_name;
+  QueueKind queue_kind = eQueueKindUnknown;
+  uint64_t queue_serial_number = 0;
+  // Iterate through all of the thread dictionary key/value pairs from the
+  // structured data dictionary
+
+  thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name,
+                        &signo, &reason, &description, &exc_type, &exc_data,
+                        &thread_dispatch_qaddr, &queue_vars_valid,
+                        &associated_with_dispatch_queue, &dispatch_queue_t,
+                        &queue_name, &queue_kind, &queue_serial_number](
+                           ConstString key,
+                           StructuredData::Object *object) -> bool {
+    if (key == g_key_tid) {
+      // thread in big endian hex
+      tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+    } else if (key == g_key_metype) {
+      // exception type in big endian hex
+      exc_type = object->GetIntegerValue(0);
+    } else if (key == g_key_medata) {
+      // exception data in big endian hex
+      StructuredData::Array *array = object->GetAsArray();
+      if (array) {
+        array->ForEach([&exc_data](StructuredData::Object *object) -> bool {
+          exc_data.push_back(object->GetIntegerValue());
+          return true; // Keep iterating through all array items
+        });
+      }
+    } else if (key == g_key_name) {
+      thread_name = object->GetStringValue();
+    } else if (key == g_key_qaddr) {
+      thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
+    } else if (key == g_key_queue_name) {
+      queue_vars_valid = true;
+      queue_name = object->GetStringValue();
+    } else if (key == g_key_queue_kind) {
+      std::string queue_kind_str = object->GetStringValue();
+      if (queue_kind_str == "serial") {
+        queue_vars_valid = true;
+        queue_kind = eQueueKindSerial;
+      } else if (queue_kind_str == "concurrent") {
+        queue_vars_valid = true;
+        queue_kind = eQueueKindConcurrent;
+      }
+    } else if (key == g_key_queue_serial_number) {
+      queue_serial_number = object->GetIntegerValue(0);
+      if (queue_serial_number != 0)
+        queue_vars_valid = true;
+    } else if (key == g_key_dispatch_queue_t) {
+      dispatch_queue_t = object->GetIntegerValue(0);
+      if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
+        queue_vars_valid = true;
+    } else if (key == g_key_associated_with_dispatch_queue) {
+      queue_vars_valid = true;
+      bool associated = object->GetBooleanValue();
+      if (associated)
+        associated_with_dispatch_queue = eLazyBoolYes;
+      else
+        associated_with_dispatch_queue = eLazyBoolNo;
+    } else if (key == g_key_reason) {
+      reason = object->GetStringValue();
+    } else if (key == g_key_description) {
+      description = object->GetStringValue();
+    } else if (key == g_key_registers) {
+      StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
+
+      if (registers_dict) {
+        registers_dict->ForEach(
+            [&expedited_register_map](ConstString key,
+                                      StructuredData::Object *object) -> bool {
+              const uint32_t reg =
+                  StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10);
+              if (reg != UINT32_MAX)
+                expedited_register_map[reg] = object->GetStringValue();
+              return true; // Keep iterating through all array items
+            });
+      }
+    } else if (key == g_key_memory) {
+      StructuredData::Array *array = object->GetAsArray();
+      if (array) {
+        array->ForEach([this](StructuredData::Object *object) -> bool {
+          StructuredData::Dictionary *mem_cache_dict =
+              object->GetAsDictionary();
+          if (mem_cache_dict) {
+            lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+            if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>(
+                    "address", mem_cache_addr)) {
+              if (mem_cache_addr != LLDB_INVALID_ADDRESS) {
+                StringExtractor bytes;
+                if (mem_cache_dict->GetValueForKeyAsString(
+                        "bytes", bytes.GetStringRef())) {
+                  bytes.SetFilePos(0);
+
+                  const size_t byte_size = bytes.GetStringRef().size() / 2;
+                  DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+                  const size_t bytes_copied =
+                      bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
+                  if (bytes_copied == byte_size)
+                    m_memory_cache.AddL1CacheData(mem_cache_addr,
+                                                  data_buffer_sp);
+                }
+              }
+            }
+          }
+          return true; // Keep iterating through all array items
+        });
+      }
+
+    } else if (key == g_key_signal)
+      signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
+    return true; // Keep iterating through all dictionary key/value pairs
+  });
+
+  return SetThreadStopInfo(tid, expedited_register_map, signo, thread_name,
+                           reason, description, exc_type, exc_data,
+                           thread_dispatch_qaddr, queue_vars_valid,
+                           associated_with_dispatch_queue, dispatch_queue_t,
+                           queue_name, queue_kind, queue_serial_number);
+}
+
+StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) {
+  stop_packet.SetFilePos(0);
+  const char stop_type = stop_packet.GetChar();
+  switch (stop_type) {
+  case 'T':
+  case 'S': {
+    // This is a bit of a hack, but is is required. If we did exec, we
+    // need to clear our thread lists and also know to rebuild our dynamic
+    // register info before we lookup and threads and populate the expedited
+    // register values so we need to know this right away so we can cleanup
+    // and update our registers.
+    const uint32_t stop_id = GetStopID();
+    if (stop_id == 0) {
+      // Our first stop, make sure we have a process ID, and also make
+      // sure we know about our registers
+      if (GetID() == LLDB_INVALID_PROCESS_ID) {
+        lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+        if (pid != LLDB_INVALID_PROCESS_ID)
+          SetID(pid);
+      }
+      BuildDynamicRegisterInfo(true);
+    }
     // Stop with signal and thread info
     lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-    uint8_t signo = 0;
-    std::string value;
+    const uint8_t signo = stop_packet.GetHexU8();
+    llvm::StringRef key;
+    llvm::StringRef value;
     std::string thread_name;
     std::string reason;
     std::string description;
     uint32_t exc_type = 0;
     std::vector<addr_t> exc_data;
     addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
-    ExpeditedRegisterMap expedited_register_map;
-    bool queue_vars_valid = false;
+    bool queue_vars_valid =
+        false; // says if locals below that start with "queue_" are valid
     addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
     LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
     std::string queue_name;
     QueueKind queue_kind = eQueueKindUnknown;
     uint64_t queue_serial_number = 0;
-    // Iterate through all of the thread dictionary key/value pairs from the structured data dictionary
+    ExpeditedRegisterMap expedited_register_map;
+    while (stop_packet.GetNameColonValue(key, value)) {
+      if (key.compare("metype") == 0) {
+        // exception type in big endian hex
+        value.getAsInteger(16, exc_type);
+      } else if (key.compare("medata") == 0) {
+        // exception data in big endian hex
+        uint64_t x;
+        value.getAsInteger(16, x);
+        exc_data.push_back(x);
+      } else if (key.compare("thread") == 0) {
+        // thread in big endian hex
+        if (value.getAsInteger(16, tid))
+          tid = LLDB_INVALID_THREAD_ID;
+      } else if (key.compare("threads") == 0) {
+        std::lock_guard<std::recursive_mutex> guard(
+            m_thread_list_real.GetMutex());
 
-    thread_dict->ForEach([this,
-                          &tid,
-                          &expedited_register_map,
-                          &thread_name,
-                          &signo,
-                          &reason,
-                          &description,
-                          &exc_type,
-                          &exc_data,
-                          &thread_dispatch_qaddr,
-                          &queue_vars_valid,
-                          &associated_with_dispatch_queue,
-                          &dispatch_queue_t,
-                          &queue_name,
-                          &queue_kind,
-                          &queue_serial_number]
-                          (ConstString key, StructuredData::Object* object) -> bool
-    {
-        if (key == g_key_tid)
-        {
-            // thread in big endian hex
-            tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+        m_thread_ids.clear();
+        // A comma separated list of all threads in the current
+        // process that includes the thread for this stop reply
+        // packet
+        lldb::tid_t tid;
+        while (!value.empty()) {
+          llvm::StringRef tid_str;
+          std::tie(tid_str, value) = value.split(',');
+          if (tid_str.getAsInteger(16, tid))
+            tid = LLDB_INVALID_THREAD_ID;
+          m_thread_ids.push_back(tid);
         }
-        else if (key == g_key_metype)
-        {
-            // exception type in big endian hex
-            exc_type = object->GetIntegerValue(0);
+      } else if (key.compare("thread-pcs") == 0) {
+        m_thread_pcs.clear();
+        // A comma separated list of all threads in the current
+        // process that includes the thread for this stop reply
+        // packet
+        lldb::addr_t pc;
+        while (!value.empty()) {
+          llvm::StringRef pc_str;
+          std::tie(pc_str, value) = value.split(',');
+          if (pc_str.getAsInteger(16, pc))
+            pc = LLDB_INVALID_ADDRESS;
+          m_thread_pcs.push_back(pc);
         }
-        else if (key == g_key_medata)
-        {
-            // exception data in big endian hex
-            StructuredData::Array *array = object->GetAsArray();
-            if (array)
-            {
-                array->ForEach([&exc_data](StructuredData::Object* object) -> bool {
-                    exc_data.push_back(object->GetIntegerValue());
-                    return true; // Keep iterating through all array items
-                });
-            }
-        }
-        else if (key == g_key_name)
-        {
-            thread_name = object->GetStringValue();
-        }
-        else if (key == g_key_qaddr)
-        {
-            thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
-        }
-        else if (key == g_key_queue_name)
-        {
-            queue_vars_valid = true;
-            queue_name = object->GetStringValue();
-        }
-        else if (key == g_key_queue_kind)
-        {
-            std::string queue_kind_str = object->GetStringValue();
-            if (queue_kind_str == "serial")
-            {
-                queue_vars_valid = true;
-                queue_kind = eQueueKindSerial;
-            }
-            else if (queue_kind_str == "concurrent")
-            {
-                queue_vars_valid = true;
-                queue_kind = eQueueKindConcurrent;
-            }
-        }
-        else if (key == g_key_queue_serial_number)
-        {
-            queue_serial_number = object->GetIntegerValue(0);
-            if (queue_serial_number != 0)
-                queue_vars_valid = true;
-        }
-        else if (key == g_key_dispatch_queue_t)
-        {
-            dispatch_queue_t = object->GetIntegerValue(0);
-            if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS)
-                queue_vars_valid = true;
-        }
-        else if (key == g_key_associated_with_dispatch_queue)
-        {
-            queue_vars_valid = true;
-            bool associated = object->GetBooleanValue ();
-            if (associated)
-                associated_with_dispatch_queue = eLazyBoolYes;
-            else
-                associated_with_dispatch_queue = eLazyBoolNo;
-        }
-        else if (key == g_key_reason)
-        {
-            reason = object->GetStringValue();
-        }
-        else if (key == g_key_description)
-        {
-            description = object->GetStringValue();
-        }
-        else if (key == g_key_registers)
-        {
-            StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
+      } else if (key.compare("jstopinfo") == 0) {
+        StringExtractor json_extractor(value);
+        std::string json;
+        // Now convert the HEX bytes into a string value
+        json_extractor.GetHexByteString(json);
 
-            if (registers_dict)
-            {
-                registers_dict->ForEach([&expedited_register_map](ConstString key, StructuredData::Object* object) -> bool {
-                    const uint32_t reg = StringConvert::ToUInt32 (key.GetCString(), UINT32_MAX, 10);
-                    if (reg != UINT32_MAX)
-                        expedited_register_map[reg] = object->GetStringValue();
-                    return true; // Keep iterating through all array items
-                });
-            }
+        // This JSON contains thread IDs and thread stop info for all threads.
+        // It doesn't contain expedited registers, memory or queue info.
+        m_jstopinfo_sp = StructuredData::ParseJSON(json);
+      } else if (key.compare("hexname") == 0) {
+        StringExtractor name_extractor(value);
+        std::string name;
+        // Now convert the HEX bytes into a string value
+        name_extractor.GetHexByteString(thread_name);
+      } else if (key.compare("name") == 0) {
+        thread_name = value;
+      } else if (key.compare("qaddr") == 0) {
+        value.getAsInteger(16, thread_dispatch_qaddr);
+      } else if (key.compare("dispatch_queue_t") == 0) {
+        queue_vars_valid = true;
+        value.getAsInteger(16, dispatch_queue_t);
+      } else if (key.compare("qname") == 0) {
+        queue_vars_valid = true;
+        StringExtractor name_extractor(value);
+        // Now convert the HEX bytes into a string value
+        name_extractor.GetHexByteString(queue_name);
+      } else if (key.compare("qkind") == 0) {
+        queue_kind = llvm::StringSwitch<QueueKind>(value)
+                         .Case("serial", eQueueKindSerial)
+                         .Case("concurrent", eQueueKindConcurrent)
+                         .Default(eQueueKindUnknown);
+        queue_vars_valid = queue_kind != eQueueKindUnknown;
+      } else if (key.compare("qserialnum") == 0) {
+        if (!value.getAsInteger(0, queue_serial_number))
+          queue_vars_valid = true;
+      } else if (key.compare("reason") == 0) {
+        reason = value;
+      } else if (key.compare("description") == 0) {
+        StringExtractor desc_extractor(value);
+        // Now convert the HEX bytes into a string value
+        desc_extractor.GetHexByteString(description);
+      } else if (key.compare("memory") == 0) {
+        // Expedited memory. GDB servers can choose to send back expedited
+        // memory
+        // that can populate the L1 memory cache in the process so that things
+        // like
+        // the frame pointer backchain can be expedited. This will help stack
+        // backtracing be more efficient by not having to send as many memory
+        // read
+        // requests down the remote GDB server.
+
+        // Key/value pair format: memory:<addr>=<bytes>;
+        // <addr> is a number whose base will be interpreted by the prefix:
+        //      "0x[0-9a-fA-F]+" for hex
+        //      "0[0-7]+" for octal
+        //      "[1-9]+" for decimal
+        // <bytes> is native endian ASCII hex bytes just like the register
+        // values
+        llvm::StringRef addr_str, bytes_str;
+        std::tie(addr_str, bytes_str) = value.split('=');
+        if (!addr_str.empty() && !bytes_str.empty()) {
+          lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+          if (!addr_str.getAsInteger(0, mem_cache_addr)) {
+            StringExtractor bytes(bytes_str);
+            const size_t byte_size = bytes.GetBytesLeft() / 2;
+            DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+            const size_t bytes_copied =
+                bytes.GetHexBytes(data_buffer_sp->GetData(), 0);
+            if (bytes_copied == byte_size)
+              m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
+          }
         }
-        else if (key == g_key_memory)
-        {
-            StructuredData::Array *array = object->GetAsArray();
-            if (array)
-            {
-                array->ForEach([this](StructuredData::Object* object) -> bool {
-                    StructuredData::Dictionary *mem_cache_dict = object->GetAsDictionary();
-                    if (mem_cache_dict)
-                    {
-                        lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
-                        if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>("address", mem_cache_addr))
-                        {
-                            if (mem_cache_addr != LLDB_INVALID_ADDRESS)
-                            {
-                                StringExtractor bytes;
-                                if (mem_cache_dict->GetValueForKeyAsString("bytes", bytes.GetStringRef()))
-                                {
-                                    bytes.SetFilePos(0);
+      } else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 ||
+                 key.compare("awatch") == 0) {
+        // Support standard GDB remote stop reply packet 'TAAwatch:addr'
+        lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;
+        value.getAsInteger(16, wp_addr);
 
-                                    const size_t byte_size = bytes.GetStringRef().size()/2;
-                                    DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
-                                    const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetData(), 0);
-                                    if (bytes_copied == byte_size)
-                                        m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
-                                }
-                            }
-                        }
-                    }
-                    return true; // Keep iterating through all array items
-                });
-            }
+        WatchpointSP wp_sp =
+            GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+        uint32_t wp_index = LLDB_INVALID_INDEX32;
 
-        }
-        else if (key == g_key_signal)
-            signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER);
-        return true; // Keep iterating through all dictionary key/value pairs
-    });
+        if (wp_sp)
+          wp_index = wp_sp->GetHardwareIndex();
 
-    return SetThreadStopInfo (tid,
-                              expedited_register_map,
-                              signo,
-                              thread_name,
-                              reason,
-                              description,
-                              exc_type,
-                              exc_data,
-                              thread_dispatch_qaddr,
-                              queue_vars_valid,
-                              associated_with_dispatch_queue,
-                              dispatch_queue_t,
-                              queue_name,
-                              queue_kind,
-                              queue_serial_number);
+        reason = "watchpoint";
+        StreamString ostr;
+        ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
+        description = ostr.GetString().c_str();
+      } else if (key.compare("library") == 0) {
+        LoadModules();
+      } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) {
+        uint32_t reg = UINT32_MAX;
+        if (!key.getAsInteger(16, reg))
+          expedited_register_map[reg] = std::move(value);
+      }
+    }
+
+    if (tid == LLDB_INVALID_THREAD_ID) {
+      // A thread id may be invalid if the response is old style 'S' packet
+      // which does not provide the
+      // thread information. So update the thread list and choose the first one.
+      UpdateThreadIDList();
+
+      if (!m_thread_ids.empty()) {
+        tid = m_thread_ids.front();
+      }
+    }
+
+    ThreadSP thread_sp = SetThreadStopInfo(
+        tid, expedited_register_map, signo, thread_name, reason, description,
+        exc_type, exc_data, thread_dispatch_qaddr, queue_vars_valid,
+        associated_with_dispatch_queue, dispatch_queue_t, queue_name,
+        queue_kind, queue_serial_number);
+
+    return eStateStopped;
+  } break;
+
+  case 'W':
+  case 'X':
+    // process exited
+    return eStateExited;
+
+  default:
+    break;
+  }
+  return eStateInvalid;
 }
 
-StateType
-ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
-{
-    stop_packet.SetFilePos (0);
-    const char stop_type = stop_packet.GetChar();
-    switch (stop_type)
-    {
-    case 'T':
-    case 'S':
-        {
-            // This is a bit of a hack, but is is required. If we did exec, we
-            // need to clear our thread lists and also know to rebuild our dynamic
-            // register info before we lookup and threads and populate the expedited
-            // register values so we need to know this right away so we can cleanup
-            // and update our registers.
-            const uint32_t stop_id = GetStopID();
-            if (stop_id == 0)
-            {
-                // Our first stop, make sure we have a process ID, and also make
-                // sure we know about our registers
-                if (GetID() == LLDB_INVALID_PROCESS_ID)
-                {
-                    lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
-                    if (pid != LLDB_INVALID_PROCESS_ID)
-                        SetID (pid);
-                }
-                BuildDynamicRegisterInfo (true);
-            }
-            // Stop with signal and thread info
-            lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
-            const uint8_t signo = stop_packet.GetHexU8();
-            llvm::StringRef key;
-            llvm::StringRef value;
-            std::string thread_name;
-            std::string reason;
-            std::string description;
-            uint32_t exc_type = 0;
-            std::vector<addr_t> exc_data;
-            addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
-            bool queue_vars_valid = false; // says if locals below that start with "queue_" are valid
-            addr_t dispatch_queue_t = LLDB_INVALID_ADDRESS;
-            LazyBool associated_with_dispatch_queue = eLazyBoolCalculate;
-            std::string queue_name;
-            QueueKind queue_kind = eQueueKindUnknown;
-            uint64_t queue_serial_number = 0;
-            ExpeditedRegisterMap expedited_register_map;
-            while (stop_packet.GetNameColonValue(key, value))
-            {
-                if (key.compare("metype") == 0)
-                {
-                    // exception type in big endian hex
-                    value.getAsInteger(16, exc_type);
-                }
-                else if (key.compare("medata") == 0)
-                {
-                    // exception data in big endian hex
-                    uint64_t x;
-                    value.getAsInteger(16, x);
-                    exc_data.push_back(x);
-                }
-                else if (key.compare("thread") == 0)
-                {
-                    // thread in big endian hex
-                    if (value.getAsInteger(16, tid))
-                        tid = LLDB_INVALID_THREAD_ID;
-                }
-                else if (key.compare("threads") == 0)
-                {
-                    std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+void ProcessGDBRemote::RefreshStateAfterStop() {
+  std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
 
-                    m_thread_ids.clear();
-                    // A comma separated list of all threads in the current
-                    // process that includes the thread for this stop reply
-                    // packet
-                    lldb::tid_t tid;
-                    while (!value.empty())
-                    {
-                        llvm::StringRef tid_str;
-                        std::tie(tid_str, value) = value.split(',');
-                        if (tid_str.getAsInteger(16, tid))
-                            tid = LLDB_INVALID_THREAD_ID;
-                        m_thread_ids.push_back(tid);
-                    }
-                }
-                else if (key.compare("thread-pcs") == 0)
-                {
-                    m_thread_pcs.clear();
-                    // A comma separated list of all threads in the current
-                    // process that includes the thread for this stop reply
-                    // packet
-                    lldb::addr_t pc;
-                    while (!value.empty())
-                    {
-                        llvm::StringRef pc_str;
-                        std::tie(pc_str, value) = value.split(',');
-                        if (pc_str.getAsInteger(16, pc))
-                            pc = LLDB_INVALID_ADDRESS;
-                        m_thread_pcs.push_back(pc);
-                    }
-                }
-                else if (key.compare("jstopinfo") == 0)
-                {
-                    StringExtractor json_extractor(value);
-                    std::string json;
-                    // Now convert the HEX bytes into a string value
-                    json_extractor.GetHexByteString(json);
+  m_thread_ids.clear();
+  m_thread_pcs.clear();
+  // Set the thread stop info. It might have a "threads" key whose value is
+  // a list of all thread IDs in the current process, so m_thread_ids might
+  // get set.
 
-                    // This JSON contains thread IDs and thread stop info for all threads.
-                    // It doesn't contain expedited registers, memory or queue info.
-                    m_jstopinfo_sp = StructuredData::ParseJSON(json);
-                }
-                else if (key.compare("hexname") == 0)
-                {
-                    StringExtractor name_extractor(value);
-                    std::string name;
-                    // Now convert the HEX bytes into a string value
-                    name_extractor.GetHexByteString(thread_name);
-                }
-                else if (key.compare("name") == 0)
-                {
-                    thread_name = value;
-                }
-                else if (key.compare("qaddr") == 0)
-                {
-                    value.getAsInteger(16, thread_dispatch_qaddr);
-                }
-                else if (key.compare("dispatch_queue_t") == 0)
-                {
-                    queue_vars_valid = true;
-                    value.getAsInteger(16, dispatch_queue_t);
-                }
-                else if (key.compare("qname") == 0)
-                {
-                    queue_vars_valid = true;
-                    StringExtractor name_extractor(value);
-                    // Now convert the HEX bytes into a string value
-                    name_extractor.GetHexByteString(queue_name);
-                }
-                else if (key.compare("qkind") == 0)
-                {
-                    queue_kind = llvm::StringSwitch<QueueKind>(value)
-                                     .Case("serial", eQueueKindSerial)
-                                     .Case("concurrent", eQueueKindConcurrent)
-                                     .Default(eQueueKindUnknown);
-                    queue_vars_valid = queue_kind != eQueueKindUnknown;
-                }
-                else if (key.compare("qserialnum") == 0)
-                {
-                    if (!value.getAsInteger(0, queue_serial_number))
-                        queue_vars_valid = true;
-                }
-                else if (key.compare("reason") == 0)
-                {
-                    reason = value;
-                }
-                else if (key.compare("description") == 0)
-                {
-                    StringExtractor desc_extractor(value);
-                    // Now convert the HEX bytes into a string value
-                    desc_extractor.GetHexByteString(description);
-                }
-                else if (key.compare("memory") == 0)
-                {
-                    // Expedited memory. GDB servers can choose to send back expedited memory
-                    // that can populate the L1 memory cache in the process so that things like
-                    // the frame pointer backchain can be expedited. This will help stack
-                    // backtracing be more efficient by not having to send as many memory read
-                    // requests down the remote GDB server.
-
-                    // Key/value pair format: memory:<addr>=<bytes>;
-                    // <addr> is a number whose base will be interpreted by the prefix:
-                    //      "0x[0-9a-fA-F]+" for hex
-                    //      "0[0-7]+" for octal
-                    //      "[1-9]+" for decimal
-                    // <bytes> is native endian ASCII hex bytes just like the register values
-                    llvm::StringRef addr_str, bytes_str;
-                    std::tie(addr_str, bytes_str) = value.split('=');
-                    if (!addr_str.empty() && !bytes_str.empty())
-                    {
-                        lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
-                        if (!addr_str.getAsInteger(0, mem_cache_addr))
-                        {
-                            StringExtractor bytes(bytes_str);
-                            const size_t byte_size = bytes.GetBytesLeft() / 2;
-                            DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
-                            const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetData(), 0);
-                            if (bytes_copied == byte_size)
-                                m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
-                        }
-                    }
-                }
-                else if (key.compare("watch") == 0 || key.compare("rwatch") == 0 || key.compare("awatch") == 0)
-                {
-                    // Support standard GDB remote stop reply packet 'TAAwatch:addr'
-                    lldb::addr_t wp_addr = LLDB_INVALID_ADDRESS;
-                    value.getAsInteger(16, wp_addr);
-
-                    WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
-                    uint32_t wp_index = LLDB_INVALID_INDEX32;
-
-                    if (wp_sp)
-                        wp_index = wp_sp->GetHardwareIndex();
-
-                    reason = "watchpoint";
-                    StreamString ostr;
-                    ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index);
-                    description = ostr.GetString().c_str();
-                }
-                else if (key.compare("library") == 0)
-                {
-                    LoadModules();
-                }
-                else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1]))
-                {
-                    uint32_t reg = UINT32_MAX;
-                    if (!key.getAsInteger(16, reg))
-                        expedited_register_map[reg] = std::move(value);
-                }
-            }
-
-            if (tid == LLDB_INVALID_THREAD_ID)
-            {
-                // A thread id may be invalid if the response is old style 'S' packet which does not provide the
-                // thread information. So update the thread list and choose the first one.
-                UpdateThreadIDList ();
-
-                if (!m_thread_ids.empty ())
-                {
-                    tid = m_thread_ids.front ();
-                }
-            }
-
-            ThreadSP thread_sp = SetThreadStopInfo (tid,
-                                                    expedited_register_map,
-                                                    signo,
-                                                    thread_name,
-                                                    reason,
-                                                    description,
-                                                    exc_type,
-                                                    exc_data,
-                                                    thread_dispatch_qaddr,
-                                                    queue_vars_valid,
-                                                    associated_with_dispatch_queue,
-                                                    dispatch_queue_t,
-                                                    queue_name,
-                                                    queue_kind,
-                                                    queue_serial_number);
-
-            return eStateStopped;
-        }
-        break;
-
-    case 'W':
-    case 'X':
-        // process exited
-        return eStateExited;
-
-    default:
-        break;
+  // Scope for the lock
+  {
+    // Lock the thread stack while we access it
+    std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+    // Get the number of stop packets on the stack
+    int nItems = m_stop_packet_stack.size();
+    // Iterate over them
+    for (int i = 0; i < nItems; i++) {
+      // Get the thread stop info
+      StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
+      // Process thread stop info
+      SetThreadStopInfo(stop_info);
     }
-    return eStateInvalid;
+    // Clear the thread stop stack
+    m_stop_packet_stack.clear();
+  }
+
+  // Check to see if SetThreadStopInfo() filled in m_thread_ids?
+  if (m_thread_ids.empty()) {
+    // No, we need to fetch the thread list manually
+    UpdateThreadIDList();
+  }
+
+  // If we have queried for a default thread id
+  if (m_initial_tid != LLDB_INVALID_THREAD_ID) {
+    m_thread_list.SetSelectedThreadByID(m_initial_tid);
+    m_initial_tid = LLDB_INVALID_THREAD_ID;
+  }
+
+  // Let all threads recover from stopping and do any clean up based
+  // on the previous thread state (if any).
+  m_thread_list_real.RefreshStateAfterStop();
 }
 
-void
-ProcessGDBRemote::RefreshStateAfterStop ()
-{
-    std::lock_guard<std::recursive_mutex> guard(m_thread_list_real.GetMutex());
+Error ProcessGDBRemote::DoHalt(bool &caused_stop) {
+  Error error;
 
-    m_thread_ids.clear();
-    m_thread_pcs.clear();
-    // Set the thread stop info. It might have a "threads" key whose value is
-    // a list of all thread IDs in the current process, so m_thread_ids might
-    // get set.
-
-    // Scope for the lock
-    {
-        // Lock the thread stack while we access it
-        std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
-        // Get the number of stop packets on the stack
-        int nItems = m_stop_packet_stack.size();
-        // Iterate over them
-        for (int i = 0; i < nItems; i++)
-        {
-            // Get the thread stop info
-            StringExtractorGDBRemote stop_info = m_stop_packet_stack[i];
-            // Process thread stop info
-            SetThreadStopInfo(stop_info);
-        }
-        // Clear the thread stop stack
-        m_stop_packet_stack.clear();
-    }
-
-    // Check to see if SetThreadStopInfo() filled in m_thread_ids?
-    if (m_thread_ids.empty())
-    {
-        // No, we need to fetch the thread list manually
-        UpdateThreadIDList();
-    }
-
-    // If we have queried for a default thread id
-    if (m_initial_tid != LLDB_INVALID_THREAD_ID)
-    {
-        m_thread_list.SetSelectedThreadByID(m_initial_tid);
-        m_initial_tid = LLDB_INVALID_THREAD_ID;
-    }
-
-    // Let all threads recover from stopping and do any clean up based
-    // on the previous thread state (if any).
-    m_thread_list_real.RefreshStateAfterStop();
-
+  if (m_public_state.GetValue() == eStateAttaching) {
+    // We are being asked to halt during an attach. We need to just close
+    // our file handle and debugserver will go away, and we can be done...
+    m_gdb_comm.Disconnect();
+  } else
+    caused_stop = m_gdb_comm.Interrupt();
+  return error;
 }
 
-Error
-ProcessGDBRemote::DoHalt (bool &caused_stop)
-{
-    Error error;
+Error ProcessGDBRemote::DoDetach(bool keep_stopped) {
+  Error error;
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
 
-    if (m_public_state.GetValue() == eStateAttaching)
-    {
-        // We are being asked to halt during an attach. We need to just close
-        // our file handle and debugserver will go away, and we can be done...
-        m_gdb_comm.Disconnect();
-    }
+  error = m_gdb_comm.Detach(keep_stopped);
+  if (log) {
+    if (error.Success())
+      log->PutCString(
+          "ProcessGDBRemote::DoDetach() detach packet sent successfully");
     else
-        caused_stop = m_gdb_comm.Interrupt();
+      log->Printf("ProcessGDBRemote::DoDetach() detach packet send failed: %s",
+                  error.AsCString() ? error.AsCString() : "<unknown error>");
+  }
+
+  if (!error.Success())
     return error;
+
+  // Sleep for one second to let the process get all detached...
+  StopAsyncThread();
+
+  SetPrivateState(eStateDetached);
+  ResumePrivateStateThread();
+
+  // KillDebugserverProcess ();
+  return error;
 }
 
-Error
-ProcessGDBRemote::DoDetach(bool keep_stopped)
-{
-    Error error;
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("ProcessGDBRemote::DoDetach(keep_stopped: %i)", keep_stopped);
+Error ProcessGDBRemote::DoDestroy() {
+  Error error;
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("ProcessGDBRemote::DoDestroy()");
 
-    error = m_gdb_comm.Detach (keep_stopped);
-    if (log)
-    {
-        if (error.Success())
-            log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully");
-        else
-            log->Printf ("ProcessGDBRemote::DoDetach() detach packet send failed: %s", error.AsCString() ? error.AsCString() : "<unknown error>");
-    }
+  // There is a bug in older iOS debugservers where they don't shut down the
+  // process
+  // they are debugging properly.  If the process is sitting at a breakpoint or
+  // an exception,
+  // this can cause problems with restarting.  So we check to see if any of our
+  // threads are stopped
+  // at a breakpoint, and if so we remove all the breakpoints, resume the
+  // process, and THEN
+  // destroy it again.
+  //
+  // Note, we don't have a good way to test the version of debugserver, but I
+  // happen to know that
+  // the set of all the iOS debugservers which don't support
+  // GetThreadSuffixSupported() and that of
+  // the debugservers with this bug are equal.  There really should be a better
+  // way to test this!
+  //
+  // We also use m_destroy_tried_resuming to make sure we only do this once, if
+  // we resume and then halt and
+  // get called here to destroy again and we're still at a breakpoint or
+  // exception, then we should
+  // just do the straight-forward kill.
+  //
+  // And of course, if we weren't able to stop the process by the time we get
+  // here, it isn't
+  // necessary (or helpful) to do any of this.
 
-    if (!error.Success())
-        return error;
+  if (!m_gdb_comm.GetThreadSuffixSupported() &&
+      m_public_state.GetValue() != eStateRunning) {
+    PlatformSP platform_sp = GetTarget().GetPlatform();
 
-    // Sleep for one second to let the process get all detached...
-    StopAsyncThread ();
-
-    SetPrivateState (eStateDetached);
-    ResumePrivateStateThread();
-
-    //KillDebugserverProcess ();
-    return error;
-}
-
-
-Error
-ProcessGDBRemote::DoDestroy ()
-{
-    Error error;
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("ProcessGDBRemote::DoDestroy()");
-
-    // There is a bug in older iOS debugservers where they don't shut down the process
-    // they are debugging properly.  If the process is sitting at a breakpoint or an exception,
-    // this can cause problems with restarting.  So we check to see if any of our threads are stopped
-    // at a breakpoint, and if so we remove all the breakpoints, resume the process, and THEN
-    // destroy it again.
-    //
-    // Note, we don't have a good way to test the version of debugserver, but I happen to know that
-    // the set of all the iOS debugservers which don't support GetThreadSuffixSupported() and that of
-    // the debugservers with this bug are equal.  There really should be a better way to test this!
-    //
-    // We also use m_destroy_tried_resuming to make sure we only do this once, if we resume and then halt and
-    // get called here to destroy again and we're still at a breakpoint or exception, then we should
-    // just do the straight-forward kill.
-    //
-    // And of course, if we weren't able to stop the process by the time we get here, it isn't
-    // necessary (or helpful) to do any of this.
-
-    if (!m_gdb_comm.GetThreadSuffixSupported() && m_public_state.GetValue() != eStateRunning)
-    {
-        PlatformSP platform_sp = GetTarget().GetPlatform();
-
-        // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
-        if (platform_sp
-            && platform_sp->GetName()
-            && platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic())
-        {
-            if (m_destroy_tried_resuming)
-            {
-                if (log)
-                    log->PutCString ("ProcessGDBRemote::DoDestroy() - Tried resuming to destroy once already, not doing it again.");
-            }
-            else
-            {
-                // At present, the plans are discarded and the breakpoints disabled Process::Destroy,
-                // but we really need it to happen here and it doesn't matter if we do it twice.
-                m_thread_list.DiscardThreadPlans();
-                DisableAllBreakpointSites();
-
-                bool stop_looks_like_crash = false;
-                ThreadList &threads = GetThreadList();
-
-                {
-                    std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
-                    size_t num_threads = threads.GetSize();
-                    for (size_t i = 0; i < num_threads; i++)
-                    {
-                        ThreadSP thread_sp = threads.GetThreadAtIndex(i);
-                        StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
-                        StopReason reason = eStopReasonInvalid;
-                        if (stop_info_sp)
-                            reason = stop_info_sp->GetStopReason();
-                        if (reason == eStopReasonBreakpoint
-                            || reason == eStopReasonException)
-                        {
-                            if (log)
-                                log->Printf ("ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64 " stopped with reason: %s.",
-                                             thread_sp->GetProtocolID(),
-                                             stop_info_sp->GetDescription());
-                            stop_looks_like_crash = true;
-                            break;
-                        }
-                    }
-                }
-
-                if (stop_looks_like_crash)
-                {
-                    if (log)
-                        log->PutCString ("ProcessGDBRemote::DoDestroy() - Stopped at a breakpoint, continue and then kill.");
-                    m_destroy_tried_resuming = true;
-
-                    // If we are going to run again before killing, it would be good to suspend all the threads
-                    // before resuming so they won't get into more trouble.  Sadly, for the threads stopped with
-                    // the breakpoint or exception, the exception doesn't get cleared if it is suspended, so we do
-                    // have to run the risk of letting those threads proceed a bit.
-
-                    {
-                        std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
-
-                        size_t num_threads = threads.GetSize();
-                        for (size_t i = 0; i < num_threads; i++)
-                        {
-                            ThreadSP thread_sp = threads.GetThreadAtIndex(i);
-                            StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
-                            StopReason reason = eStopReasonInvalid;
-                            if (stop_info_sp)
-                                reason = stop_info_sp->GetStopReason();
-                            if (reason != eStopReasonBreakpoint
-                                && reason != eStopReasonException)
-                            {
-                                if (log)
-                                    log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: 0x%4.4" PRIx64 " before running.",
-                                                 thread_sp->GetProtocolID());
-                                thread_sp->SetResumeState(eStateSuspended);
-                            }
-                        }
-                    }
-                    Resume ();
-                    return Destroy(false);
-                }
-            }
-        }
-    }
-
-    // Interrupt if our inferior is running...
-    int exit_status = SIGABRT;
-    std::string exit_string;
-
-    if (m_gdb_comm.IsConnected())
-    {
-        if (m_public_state.GetValue() != eStateAttaching)
-        {
-            StringExtractorGDBRemote response;
-            bool send_async = true;
-            GDBRemoteCommunication::ScopedTimeout (m_gdb_comm, 3);
-
-            if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async) == GDBRemoteCommunication::PacketResult::Success)
-            {
-                char packet_cmd = response.GetChar(0);
-
-                if (packet_cmd == 'W' || packet_cmd == 'X')
-                {
-#if defined(__APPLE__)
-                    // For Native processes on Mac OS X, we launch through the Host Platform, then hand the process off
-                    // to debugserver, which becomes the parent process through "PT_ATTACH".  Then when we go to kill
-                    // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we call waitpid which returns
-                    // with no error and the correct status.  But amusingly enough that doesn't seem to actually reap
-                    // the process, but instead it is left around as a Zombie.  Probably the kernel is in the process of
-                    // switching ownership back to lldb which was the original parent, and gets confused in the handoff.
-                    // Anyway, so call waitpid here to finally reap it.
-                    PlatformSP platform_sp(GetTarget().GetPlatform());
-                    if (platform_sp && platform_sp->IsHost())
-                    {
-                        int status;
-                        ::pid_t reap_pid;
-                        reap_pid = waitpid (GetID(), &status, WNOHANG);
-                        if (log)
-                            log->Printf ("Reaped pid: %d, status: %d.\n", reap_pid, status);
-                    }
-#endif
-                    SetLastStopPacket (response);
-                    ClearThreadIDList ();
-                    exit_status = response.GetHexU8();
-                }
-                else
-                {
-                    if (log)
-                        log->Printf ("ProcessGDBRemote::DoDestroy - got unexpected response to k packet: %s", response.GetStringRef().c_str());
-                    exit_string.assign("got unexpected response to k packet: ");
-                    exit_string.append(response.GetStringRef());
-                }
-            }
-            else
-            {
-                if (log)
-                    log->Printf ("ProcessGDBRemote::DoDestroy - failed to send k packet");
-                exit_string.assign("failed to send the k packet");
-            }
-        }
-        else
-        {
-            if (log)
-                log->Printf ("ProcessGDBRemote::DoDestroy - killed or interrupted while attaching");
-            exit_string.assign ("killed or interrupted while attaching.");
-        }
-    }
-    else
-    {
-        // If we missed setting the exit status on the way out, do it here.
-        // NB set exit status can be called multiple times, the first one sets the status.
-        exit_string.assign("destroying when not connected to debugserver");
-    }
-
-    SetExitStatus(exit_status, exit_string.c_str());
-
-    StopAsyncThread ();
-    KillDebugserverProcess ();
-    return error;
-}
-
-void
-ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
-{
-    const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
-    if (did_exec)
-    {
-        Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+    // FIXME: These should be ConstStrings so we aren't doing strcmp'ing.
+    if (platform_sp && platform_sp->GetName() &&
+        platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic()) {
+      if (m_destroy_tried_resuming) {
         if (log)
-            log->Printf ("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+          log->PutCString("ProcessGDBRemote::DoDestroy() - Tried resuming to "
+                          "destroy once already, not doing it again.");
+      } else {
+        // At present, the plans are discarded and the breakpoints disabled
+        // Process::Destroy,
+        // but we really need it to happen here and it doesn't matter if we do
+        // it twice.
+        m_thread_list.DiscardThreadPlans();
+        DisableAllBreakpointSites();
 
-        m_thread_list_real.Clear();
-        m_thread_list.Clear();
-        BuildDynamicRegisterInfo (true);
-        m_gdb_comm.ResetDiscoverableSettings (did_exec);
+        bool stop_looks_like_crash = false;
+        ThreadList &threads = GetThreadList();
+
+        {
+          std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+
+          size_t num_threads = threads.GetSize();
+          for (size_t i = 0; i < num_threads; i++) {
+            ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+            StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
+            StopReason reason = eStopReasonInvalid;
+            if (stop_info_sp)
+              reason = stop_info_sp->GetStopReason();
+            if (reason == eStopReasonBreakpoint ||
+                reason == eStopReasonException) {
+              if (log)
+                log->Printf(
+                    "ProcessGDBRemote::DoDestroy() - thread: 0x%4.4" PRIx64
+                    " stopped with reason: %s.",
+                    thread_sp->GetProtocolID(), stop_info_sp->GetDescription());
+              stop_looks_like_crash = true;
+              break;
+            }
+          }
+        }
+
+        if (stop_looks_like_crash) {
+          if (log)
+            log->PutCString("ProcessGDBRemote::DoDestroy() - Stopped at a "
+                            "breakpoint, continue and then kill.");
+          m_destroy_tried_resuming = true;
+
+          // If we are going to run again before killing, it would be good to
+          // suspend all the threads
+          // before resuming so they won't get into more trouble.  Sadly, for
+          // the threads stopped with
+          // the breakpoint or exception, the exception doesn't get cleared if
+          // it is suspended, so we do
+          // have to run the risk of letting those threads proceed a bit.
+
+          {
+            std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+
+            size_t num_threads = threads.GetSize();
+            for (size_t i = 0; i < num_threads; i++) {
+              ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+              StopInfoSP stop_info_sp = thread_sp->GetPrivateStopInfo();
+              StopReason reason = eStopReasonInvalid;
+              if (stop_info_sp)
+                reason = stop_info_sp->GetStopReason();
+              if (reason != eStopReasonBreakpoint &&
+                  reason != eStopReasonException) {
+                if (log)
+                  log->Printf("ProcessGDBRemote::DoDestroy() - Suspending "
+                              "thread: 0x%4.4" PRIx64 " before running.",
+                              thread_sp->GetProtocolID());
+                thread_sp->SetResumeState(eStateSuspended);
+              }
+            }
+          }
+          Resume();
+          return Destroy(false);
+        }
+      }
     }
+  }
 
-    // Scope the lock
-    {
-        // Lock the thread stack while we access it
-        std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+  // Interrupt if our inferior is running...
+  int exit_status = SIGABRT;
+  std::string exit_string;
 
-        // We are are not using non-stop mode, there can only be one last stop
-        // reply packet, so clear the list.
-        if (GetTarget().GetNonStopModeEnabled() == false)
-            m_stop_packet_stack.clear();
+  if (m_gdb_comm.IsConnected()) {
+    if (m_public_state.GetValue() != eStateAttaching) {
+      StringExtractorGDBRemote response;
+      bool send_async = true;
+      GDBRemoteCommunication::ScopedTimeout(m_gdb_comm, 3);
 
-        // Add this stop packet to the stop packet stack
-        // This stack will get popped and examined when we switch to the
-        // Stopped state
-        m_stop_packet_stack.push_back(response);
+      if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response,
+                                                  send_async) ==
+          GDBRemoteCommunication::PacketResult::Success) {
+        char packet_cmd = response.GetChar(0);
+
+        if (packet_cmd == 'W' || packet_cmd == 'X') {
+#if defined(__APPLE__)
+          // For Native processes on Mac OS X, we launch through the Host
+          // Platform, then hand the process off
+          // to debugserver, which becomes the parent process through
+          // "PT_ATTACH".  Then when we go to kill
+          // the process on Mac OS X we call ptrace(PT_KILL) to kill it, then we
+          // call waitpid which returns
+          // with no error and the correct status.  But amusingly enough that
+          // doesn't seem to actually reap
+          // the process, but instead it is left around as a Zombie.  Probably
+          // the kernel is in the process of
+          // switching ownership back to lldb which was the original parent, and
+          // gets confused in the handoff.
+          // Anyway, so call waitpid here to finally reap it.
+          PlatformSP platform_sp(GetTarget().GetPlatform());
+          if (platform_sp && platform_sp->IsHost()) {
+            int status;
+            ::pid_t reap_pid;
+            reap_pid = waitpid(GetID(), &status, WNOHANG);
+            if (log)
+              log->Printf("Reaped pid: %d, status: %d.\n", reap_pid, status);
+          }
+#endif
+          SetLastStopPacket(response);
+          ClearThreadIDList();
+          exit_status = response.GetHexU8();
+        } else {
+          if (log)
+            log->Printf("ProcessGDBRemote::DoDestroy - got unexpected response "
+                        "to k packet: %s",
+                        response.GetStringRef().c_str());
+          exit_string.assign("got unexpected response to k packet: ");
+          exit_string.append(response.GetStringRef());
+        }
+      } else {
+        if (log)
+          log->Printf("ProcessGDBRemote::DoDestroy - failed to send k packet");
+        exit_string.assign("failed to send the k packet");
+      }
+    } else {
+      if (log)
+        log->Printf("ProcessGDBRemote::DoDestroy - killed or interrupted while "
+                    "attaching");
+      exit_string.assign("killed or interrupted while attaching.");
     }
+  } else {
+    // If we missed setting the exit status on the way out, do it here.
+    // NB set exit status can be called multiple times, the first one sets the
+    // status.
+    exit_string.assign("destroying when not connected to debugserver");
+  }
+
+  SetExitStatus(exit_status, exit_string.c_str());
+
+  StopAsyncThread();
+  KillDebugserverProcess();
+  return error;
 }
 
-void
-ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp)
-{
-    Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
+void ProcessGDBRemote::SetLastStopPacket(
+    const StringExtractorGDBRemote &response) {
+  const bool did_exec =
+      response.GetStringRef().find(";reason:exec;") != std::string::npos;
+  if (did_exec) {
+    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+    if (log)
+      log->Printf("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+
+    m_thread_list_real.Clear();
+    m_thread_list.Clear();
+    BuildDynamicRegisterInfo(true);
+    m_gdb_comm.ResetDiscoverableSettings(did_exec);
+  }
+
+  // Scope the lock
+  {
+    // Lock the thread stack while we access it
+    std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex);
+
+    // We are are not using non-stop mode, there can only be one last stop
+    // reply packet, so clear the list.
+    if (GetTarget().GetNonStopModeEnabled() == false)
+      m_stop_packet_stack.clear();
+
+    // Add this stop packet to the stop packet stack
+    // This stack will get popped and examined when we switch to the
+    // Stopped state
+    m_stop_packet_stack.push_back(response);
+  }
+}
+
+void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) {
+  Process::SetUnixSignals(std::make_shared<GDBRemoteSignals>(signals_sp));
 }
 
 //------------------------------------------------------------------
 // Process Queries
 //------------------------------------------------------------------
 
-bool
-ProcessGDBRemote::IsAlive ()
-{
-    return m_gdb_comm.IsConnected() && Process::IsAlive();
+bool ProcessGDBRemote::IsAlive() {
+  return m_gdb_comm.IsConnected() && Process::IsAlive();
 }
 
-addr_t
-ProcessGDBRemote::GetImageInfoAddress()
-{
-    // request the link map address via the $qShlibInfoAddr packet
-    lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
+addr_t ProcessGDBRemote::GetImageInfoAddress() {
+  // request the link map address via the $qShlibInfoAddr packet
+  lldb::addr_t addr = m_gdb_comm.GetShlibInfoAddr();
 
-    // the loaded module list can also provides a link map address
-    if (addr == LLDB_INVALID_ADDRESS)
-    {
-        LoadedModuleInfoList list;
-        if (GetLoadedModuleList (list).Success())
-            addr = list.m_link_map;
-    }
+  // the loaded module list can also provides a link map address
+  if (addr == LLDB_INVALID_ADDRESS) {
+    LoadedModuleInfoList list;
+    if (GetLoadedModuleList(list).Success())
+      addr = list.m_link_map;
+  }
 
-    return addr;
+  return addr;
 }
 
-void
-ProcessGDBRemote::WillPublicStop ()
-{
-    // See if the GDB remote client supports the JSON threads info.
-    // If so, we gather stop info for all threads, expedited registers,
-    // expedited memory, runtime queue information (iOS and MacOSX only),
-    // and more. Expediting memory will help stack backtracing be much
-    // faster. Expediting registers will make sure we don't have to read
-    // the thread registers for GPRs.
-    m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
+void ProcessGDBRemote::WillPublicStop() {
+  // See if the GDB remote client supports the JSON threads info.
+  // If so, we gather stop info for all threads, expedited registers,
+  // expedited memory, runtime queue information (iOS and MacOSX only),
+  // and more. Expediting memory will help stack backtracing be much
+  // faster. Expediting registers will make sure we don't have to read
+  // the thread registers for GPRs.
+  m_jthreadsinfo_sp = m_gdb_comm.GetThreadsInfo();
 
-    if (m_jthreadsinfo_sp)
-    {
-        // Now set the stop info for each thread and also expedite any registers
-        // and memory that was in the jThreadsInfo response.
-        StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
-        if (thread_infos)
-        {
-            const size_t n = thread_infos->GetSize();
-            for (size_t i=0; i<n; ++i)
-            {
-                StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
-                if (thread_dict)
-                    SetThreadStopInfo(thread_dict);
-            }
-        }
+  if (m_jthreadsinfo_sp) {
+    // Now set the stop info for each thread and also expedite any registers
+    // and memory that was in the jThreadsInfo response.
+    StructuredData::Array *thread_infos = m_jthreadsinfo_sp->GetAsArray();
+    if (thread_infos) {
+      const size_t n = thread_infos->GetSize();
+      for (size_t i = 0; i < n; ++i) {
+        StructuredData::Dictionary *thread_dict =
+            thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+        if (thread_dict)
+          SetThreadStopInfo(thread_dict);
+      }
     }
+  }
 }
 
 //------------------------------------------------------------------
 // Process Memory
 //------------------------------------------------------------------
-size_t
-ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
-{
-    GetMaxMemorySize ();
-    if (size > m_max_memory_size)
-    {
-        // Keep memory read sizes down to a sane limit. This function will be
-        // called multiple times in order to complete the task by
-        // lldb_private::Process so it is ok to do this.
-        size = m_max_memory_size;
-    }
+size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size,
+                                      Error &error) {
+  GetMaxMemorySize();
+  if (size > m_max_memory_size) {
+    // Keep memory read sizes down to a sane limit. This function will be
+    // called multiple times in order to complete the task by
+    // lldb_private::Process so it is ok to do this.
+    size = m_max_memory_size;
+  }
 
-    char packet[64];
-    int packet_len;
-    bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
-    packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
-                            binary_memory_read ? 'x' : 'm', (uint64_t)addr, (uint64_t)size);
-    assert (packet_len + 1 < (int)sizeof(packet));
-    StringExtractorGDBRemote response;
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true) == GDBRemoteCommunication::PacketResult::Success)
-    {
-        if (response.IsNormalResponse())
-        {
-            error.Clear();
-            if (binary_memory_read)
-            {
-                // The lower level GDBRemoteCommunication packet receive layer has already de-quoted any
-                // 0x7d character escaping that was present in the packet
+  char packet[64];
+  int packet_len;
+  bool binary_memory_read = m_gdb_comm.GetxPacketSupported();
+  packet_len = ::snprintf(packet, sizeof(packet), "%c%" PRIx64 ",%" PRIx64,
+                          binary_memory_read ? 'x' : 'm', (uint64_t)addr,
+                          (uint64_t)size);
+  assert(packet_len + 1 < (int)sizeof(packet));
+  StringExtractorGDBRemote response;
+  if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response,
+                                              true) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    if (response.IsNormalResponse()) {
+      error.Clear();
+      if (binary_memory_read) {
+        // The lower level GDBRemoteCommunication packet receive layer has
+        // already de-quoted any
+        // 0x7d character escaping that was present in the packet
 
-                size_t data_received_size = response.GetBytesLeft();
-                if (data_received_size > size)
-                {
-                    // Don't write past the end of BUF if the remote debug server gave us too
-                    // much data for some reason.
-                    data_received_size = size;
-                }
-                memcpy (buf, response.GetStringRef().data(), data_received_size);
-                return data_received_size;
-            }
-            else
-            {
-                return response.GetHexBytes(llvm::MutableArrayRef<uint8_t>((uint8_t*)buf, size), '\xdd');
-            }
+        size_t data_received_size = response.GetBytesLeft();
+        if (data_received_size > size) {
+          // Don't write past the end of BUF if the remote debug server gave us
+          // too
+          // much data for some reason.
+          data_received_size = size;
         }
-        else if (response.IsErrorResponse())
-            error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
-        else if (response.IsUnsupportedResponse())
-            error.SetErrorStringWithFormat("GDB server does not support reading memory");
-        else
-            error.SetErrorStringWithFormat("unexpected response to GDB server memory read packet '%s': '%s'", packet, response.GetStringRef().c_str());
-    }
+        memcpy(buf, response.GetStringRef().data(), data_received_size);
+        return data_received_size;
+      } else {
+        return response.GetHexBytes(
+            llvm::MutableArrayRef<uint8_t>((uint8_t *)buf, size), '\xdd');
+      }
+    } else if (response.IsErrorResponse())
+      error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
+    else if (response.IsUnsupportedResponse())
+      error.SetErrorStringWithFormat(
+          "GDB server does not support reading memory");
     else
-    {
-        error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
-    }
-    return 0;
+      error.SetErrorStringWithFormat(
+          "unexpected response to GDB server memory read packet '%s': '%s'",
+          packet, response.GetStringRef().c_str());
+  } else {
+    error.SetErrorStringWithFormat("failed to send packet: '%s'", packet);
+  }
+  return 0;
 }
 
-size_t
-ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error)
-{
-    GetMaxMemorySize ();
-    if (size > m_max_memory_size)
-    {
-        // Keep memory read sizes down to a sane limit. This function will be
-        // called multiple times in order to complete the task by
-        // lldb_private::Process so it is ok to do this.
-        size = m_max_memory_size;
-    }
+size_t ProcessGDBRemote::DoWriteMemory(addr_t addr, const void *buf,
+                                       size_t size, Error &error) {
+  GetMaxMemorySize();
+  if (size > m_max_memory_size) {
+    // Keep memory read sizes down to a sane limit. This function will be
+    // called multiple times in order to complete the task by
+    // lldb_private::Process so it is ok to do this.
+    size = m_max_memory_size;
+  }
 
-    StreamString packet;
-    packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
-    packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(), endian::InlHostByteOrder());
-    StringExtractorGDBRemote response;
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true) == GDBRemoteCommunication::PacketResult::Success)
-    {
-        if (response.IsOKResponse())
-        {
-            error.Clear();
-            return size;
-        }
-        else if (response.IsErrorResponse())
-            error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64, addr);
-        else if (response.IsUnsupportedResponse())
-            error.SetErrorStringWithFormat("GDB server does not support writing memory");
-        else
-            error.SetErrorStringWithFormat("unexpected response to GDB server memory write packet '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
-    }
+  StreamString packet;
+  packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
+  packet.PutBytesAsRawHex8(buf, size, endian::InlHostByteOrder(),
+                           endian::InlHostByteOrder());
+  StringExtractorGDBRemote response;
+  if (m_gdb_comm.SendPacketAndWaitForResponse(
+          packet.GetData(), packet.GetSize(), response, true) ==
+      GDBRemoteCommunication::PacketResult::Success) {
+    if (response.IsOKResponse()) {
+      error.Clear();
+      return size;
+    } else if (response.IsErrorResponse())
+      error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64,
+                                     addr);
+    else if (response.IsUnsupportedResponse())
+      error.SetErrorStringWithFormat(
+          "GDB server does not support writing memory");
     else
-    {
-        error.SetErrorStringWithFormat("failed to send packet: '%s'", packet.GetString().c_str());
+      error.SetErrorStringWithFormat(
+          "unexpected response to GDB server memory write packet '%s': '%s'",
+          packet.GetString().c_str(), response.GetStringRef().c_str());
+  } else {
+    error.SetErrorStringWithFormat("failed to send packet: '%s'",
+                                   packet.GetString().c_str());
+  }
+  return 0;
+}
+
+lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
+                                                uint32_t permissions,
+                                                Error &error) {
+  Log *log(
+      GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_EXPRESSIONS));
+  addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+
+  if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo) {
+    allocated_addr = m_gdb_comm.AllocateMemory(size, permissions);
+    if (allocated_addr != LLDB_INVALID_ADDRESS ||
+        m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
+      return allocated_addr;
+  }
+
+  if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo) {
+    // Call mmap() to create memory in the inferior..
+    unsigned prot = 0;
+    if (permissions & lldb::ePermissionsReadable)
+      prot |= eMmapProtRead;
+    if (permissions & lldb::ePermissionsWritable)
+      prot |= eMmapProtWrite;
+    if (permissions & lldb::ePermissionsExecutable)
+      prot |= eMmapProtExec;
+
+    if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
+                         eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
+      m_addr_to_mmap_size[allocated_addr] = size;
+    else {
+      allocated_addr = LLDB_INVALID_ADDRESS;
+      if (log)
+        log->Printf("ProcessGDBRemote::%s no direct stub support for memory "
+                    "allocation, and InferiorCallMmap also failed - is stub "
+                    "missing register context save/restore capability?",
+                    __FUNCTION__);
     }
-    return 0;
+  }
+
+  if (allocated_addr == LLDB_INVALID_ADDRESS)
+    error.SetErrorStringWithFormat(
+        "unable to allocate %" PRIu64 " bytes of memory with permissions %s",
+        (uint64_t)size, GetPermissionsAsCString(permissions));
+  else
+    error.Clear();
+  return allocated_addr;
 }
 
-lldb::addr_t
-ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error)
-{
-    Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_EXPRESSIONS));
-    addr_t allocated_addr = LLDB_INVALID_ADDRESS;
+Error ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
+                                            MemoryRegionInfo &region_info) {
 
-    if (m_gdb_comm.SupportsAllocDeallocMemory() != eLazyBoolNo)
+  Error error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
+  return error;
+}
+
+Error ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num) {
+
+  Error error(m_gdb_comm.GetWatchpointSupportInfo(num));
+  return error;
+}
+
+Error ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
+  Error error(m_gdb_comm.GetWatchpointSupportInfo(
+      num, after, GetTarget().GetArchitecture()));
+  return error;
+}
+
+Error ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) {
+  Error error;
+  LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
+
+  switch (supported) {
+  case eLazyBoolCalculate:
+    // We should never be deallocating memory without allocating memory
+    // first so we should never get eLazyBoolCalculate
+    error.SetErrorString(
+        "tried to deallocate memory without ever allocating memory");
+    break;
+
+  case eLazyBoolYes:
+    if (!m_gdb_comm.DeallocateMemory(addr))
+      error.SetErrorStringWithFormat(
+          "unable to deallocate memory at 0x%" PRIx64, addr);
+    break;
+
+  case eLazyBoolNo:
+    // Call munmap() to deallocate memory in the inferior..
     {
-        allocated_addr = m_gdb_comm.AllocateMemory (size, permissions);
-        if (allocated_addr != LLDB_INVALID_ADDRESS || m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolYes)
-            return allocated_addr;
+      MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
+      if (pos != m_addr_to_mmap_size.end() &&
+          InferiorCallMunmap(this, addr, pos->second))
+        m_addr_to_mmap_size.erase(pos);
+      else
+        error.SetErrorStringWithFormat(
+            "unable to deallocate memory at 0x%" PRIx64, addr);
     }
+    break;
+  }
 
-    if (m_gdb_comm.SupportsAllocDeallocMemory() == eLazyBoolNo)
-    {
-        // Call mmap() to create memory in the inferior..
-        unsigned prot = 0;
-        if (permissions & lldb::ePermissionsReadable)
-            prot |= eMmapProtRead;
-        if (permissions & lldb::ePermissionsWritable)
-            prot |= eMmapProtWrite;
-        if (permissions & lldb::ePermissionsExecutable)
-            prot |= eMmapProtExec;
-
-        if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
-                             eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0))
-            m_addr_to_mmap_size[allocated_addr] = size;
-        else
-        {
-            allocated_addr = LLDB_INVALID_ADDRESS;
-            if (log)
-                log->Printf ("ProcessGDBRemote::%s no direct stub support for memory allocation, and InferiorCallMmap also failed - is stub missing register context save/restore capability?", __FUNCTION__);
-        }
-    }
-
-    if (allocated_addr == LLDB_INVALID_ADDRESS)
-        error.SetErrorStringWithFormat("unable to allocate %" PRIu64 " bytes of memory with permissions %s", (uint64_t)size, GetPermissionsAsCString (permissions));
-    else
-        error.Clear();
-    return allocated_addr;
+  return error;
 }
 
-Error
-ProcessGDBRemote::GetMemoryRegionInfo (addr_t load_addr,
-                                       MemoryRegionInfo &region_info)
-{
-
-    Error error (m_gdb_comm.GetMemoryRegionInfo (load_addr, region_info));
-    return error;
-}
-
-Error
-ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num)
-{
-
-    Error error (m_gdb_comm.GetWatchpointSupportInfo (num));
-    return error;
-}
-
-Error
-ProcessGDBRemote::GetWatchpointSupportInfo (uint32_t &num, bool& after)
-{
-    Error error (m_gdb_comm.GetWatchpointSupportInfo (num, after, GetTarget().GetArchitecture()));
-    return error;
-}
-
-Error
-ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr)
-{
-    Error error;
-    LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory();
-
-    switch (supported)
-    {
-        case eLazyBoolCalculate:
-            // We should never be deallocating memory without allocating memory
-            // first so we should never get eLazyBoolCalculate
-            error.SetErrorString ("tried to deallocate memory without ever allocating memory");
-            break;
-
-        case eLazyBoolYes:
-            if (!m_gdb_comm.DeallocateMemory (addr))
-                error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
-            break;
-
-        case eLazyBoolNo:
-            // Call munmap() to deallocate memory in the inferior..
-            {
-                MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
-                if (pos != m_addr_to_mmap_size.end() &&
-                    InferiorCallMunmap(this, addr, pos->second))
-                    m_addr_to_mmap_size.erase (pos);
-                else
-                    error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
-            }
-            break;
-    }
-
-    return error;
-}
-
-
 //------------------------------------------------------------------
 // Process STDIO
 //------------------------------------------------------------------
-size_t
-ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error)
-{
-    if (m_stdio_communication.IsConnected())
-    {
-        ConnectionStatus status;
-        m_stdio_communication.Write(src, src_len, status, NULL);
-    }
-    else if (m_stdin_forward)
-    {
-        m_gdb_comm.SendStdinNotification(src, src_len);
-    }
-    return 0;
+size_t ProcessGDBRemote::PutSTDIN(const char *src, size_t src_len,
+                                  Error &error) {
+  if (m_stdio_communication.IsConnected()) {
+    ConnectionStatus status;
+    m_stdio_communication.Write(src, src_len, status, NULL);
+  } else if (m_stdin_forward) {
+    m_gdb_comm.SendStdinNotification(src, src_len);
+  }
+  return 0;
 }
 
-Error
-ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
-{
-    Error error;
-    assert(bp_site != NULL);
+Error ProcessGDBRemote::EnableBreakpointSite(BreakpointSite *bp_site) {
+  Error error;
+  assert(bp_site != NULL);
 
-    // Get logging info
-    Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
-    user_id_t site_id = bp_site->GetID();
+  // Get logging info
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+  user_id_t site_id = bp_site->GetID();
 
-    // Get the breakpoint address
-    const addr_t addr = bp_site->GetLoadAddress();
+  // Get the breakpoint address
+  const addr_t addr = bp_site->GetLoadAddress();
 
-    // Log that a breakpoint was requested
+  // Log that a breakpoint was requested
+  if (log)
+    log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+                ") address = 0x%" PRIx64,
+                site_id, (uint64_t)addr);
+
+  // Breakpoint already exists and is enabled
+  if (bp_site->IsEnabled()) {
     if (log)
-        log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
+      log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64
+                  ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)",
+                  site_id, (uint64_t)addr);
+    return error;
+  }
 
-    // Breakpoint already exists and is enabled
-    if (bp_site->IsEnabled())
-    {
-        if (log)
-            log->Printf("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
-        return error;
+  // Get the software breakpoint trap opcode size
+  const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
+
+  // SupportsGDBStoppointPacket() simply checks a boolean, indicating if this
+  // breakpoint type
+  // is supported by the remote stub. These are set to true by default, and
+  // later set to false
+  // only after we receive an unimplemented response when sending a breakpoint
+  // packet. This means
+  // initially that unless we were specifically instructed to use a hardware
+  // breakpoint, LLDB will
+  // attempt to set a software breakpoint. HardwareRequired() also queries a
+  // boolean variable which
+  // indicates if the user specifically asked for hardware breakpoints.  If true
+  // then we will
+  // skip over software breakpoints.
+  if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) &&
+      (!bp_site->HardwareRequired())) {
+    // Try to send off a software breakpoint packet ($Z0)
+    uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
+        eBreakpointSoftware, true, addr, bp_op_size);
+    if (error_no == 0) {
+      // The breakpoint was placed successfully
+      bp_site->SetEnabled(true);
+      bp_site->SetType(BreakpointSite::eExternal);
+      return error;
     }
 
-    // Get the software breakpoint trap opcode size
+    // SendGDBStoppointTypePacket() will return an error if it was unable to set
+    // this
+    // breakpoint. We need to differentiate between a error specific to placing
+    // this breakpoint
+    // or if we have learned that this breakpoint type is unsupported. To do
+    // this, we
+    // must test the support boolean for this breakpoint type to see if it now
+    // indicates that
+    // this breakpoint type is unsupported.  If they are still supported then we
+    // should return
+    // with the error code.  If they are now unsupported, then we would like to
+    // fall through
+    // and try another form of breakpoint.
+    if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) {
+      if (error_no != UINT8_MAX)
+        error.SetErrorStringWithFormat(
+            "error: %d sending the breakpoint request", errno);
+      else
+        error.SetErrorString("error sending the breakpoint request");
+      return error;
+    }
+
+    // We reach here when software breakpoints have been found to be
+    // unsupported. For future
+    // calls to set a breakpoint, we will not attempt to set a breakpoint with a
+    // type that is
+    // known not to be supported.
+    if (log)
+      log->Printf("Software breakpoints are unsupported");
+
+    // So we will fall through and try a hardware breakpoint
+  }
+
+  // The process of setting a hardware breakpoint is much the same as above.  We
+  // check the
+  // supported boolean for this breakpoint type, and if it is thought to be
+  // supported then we
+  // will try to set this breakpoint with a hardware breakpoint.
+  if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
+    // Try to send off a hardware breakpoint packet ($Z1)
+    uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(
+        eBreakpointHardware, true, addr, bp_op_size);
+    if (error_no == 0) {
+      // The breakpoint was placed successfully
+      bp_site->SetEnabled(true);
+      bp_site->SetType(BreakpointSite::eHardware);
+      return error;
+    }
+
+    // Check if the error was something other then an unsupported breakpoint
+    // type
+    if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) {
+      // Unable to set this hardware breakpoint
+      if (error_no != UINT8_MAX)
+        error.SetErrorStringWithFormat(
+            "error: %d sending the hardware breakpoint request "
+            "(hardware breakpoint resources might be exhausted or unavailable)",
+            error_no);
+      else
+        error.SetErrorString("error sending the hardware breakpoint request "
+                             "(hardware breakpoint resources "
+                             "might be exhausted or unavailable)");
+      return error;
+    }
+
+    // We will reach here when the stub gives an unsupported response to a
+    // hardware breakpoint
+    if (log)
+      log->Printf("Hardware breakpoints are unsupported");
+
+    // Finally we will falling through to a #trap style breakpoint
+  }
+
+  // Don't fall through when hardware breakpoints were specifically requested
+  if (bp_site->HardwareRequired()) {
+    error.SetErrorString("hardware breakpoints are not supported");
+    return error;
+  }
+
+  // As a last resort we want to place a manual breakpoint. An instruction
+  // is placed into the process memory using memory write packets.
+  return EnableSoftwareBreakpoint(bp_site);
+}
+
+Error ProcessGDBRemote::DisableBreakpointSite(BreakpointSite *bp_site) {
+  Error error;
+  assert(bp_site != NULL);
+  addr_t addr = bp_site->GetLoadAddress();
+  user_id_t site_id = bp_site->GetID();
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+  if (log)
+    log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+                ") addr = 0x%8.8" PRIx64,
+                site_id, (uint64_t)addr);
+
+  if (bp_site->IsEnabled()) {
     const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode(bp_site);
 
-    // SupportsGDBStoppointPacket() simply checks a boolean, indicating if this breakpoint type
-    // is supported by the remote stub. These are set to true by default, and later set to false
-    // only after we receive an unimplemented response when sending a breakpoint packet. This means
-    // initially that unless we were specifically instructed to use a hardware breakpoint, LLDB will
-    // attempt to set a software breakpoint. HardwareRequired() also queries a boolean variable which
-    // indicates if the user specifically asked for hardware breakpoints.  If true then we will
-    // skip over software breakpoints.
-    if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware) && (!bp_site->HardwareRequired()))
-    {
-        // Try to send off a software breakpoint packet ($Z0)
-        uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size);
-        if (error_no == 0)
-        {
-            // The breakpoint was placed successfully
-            bp_site->SetEnabled(true);
-            bp_site->SetType(BreakpointSite::eExternal);
-            return error;
-        }
+    BreakpointSite::Type bp_type = bp_site->GetType();
+    switch (bp_type) {
+    case BreakpointSite::eSoftware:
+      error = DisableSoftwareBreakpoint(bp_site);
+      break;
 
-        // SendGDBStoppointTypePacket() will return an error if it was unable to set this
-        // breakpoint. We need to differentiate between a error specific to placing this breakpoint
-        // or if we have learned that this breakpoint type is unsupported. To do this, we
-        // must test the support boolean for this breakpoint type to see if it now indicates that
-        // this breakpoint type is unsupported.  If they are still supported then we should return
-        // with the error code.  If they are now unsupported, then we would like to fall through
-        // and try another form of breakpoint.
-        if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware))
-        {
-            if (error_no != UINT8_MAX)
-                error.SetErrorStringWithFormat("error: %d sending the breakpoint request", errno);
-            else
-                error.SetErrorString("error sending the breakpoint request");
-            return error;
-        }
-
-        // We reach here when software breakpoints have been found to be unsupported. For future
-        // calls to set a breakpoint, we will not attempt to set a breakpoint with a type that is
-        // known not to be supported.
-        if (log)
-            log->Printf("Software breakpoints are unsupported");
-
-        // So we will fall through and try a hardware breakpoint
-    }
-
-    // The process of setting a hardware breakpoint is much the same as above.  We check the
-    // supported boolean for this breakpoint type, and if it is thought to be supported then we
-    // will try to set this breakpoint with a hardware breakpoint.
-    if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
-    {
-        // Try to send off a hardware breakpoint packet ($Z1)
-        uint8_t error_no = m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size);
-        if (error_no == 0)
-        {
-            // The breakpoint was placed successfully
-            bp_site->SetEnabled(true);
-            bp_site->SetType(BreakpointSite::eHardware);
-            return error;
-        }
-
-        // Check if the error was something other then an unsupported breakpoint type
-        if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware))
-        {
-            // Unable to set this hardware breakpoint
-            if (error_no != UINT8_MAX)
-                error.SetErrorStringWithFormat("error: %d sending the hardware breakpoint request "
-                                               "(hardware breakpoint resources might be exhausted or unavailable)",
-                                               error_no);
-            else
-                error.SetErrorString("error sending the hardware breakpoint request (hardware breakpoint resources "
-                                     "might be exhausted or unavailable)");
-            return error;
-        }
-
-        // We will reach here when the stub gives an unsupported response to a hardware breakpoint
-        if (log)
-            log->Printf("Hardware breakpoints are unsupported");
-
-        // Finally we will falling through to a #trap style breakpoint
-    }
-
-    // Don't fall through when hardware breakpoints were specifically requested
-    if (bp_site->HardwareRequired())
-    {
-        error.SetErrorString("hardware breakpoints are not supported");
-        return error;
-    }
-
-    // As a last resort we want to place a manual breakpoint. An instruction
-    // is placed into the process memory using memory write packets.
-    return EnableSoftwareBreakpoint(bp_site);
-}
-
-Error
-ProcessGDBRemote::DisableBreakpointSite (BreakpointSite *bp_site)
-{
-    Error error;
-    assert (bp_site != NULL);
-    addr_t addr = bp_site->GetLoadAddress();
-    user_id_t site_id = bp_site->GetID();
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
-    if (log)
-        log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
-
-    if (bp_site->IsEnabled())
-    {
-        const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site);
-
-        BreakpointSite::Type bp_type = bp_site->GetType();
-        switch (bp_type)
-        {
-        case BreakpointSite::eSoftware:
-            error = DisableSoftwareBreakpoint (bp_site);
-            break;
-
-        case BreakpointSite::eHardware:
-            if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false, addr, bp_op_size))
-                error.SetErrorToGenericError();
-            break;
-
-        case BreakpointSite::eExternal:
-            {
-                GDBStoppointType stoppoint_type;
-                if (bp_site->IsHardware())
-                    stoppoint_type = eBreakpointHardware;
-                else
-                    stoppoint_type = eBreakpointSoftware;
-
-                if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr, bp_op_size))
-                error.SetErrorToGenericError();
-            }
-            break;
-        }
-        if (error.Success())
-            bp_site->SetEnabled(false);
-    }
-    else
-    {
-        if (log)
-            log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
-        return error;
-    }
-
-    if (error.Success())
+    case BreakpointSite::eHardware:
+      if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, false,
+                                                addr, bp_op_size))
         error.SetErrorToGenericError();
+      break;
+
+    case BreakpointSite::eExternal: {
+      GDBStoppointType stoppoint_type;
+      if (bp_site->IsHardware())
+        stoppoint_type = eBreakpointHardware;
+      else
+        stoppoint_type = eBreakpointSoftware;
+
+      if (m_gdb_comm.SendGDBStoppointTypePacket(stoppoint_type, false, addr,
+                                                bp_op_size))
+        error.SetErrorToGenericError();
+    } break;
+    }
+    if (error.Success())
+      bp_site->SetEnabled(false);
+  } else {
+    if (log)
+      log->Printf("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64
+                  ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+                  site_id, (uint64_t)addr);
     return error;
+  }
+
+  if (error.Success())
+    error.SetErrorToGenericError();
+  return error;
 }
 
 // Pre-requisite: wp != NULL.
-static GDBStoppointType
-GetGDBStoppointType (Watchpoint *wp)
-{
-    assert(wp);
-    bool watch_read = wp->WatchpointRead();
-    bool watch_write = wp->WatchpointWrite();
+static GDBStoppointType GetGDBStoppointType(Watchpoint *wp) {
+  assert(wp);
+  bool watch_read = wp->WatchpointRead();
+  bool watch_write = wp->WatchpointWrite();
 
-    // watch_read and watch_write cannot both be false.
-    assert(watch_read || watch_write);
-    if (watch_read && watch_write)
-        return eWatchpointReadWrite;
-    else if (watch_read)
-        return eWatchpointRead;
-    else // Must be watch_write, then.
-        return eWatchpointWrite;
+  // watch_read and watch_write cannot both be false.
+  assert(watch_read || watch_write);
+  if (watch_read && watch_write)
+    return eWatchpointReadWrite;
+  else if (watch_read)
+    return eWatchpointRead;
+  else // Must be watch_write, then.
+    return eWatchpointWrite;
 }
 
-Error
-ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp, bool notify)
-{
-    Error error;
-    if (wp)
-    {
-        user_id_t watchID = wp->GetID();
-        addr_t addr = wp->GetLoadAddress();
-        Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
-        if (log)
-            log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", watchID);
-        if (wp->IsEnabled())
-        {
-            if (log)
-                log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", watchID, (uint64_t)addr);
-            return error;
-        }
-
-        GDBStoppointType type = GetGDBStoppointType(wp);
-        // Pass down an appropriate z/Z packet...
-        if (m_gdb_comm.SupportsGDBStoppointPacket (type))
-        {
-            if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0)
-            {
-                wp->SetEnabled(true, notify);
-                return error;
-            }
-            else
-                error.SetErrorString("sending gdb watchpoint packet failed");
-        }
-        else
-            error.SetErrorString("watchpoints not supported");
-    }
-    else
-    {
-        error.SetErrorString("Watchpoint argument was NULL.");
-    }
-    if (error.Success())
-        error.SetErrorToGenericError();
-    return error;
-}
-
-Error
-ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp, bool notify)
-{
-    Error error;
-    if (wp)
-    {
-        user_id_t watchID = wp->GetID();
-
-        Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
-
-        addr_t addr = wp->GetLoadAddress();
-
-        if (log)
-            log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64, watchID, (uint64_t)addr);
-
-        if (!wp->IsEnabled())
-        {
-            if (log)
-                log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
-            // See also 'class WatchpointSentry' within StopInfo.cpp.
-            // This disabling attempt might come from the user-supplied actions, we'll route it in order for
-            // the watchpoint object to intelligently process this action.
-            wp->SetEnabled(false, notify);
-            return error;
-        }
-
-        if (wp->IsHardware())
-        {
-            GDBStoppointType type = GetGDBStoppointType(wp);
-            // Pass down an appropriate z/Z packet...
-            if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0)
-            {
-                wp->SetEnabled(false, notify);
-                return error;
-            }
-            else
-                error.SetErrorString("sending gdb watchpoint packet failed");
-        }
-        // TODO: clear software watchpoints if we implement them
-    }
-    else
-    {
-        error.SetErrorString("Watchpoint argument was NULL.");
-    }
-    if (error.Success())
-        error.SetErrorToGenericError();
-    return error;
-}
-
-void
-ProcessGDBRemote::Clear()
-{
-    m_flags = 0;
-    m_thread_list_real.Clear();
-    m_thread_list.Clear();
-}
-
-Error
-ProcessGDBRemote::DoSignal (int signo)
-{
-    Error error;
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+Error ProcessGDBRemote::EnableWatchpoint(Watchpoint *wp, bool notify) {
+  Error error;
+  if (wp) {
+    user_id_t watchID = wp->GetID();
+    addr_t addr = wp->GetLoadAddress();
+    Log *log(
+        ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
     if (log)
-        log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
-
-    if (!m_gdb_comm.SendAsyncSignal (signo))
-        error.SetErrorStringWithFormat("failed to send signal %i", signo);
-    return error;
-}
-
-Error
-ProcessGDBRemote::EstablishConnectionIfNeeded (const ProcessInfo &process_info)
-{
-    // Make sure we aren't already connected?
-    if (m_gdb_comm.IsConnected())
-        return Error();
-
-    PlatformSP platform_sp (GetTarget ().GetPlatform ());
-    if (platform_sp && !platform_sp->IsHost ())
-        return Error("Lost debug server connection");
-
-    auto error = LaunchAndConnectToDebugserver (process_info);
-    if (error.Fail())
-    {
-        const char *error_string = error.AsCString();
-        if (error_string == nullptr)
-            error_string = "unable to launch " DEBUGSERVER_BASENAME;
+      log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")",
+                  watchID);
+    if (wp->IsEnabled()) {
+      if (log)
+        log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64
+                    ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
+                    watchID, (uint64_t)addr);
+      return error;
     }
-    return error;
+
+    GDBStoppointType type = GetGDBStoppointType(wp);
+    // Pass down an appropriate z/Z packet...
+    if (m_gdb_comm.SupportsGDBStoppointPacket(type)) {
+      if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr,
+                                                wp->GetByteSize()) == 0) {
+        wp->SetEnabled(true, notify);
+        return error;
+      } else
+        error.SetErrorString("sending gdb watchpoint packet failed");
+    } else
+      error.SetErrorString("watchpoints not supported");
+  } else {
+    error.SetErrorString("Watchpoint argument was NULL.");
+  }
+  if (error.Success())
+    error.SetErrorToGenericError();
+  return error;
 }
-#if defined (__APPLE__)
+
+Error ProcessGDBRemote::DisableWatchpoint(Watchpoint *wp, bool notify) {
+  Error error;
+  if (wp) {
+    user_id_t watchID = wp->GetID();
+
+    Log *log(
+        ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+
+    addr_t addr = wp->GetLoadAddress();
+
+    if (log)
+      log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+                  ") addr = 0x%8.8" PRIx64,
+                  watchID, (uint64_t)addr);
+
+    if (!wp->IsEnabled()) {
+      if (log)
+        log->Printf("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64
+                    ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)",
+                    watchID, (uint64_t)addr);
+      // See also 'class WatchpointSentry' within StopInfo.cpp.
+      // This disabling attempt might come from the user-supplied actions, we'll
+      // route it in order for
+      // the watchpoint object to intelligently process this action.
+      wp->SetEnabled(false, notify);
+      return error;
+    }
+
+    if (wp->IsHardware()) {
+      GDBStoppointType type = GetGDBStoppointType(wp);
+      // Pass down an appropriate z/Z packet...
+      if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr,
+                                                wp->GetByteSize()) == 0) {
+        wp->SetEnabled(false, notify);
+        return error;
+      } else
+        error.SetErrorString("sending gdb watchpoint packet failed");
+    }
+    // TODO: clear software watchpoints if we implement them
+  } else {
+    error.SetErrorString("Watchpoint argument was NULL.");
+  }
+  if (error.Success())
+    error.SetErrorToGenericError();
+  return error;
+}
+
+void ProcessGDBRemote::Clear() {
+  m_flags = 0;
+  m_thread_list_real.Clear();
+  m_thread_list.Clear();
+}
+
+Error ProcessGDBRemote::DoSignal(int signo) {
+  Error error;
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("ProcessGDBRemote::DoSignal (signal = %d)", signo);
+
+  if (!m_gdb_comm.SendAsyncSignal(signo))
+    error.SetErrorStringWithFormat("failed to send signal %i", signo);
+  return error;
+}
+
+Error ProcessGDBRemote::EstablishConnectionIfNeeded(
+    const ProcessInfo &process_info) {
+  // Make sure we aren't already connected?
+  if (m_gdb_comm.IsConnected())
+    return Error();
+
+  PlatformSP platform_sp(GetTarget().GetPlatform());
+  if (platform_sp && !platform_sp->IsHost())
+    return Error("Lost debug server connection");
+
+  auto error = LaunchAndConnectToDebugserver(process_info);
+  if (error.Fail()) {
+    const char *error_string = error.AsCString();
+    if (error_string == nullptr)
+      error_string = "unable to launch " DEBUGSERVER_BASENAME;
+  }
+  return error;
+}
+#if defined(__APPLE__)
 #define USE_SOCKETPAIR_FOR_LOCAL_CONNECTION 1
 #endif
 
 #ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
-static bool SetCloexecFlag(int fd)
-{
-#if defined(FD_CLOEXEC) 
-    int flags = ::fcntl(fd, F_GETFD);
-    if (flags == -1)
-        return false;
-    return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
-#else
+static bool SetCloexecFlag(int fd) {
+#if defined(FD_CLOEXEC)
+  int flags = ::fcntl(fd, F_GETFD);
+  if (flags == -1)
     return false;
+  return (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == 0);
+#else
+  return false;
 #endif
 }
 #endif
 
-Error
-ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
-{
-    using namespace std::placeholders; // For _1, _2, etc.
+Error ProcessGDBRemote::LaunchAndConnectToDebugserver(
+    const ProcessInfo &process_info) {
+  using namespace std::placeholders; // For _1, _2, etc.
 
-    Error error;
-    if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
+  Error error;
+  if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) {
+    // If we locate debugserver, keep that located version around
+    static FileSpec g_debugserver_file_spec;
+
+    ProcessLaunchInfo debugserver_launch_info;
+    // Make debugserver run in its own session so signals generated by
+    // special terminal key sequences (^C) don't affect debugserver.
+    debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
+
+    const std::weak_ptr<ProcessGDBRemote> this_wp =
+        std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
+    debugserver_launch_info.SetMonitorProcessCallback(
+        std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4), false);
+    debugserver_launch_info.SetUserID(process_info.GetUserID());
+
+    int communication_fd = -1;
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+    // Auto close the sockets we might open up unless everything goes OK. This
+    // helps us not leak file descriptors when things go wrong.
+    lldb_utility::CleanUp<int, int> our_socket(-1, -1, close);
+    lldb_utility::CleanUp<int, int> gdb_socket(-1, -1, close);
+
+    // Use a socketpair on Apple for now until other platforms can verify it
+    // works and is fast enough
     {
-        // If we locate debugserver, keep that located version around
-        static FileSpec g_debugserver_file_spec;
+      int sockets[2]; /* the pair of socket descriptors */
+      if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1) {
+        error.SetErrorToErrno();
+        return error;
+      }
 
-        ProcessLaunchInfo debugserver_launch_info;
-        // Make debugserver run in its own session so signals generated by
-        // special terminal key sequences (^C) don't affect debugserver.
-        debugserver_launch_info.SetLaunchInSeparateProcessGroup(true);
-
-        const std::weak_ptr<ProcessGDBRemote> this_wp = std::static_pointer_cast<ProcessGDBRemote>(shared_from_this());
-        debugserver_launch_info.SetMonitorProcessCallback(std::bind(MonitorDebugserverProcess, this_wp, _1, _2, _3, _4),
-                                                          false);
-        debugserver_launch_info.SetUserID(process_info.GetUserID());
-
-
-        int communication_fd = -1;
-#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
-        // Auto close the sockets we might open up unless everything goes OK. This
-        // helps us not leak file descriptors when things go wrong.
-        lldb_utility::CleanUp <int, int> our_socket(-1, -1, close);
-        lldb_utility::CleanUp <int, int> gdb_socket(-1, -1, close);
-
-        // Use a socketpair on Apple for now until other platforms can verify it
-        // works and is fast enough
-        {
-            int sockets[2]; /* the pair of socket descriptors */
-            if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == -1)
-            {
-                error.SetErrorToErrno();
-                return error;
-            }
-
-            our_socket.set(sockets[0]);
-            gdb_socket.set(sockets[1]);
-        }
-
-        // Don't let any child processes inherit our communication socket
-        SetCloexecFlag(our_socket.get());
-        communication_fd = gdb_socket.get();
-#endif
-
-        error = m_gdb_comm.StartDebugserverProcess(nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info, nullptr, nullptr, communication_fd);
-
-        if (error.Success ())
-            m_debugserver_pid = debugserver_launch_info.GetProcessID();
-        else
-            m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
-
-        if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
-        {
-#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
-            // Our process spawned correctly, we can now set our connection to use our
-            // end of the socket pair
-            m_gdb_comm.SetConnection(new ConnectionFileDescriptor(our_socket.release(), true));
-#endif
-            StartAsyncThread ();
-        }
-
-        if (error.Fail())
-        {
-            Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
-            if (log)
-                log->Printf("failed to start debugserver process: %s", error.AsCString());
-            return error;
-        }
-
-        if (m_gdb_comm.IsConnected())
-        {
-            // Finish the connection process by doing the handshake without connecting (send NULL URL)
-            ConnectToDebugserver(NULL);
-        }
-        else
-        {
-            error.SetErrorString("connection failed");
-        }
-
+      our_socket.set(sockets[0]);
+      gdb_socket.set(sockets[1]);
     }
-    return error;
+
+    // Don't let any child processes inherit our communication socket
+    SetCloexecFlag(our_socket.get());
+    communication_fd = gdb_socket.get();
+#endif
+
+    error = m_gdb_comm.StartDebugserverProcess(
+        nullptr, GetTarget().GetPlatform().get(), debugserver_launch_info,
+        nullptr, nullptr, communication_fd);
+
+    if (error.Success())
+      m_debugserver_pid = debugserver_launch_info.GetProcessID();
+    else
+      m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+
+    if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+#ifdef USE_SOCKETPAIR_FOR_LOCAL_CONNECTION
+      // Our process spawned correctly, we can now set our connection to use our
+      // end of the socket pair
+      m_gdb_comm.SetConnection(
+          new ConnectionFileDescriptor(our_socket.release(), true));
+#endif
+      StartAsyncThread();
+    }
+
+    if (error.Fail()) {
+      Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+      if (log)
+        log->Printf("failed to start debugserver process: %s",
+                    error.AsCString());
+      return error;
+    }
+
+    if (m_gdb_comm.IsConnected()) {
+      // Finish the connection process by doing the handshake without connecting
+      // (send NULL URL)
+      ConnectToDebugserver(NULL);
+    } else {
+      error.SetErrorString("connection failed");
+    }
+  }
+  return error;
 }
 
-bool
-ProcessGDBRemote::MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
-                                            bool exited,    // True if the process did exit
-                                            int signo,      // Zero for no signal
-                                            int exit_status // Exit value of process if signal is zero
-                                            )
-{
-    // "debugserver_pid" argument passed in is the process ID for
-    // debugserver that we are tracking...
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-    const bool handled = true;
+bool ProcessGDBRemote::MonitorDebugserverProcess(
+    std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t debugserver_pid,
+    bool exited,    // True if the process did exit
+    int signo,      // Zero for no signal
+    int exit_status // Exit value of process if signal is zero
+    ) {
+  // "debugserver_pid" argument passed in is the process ID for
+  // debugserver that we are tracking...
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  const bool handled = true;
 
-    if (log)
-        log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", __FUNCTION__,
-                    debugserver_pid, signo, signo, exit_status);
+  if (log)
+    log->Printf("ProcessGDBRemote::%s(process_wp, pid=%" PRIu64
+                ", signo=%i (0x%x), exit_status=%i)",
+                __FUNCTION__, debugserver_pid, signo, signo, exit_status);
 
-    std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
-    if (log)
-        log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__, static_cast<void *>(process_sp.get()));
-    if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
-        return handled;
-
-    // Sleep for a half a second to make sure our inferior process has
-    // time to set its exit status before we set it incorrectly when
-    // both the debugserver and the inferior process shut down.
-    usleep(500000);
-    // If our process hasn't yet exited, debugserver might have died.
-    // If the process did exit, then we are reaping it.
-    const StateType state = process_sp->GetState();
-
-    if (state != eStateInvalid && state != eStateUnloaded && state != eStateExited && state != eStateDetached)
-    {
-        char error_str[1024];
-        if (signo)
-        {
-            const char *signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo);
-            if (signal_cstr)
-                ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
-            else
-                ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with signal %i", signo);
-        }
-        else
-        {
-            ::snprintf(error_str, sizeof(error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
-                       exit_status);
-        }
-
-        process_sp->SetExitStatus(-1, error_str);
-    }
-    // Debugserver has exited we need to let our ProcessGDBRemote
-    // know that it no longer has a debugserver instance
-    process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+  std::shared_ptr<ProcessGDBRemote> process_sp = process_wp.lock();
+  if (log)
+    log->Printf("ProcessGDBRemote::%s(process = %p)", __FUNCTION__,
+                static_cast<void *>(process_sp.get()));
+  if (!process_sp || process_sp->m_debugserver_pid != debugserver_pid)
     return handled;
-}
 
-void
-ProcessGDBRemote::KillDebugserverProcess ()
-{
-    m_gdb_comm.Disconnect();
-    if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
-    {
-        Host::Kill (m_debugserver_pid, SIGINT);
-        m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+  // Sleep for a half a second to make sure our inferior process has
+  // time to set its exit status before we set it incorrectly when
+  // both the debugserver and the inferior process shut down.
+  usleep(500000);
+  // If our process hasn't yet exited, debugserver might have died.
+  // If the process did exit, then we are reaping it.
+  const StateType state = process_sp->GetState();
+
+  if (state != eStateInvalid && state != eStateUnloaded &&
+      state != eStateExited && state != eStateDetached) {
+    char error_str[1024];
+    if (signo) {
+      const char *signal_cstr =
+          process_sp->GetUnixSignals()->GetSignalAsCString(signo);
+      if (signal_cstr)
+        ::snprintf(error_str, sizeof(error_str),
+                   DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
+      else
+        ::snprintf(error_str, sizeof(error_str),
+                   DEBUGSERVER_BASENAME " died with signal %i", signo);
+    } else {
+      ::snprintf(error_str, sizeof(error_str),
+                 DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x",
+                 exit_status);
     }
+
+    process_sp->SetExitStatus(-1, error_str);
+  }
+  // Debugserver has exited we need to let our ProcessGDBRemote
+  // know that it no longer has a debugserver instance
+  process_sp->m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+  return handled;
 }
 
-void
-ProcessGDBRemote::Initialize()
-{
-    static std::once_flag g_once_flag;
-
-    std::call_once(g_once_flag, []()
-    {
-        PluginManager::RegisterPlugin (GetPluginNameStatic(),
-                                       GetPluginDescriptionStatic(),
-                                       CreateInstance,
-                                       DebuggerInitialize);
-    });
+void ProcessGDBRemote::KillDebugserverProcess() {
+  m_gdb_comm.Disconnect();
+  if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) {
+    Host::Kill(m_debugserver_pid, SIGINT);
+    m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+  }
 }
 
-void
-ProcessGDBRemote::DebuggerInitialize (Debugger &debugger)
-{
-    if (!PluginManager::GetSettingForProcessPlugin(debugger, PluginProperties::GetSettingName()))
-    {
-        const bool is_global_setting = true;
-        PluginManager::CreateSettingForProcessPlugin (debugger,
-                                                      GetGlobalPluginProperties()->GetValueProperties(),
-                                                      ConstString ("Properties for the gdb-remote process plug-in."),
-                                                      is_global_setting);
-    }
+void ProcessGDBRemote::Initialize() {
+  static std::once_flag g_once_flag;
+
+  std::call_once(g_once_flag, []() {
+    PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                  GetPluginDescriptionStatic(), CreateInstance,
+                                  DebuggerInitialize);
+  });
 }
 
-bool
-ProcessGDBRemote::StartAsyncThread ()
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) {
+  if (!PluginManager::GetSettingForProcessPlugin(
+          debugger, PluginProperties::GetSettingName())) {
+    const bool is_global_setting = true;
+    PluginManager::CreateSettingForProcessPlugin(
+        debugger, GetGlobalPluginProperties()->GetValueProperties(),
+        ConstString("Properties for the gdb-remote process plug-in."),
+        is_global_setting);
+  }
+}
 
+bool ProcessGDBRemote::StartAsyncThread() {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+  if (log)
+    log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
+
+  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+  if (!m_async_thread.IsJoinable()) {
+    // Create a thread that watches our internal state and controls which
+    // events make it to clients (into the DCProcess event queue).
+
+    m_async_thread =
+        ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>",
+                                     ProcessGDBRemote::AsyncThread, this, NULL);
+  } else if (log)
+    log->Printf("ProcessGDBRemote::%s () - Called when Async thread was "
+                "already running.",
+                __FUNCTION__);
+
+  return m_async_thread.IsJoinable();
+}
+
+void ProcessGDBRemote::StopAsyncThread() {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+
+  if (log)
+    log->Printf("ProcessGDBRemote::%s ()", __FUNCTION__);
+
+  std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
+  if (m_async_thread.IsJoinable()) {
+    m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
+
+    //  This will shut down the async thread.
+    m_gdb_comm.Disconnect(); // Disconnect from the debug server.
+
+    // Stop the stdio thread
+    m_async_thread.Join(nullptr);
+    m_async_thread.Reset();
+  } else if (log)
+    log->Printf(
+        "ProcessGDBRemote::%s () - Called when Async thread was not running.",
+        __FUNCTION__);
+}
+
+bool ProcessGDBRemote::HandleNotifyPacket(StringExtractorGDBRemote &packet) {
+  // get the packet at a string
+  const std::string &pkt = packet.GetStringRef();
+  // skip %stop:
+  StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
+
+  // pass as a thread stop info packet
+  SetLastStopPacket(stop_info);
+
+  // check for more stop reasons
+  HandleStopReplySequence();
+
+  // if the process is stopped then we need to fake a resume
+  // so that we can stop properly with the new break. This
+  // is possible due to SetPrivateState() broadcasting the
+  // state change as a side effect.
+  if (GetPrivateState() == lldb::StateType::eStateStopped) {
+    SetPrivateState(lldb::StateType::eStateRunning);
+  }
+
+  // since we have some stopped packets we can halt the process
+  SetPrivateState(lldb::StateType::eStateStopped);
+
+  return true;
+}
+
+thread_result_t ProcessGDBRemote::AsyncThread(void *arg) {
+  ProcessGDBRemote *process = (ProcessGDBRemote *)arg;
+
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  if (log)
+    log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                ") thread starting...",
+                __FUNCTION__, arg, process->GetID());
+
+  EventSP event_sp;
+  bool done = false;
+  while (!done) {
     if (log)
-        log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
-
-    std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
-    if (!m_async_thread.IsJoinable())
-    {
-        // Create a thread that watches our internal state and controls which
-        // events make it to clients (into the DCProcess event queue).
-
-        m_async_thread = ThreadLauncher::LaunchThread("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL);
-    }
-    else if (log)
-        log->Printf("ProcessGDBRemote::%s () - Called when Async thread was already running.", __FUNCTION__);
-
-    return m_async_thread.IsJoinable();
-}
-
-void
-ProcessGDBRemote::StopAsyncThread ()
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
-
-    std::lock_guard<std::recursive_mutex> guard(m_async_thread_state_mutex);
-    if (m_async_thread.IsJoinable())
-    {
-        m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit);
-
-        //  This will shut down the async thread.
-        m_gdb_comm.Disconnect();    // Disconnect from the debug server.
-
-        // Stop the stdio thread
-        m_async_thread.Join(nullptr);
-        m_async_thread.Reset();
-    }
-    else if (log)
-        log->Printf("ProcessGDBRemote::%s () - Called when Async thread was not running.", __FUNCTION__);
-}
-
-bool
-ProcessGDBRemote::HandleNotifyPacket (StringExtractorGDBRemote &packet)
-{
-    // get the packet at a string
-    const std::string &pkt = packet.GetStringRef();
-    // skip %stop:
-    StringExtractorGDBRemote stop_info(pkt.c_str() + 5);
-
-    // pass as a thread stop info packet
-    SetLastStopPacket(stop_info);
-
-    // check for more stop reasons
-    HandleStopReplySequence();
-
-    // if the process is stopped then we need to fake a resume
-    // so that we can stop properly with the new break. This
-    // is possible due to SetPrivateState() broadcasting the
-    // state change as a side effect.
-    if (GetPrivateState() == lldb::StateType::eStateStopped)
-    {
-        SetPrivateState(lldb::StateType::eStateRunning);
-    }
-
-    // since we have some stopped packets we can halt the process
-    SetPrivateState(lldb::StateType::eStateStopped);
-
-    return true;
-}
-
-thread_result_t
-ProcessGDBRemote::AsyncThread (void *arg)
-{
-    ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
-
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, arg, process->GetID());
-
-    EventSP event_sp;
-    bool done = false;
-    while (!done)
-    {
+      log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                  ") listener.WaitForEvent (NULL, event_sp)...",
+                  __FUNCTION__, arg, process->GetID());
+    if (process->m_async_listener_sp->WaitForEvent(std::chrono::microseconds(0),
+                                                   event_sp)) {
+      const uint32_t event_type = event_sp->GetType();
+      if (event_sp->BroadcasterIs(&process->m_async_broadcaster)) {
         if (log)
-            log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
-        if (process->m_async_listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp))
-        {
-            const uint32_t event_type = event_sp->GetType();
-            if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
-            {
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
+          log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                      ") Got an event of type: %d...",
+                      __FUNCTION__, arg, process->GetID(), event_type);
 
-                switch (event_type)
-                {
-                    case eBroadcastBitAsyncContinue:
-                        {
-                            const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get());
+        switch (event_type) {
+        case eBroadcastBitAsyncContinue: {
+          const EventDataBytes *continue_packet =
+              EventDataBytes::GetEventDataFromEvent(event_sp.get());
 
-                            if (continue_packet)
-                            {
-                                const char *continue_cstr = (const char *)continue_packet->GetBytes ();
-                                const size_t continue_cstr_len = continue_packet->GetByteSize ();
-                                if (log)
-                                    log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
-
-                                if (::strstr (continue_cstr, "vAttach") == NULL)
-                                    process->SetPrivateState(eStateRunning);
-                                StringExtractorGDBRemote response;
-
-                                // If in Non-Stop-Mode
-                                if (process->GetTarget().GetNonStopModeEnabled())
-                                {
-                                    // send the vCont packet
-                                    if (!process->GetGDBRemote().SendvContPacket(
-                                            llvm::StringRef(continue_cstr, continue_cstr_len), response))
-                                    {
-                                        // Something went wrong
-                                        done = true;
-                                        break;
-                                    }
-                                }
-                                // If in All-Stop-Mode
-                                else
-                                {
-                                    StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
-                                        *process, *process->GetUnixSignals(),
-                                        llvm::StringRef(continue_cstr, continue_cstr_len), response);
-
-                                    // We need to immediately clear the thread ID list so we are sure to get a valid list of threads.
-                                    // The thread ID list might be contained within the "response", or the stop reply packet that
-                                    // caused the stop. So clear it now before we give the stop reply packet to the process
-                                    // using the process->SetLastStopPacket()...
-                                    process->ClearThreadIDList ();
-
-                                    switch (stop_state)
-                                    {
-                                    case eStateStopped:
-                                    case eStateCrashed:
-                                    case eStateSuspended:
-                                        process->SetLastStopPacket (response);
-                                        process->SetPrivateState (stop_state);
-                                        break;
-
-                                    case eStateExited:
-                                    {
-                                        process->SetLastStopPacket (response);
-                                        process->ClearThreadIDList();
-                                        response.SetFilePos(1);
-
-                                        int exit_status = response.GetHexU8();
-                                        std::string desc_string;
-                                        if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';')
-                                        {
-                                            llvm::StringRef desc_str;
-                                            llvm::StringRef desc_token;
-                                            while (response.GetNameColonValue(desc_token, desc_str))
-                                            {
-                                                if (desc_token != "description")
-                                                    continue;
-                                                StringExtractor extractor(desc_str);
-                                                extractor.GetHexByteString(desc_string);
-                                            }
-                                        }
-                                        process->SetExitStatus(exit_status, desc_string.c_str());
-                                        done = true;
-                                        break;
-                                    }
-                                    case eStateInvalid:
-                                    {
-                                        // Check to see if we were trying to attach and if we got back
-                                        // the "E87" error code from debugserver -- this indicates that
-                                        // the process is not debuggable.  Return a slightly more helpful
-                                        // error message about why the attach failed.
-                                        if (::strstr (continue_cstr, "vAttach") != NULL
-                                            && response.GetError() == 0x87)
-                                        {
-                                            process->SetExitStatus(-1, "cannot attach to process due to System Integrity Protection");
-                                        }
-                                        // E01 code from vAttach means that the attach failed
-                                        if (::strstr (continue_cstr, "vAttach") != NULL
-                                            && response.GetError() == 0x1)
-                                        {
-                                            process->SetExitStatus(-1, "unable to attach");
-                                        }
-                                        else
-                                        {
-                                            process->SetExitStatus(-1, "lost connection");
-                                        }
-                                            break;
-                                    }
-
-                                    default:
-                                        process->SetPrivateState (stop_state);
-                                        break;
-                                    } // switch(stop_state)
-                                } // else // if in All-stop-mode
-                            } // if (continue_packet)
-                        } // case eBroadcastBitAysncContinue
-                        break;
-
-                    case eBroadcastBitAsyncThreadShouldExit:
-                        if (log)
-                            log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
-                        done = true;
-                        break;
-
-                    default:
-                        if (log)
-                            log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
-                        done = true;
-                        break;
-                }
-            }
-            else if (event_sp->BroadcasterIs (&process->m_gdb_comm))
-            {
-                switch (event_type)
-                {
-                    case Communication::eBroadcastBitReadThreadDidExit:
-                        process->SetExitStatus (-1, "lost connection");
-                        done = true;
-                        break;
-
-                    case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify:
-                    {
-                        lldb_private::Event *event = event_sp.get();
-                        const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event);
-                        StringExtractorGDBRemote notify((const char*)continue_packet->GetBytes());
-                        // Hand this over to the process to handle
-                        process->HandleNotifyPacket(notify);
-                        break;
-                    }
-
-                    default:
-                        if (log)
-                            log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
-                        done = true;
-                        break;
-                }
-            }
-        }
-        else
-        {
+          if (continue_packet) {
+            const char *continue_cstr =
+                (const char *)continue_packet->GetBytes();
+            const size_t continue_cstr_len = continue_packet->GetByteSize();
             if (log)
-                log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
-            done = true;
+              log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                          ") got eBroadcastBitAsyncContinue: %s",
+                          __FUNCTION__, arg, process->GetID(), continue_cstr);
+
+            if (::strstr(continue_cstr, "vAttach") == NULL)
+              process->SetPrivateState(eStateRunning);
+            StringExtractorGDBRemote response;
+
+            // If in Non-Stop-Mode
+            if (process->GetTarget().GetNonStopModeEnabled()) {
+              // send the vCont packet
+              if (!process->GetGDBRemote().SendvContPacket(
+                      llvm::StringRef(continue_cstr, continue_cstr_len),
+                      response)) {
+                // Something went wrong
+                done = true;
+                break;
+              }
+            }
+            // If in All-Stop-Mode
+            else {
+              StateType stop_state =
+                  process->GetGDBRemote().SendContinuePacketAndWaitForResponse(
+                      *process, *process->GetUnixSignals(),
+                      llvm::StringRef(continue_cstr, continue_cstr_len),
+                      response);
+
+              // We need to immediately clear the thread ID list so we are sure
+              // to get a valid list of threads.
+              // The thread ID list might be contained within the "response", or
+              // the stop reply packet that
+              // caused the stop. So clear it now before we give the stop reply
+              // packet to the process
+              // using the process->SetLastStopPacket()...
+              process->ClearThreadIDList();
+
+              switch (stop_state) {
+              case eStateStopped:
+              case eStateCrashed:
+              case eStateSuspended:
+                process->SetLastStopPacket(response);
+                process->SetPrivateState(stop_state);
+                break;
+
+              case eStateExited: {
+                process->SetLastStopPacket(response);
+                process->ClearThreadIDList();
+                response.SetFilePos(1);
+
+                int exit_status = response.GetHexU8();
+                std::string desc_string;
+                if (response.GetBytesLeft() > 0 &&
+                    response.GetChar('-') == ';') {
+                  llvm::StringRef desc_str;
+                  llvm::StringRef desc_token;
+                  while (response.GetNameColonValue(desc_token, desc_str)) {
+                    if (desc_token != "description")
+                      continue;
+                    StringExtractor extractor(desc_str);
+                    extractor.GetHexByteString(desc_string);
+                  }
+                }
+                process->SetExitStatus(exit_status, desc_string.c_str());
+                done = true;
+                break;
+              }
+              case eStateInvalid: {
+                // Check to see if we were trying to attach and if we got back
+                // the "E87" error code from debugserver -- this indicates that
+                // the process is not debuggable.  Return a slightly more
+                // helpful
+                // error message about why the attach failed.
+                if (::strstr(continue_cstr, "vAttach") != NULL &&
+                    response.GetError() == 0x87) {
+                  process->SetExitStatus(-1, "cannot attach to process due to "
+                                             "System Integrity Protection");
+                }
+                // E01 code from vAttach means that the attach failed
+                if (::strstr(continue_cstr, "vAttach") != NULL &&
+                    response.GetError() == 0x1) {
+                  process->SetExitStatus(-1, "unable to attach");
+                } else {
+                  process->SetExitStatus(-1, "lost connection");
+                }
+                break;
+              }
+
+              default:
+                process->SetPrivateState(stop_state);
+                break;
+              } // switch(stop_state)
+            }   // else // if in All-stop-mode
+          }     // if (continue_packet)
+        }       // case eBroadcastBitAysncContinue
+        break;
+
+        case eBroadcastBitAsyncThreadShouldExit:
+          if (log)
+            log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                        ") got eBroadcastBitAsyncThreadShouldExit...",
+                        __FUNCTION__, arg, process->GetID());
+          done = true;
+          break;
+
+        default:
+          if (log)
+            log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                        ") got unknown event 0x%8.8x",
+                        __FUNCTION__, arg, process->GetID(), event_type);
+          done = true;
+          break;
         }
+      } else if (event_sp->BroadcasterIs(&process->m_gdb_comm)) {
+        switch (event_type) {
+        case Communication::eBroadcastBitReadThreadDidExit:
+          process->SetExitStatus(-1, "lost connection");
+          done = true;
+          break;
+
+        case GDBRemoteCommunication::eBroadcastBitGdbReadThreadGotNotify: {
+          lldb_private::Event *event = event_sp.get();
+          const EventDataBytes *continue_packet =
+              EventDataBytes::GetEventDataFromEvent(event);
+          StringExtractorGDBRemote notify(
+              (const char *)continue_packet->GetBytes());
+          // Hand this over to the process to handle
+          process->HandleNotifyPacket(notify);
+          break;
+        }
+
+        default:
+          if (log)
+            log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                        ") got unknown event 0x%8.8x",
+                        __FUNCTION__, arg, process->GetID(), event_type);
+          done = true;
+          break;
+        }
+      }
+    } else {
+      if (log)
+        log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                    ") listener.WaitForEvent (NULL, event_sp) => false",
+                    __FUNCTION__, arg, process->GetID());
+      done = true;
     }
+  }
 
-    if (log)
-        log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID());
+  if (log)
+    log->Printf("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64
+                ") thread exiting...",
+                __FUNCTION__, arg, process->GetID());
 
-    return NULL;
+  return NULL;
 }
 
-//uint32_t
-//ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids)
+// uint32_t
+// ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList
+// &matches, std::vector<lldb::pid_t> &pids)
 //{
-//    // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver
-//    // process and ask it for the list of processes. But if we are local, we can let the Host do it.
+//    // If we are planning to launch the debugserver remotely, then we need to
+//    fire up a debugserver
+//    // process and ask it for the list of processes. But if we are local, we
+//    can let the Host do it.
 //    if (m_local_debugserver)
 //    {
 //        return Host::ListProcessesMatchingName (name, matches, pids);
@@ -4059,270 +3727,239 @@
 //
 //}
 //
-bool
-ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton,
-                             StoppointCallbackContext *context,
-                             lldb::user_id_t break_id,
-                             lldb::user_id_t break_loc_id)
-{
-    // I don't think I have to do anything here, just make sure I notice the new thread when it starts to
-    // run so I can stop it if that's what I want to do.
-    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log)
-        log->Printf("Hit New Thread Notification breakpoint.");
-    return false;
+bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
+    void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
+    lldb::user_id_t break_loc_id) {
+  // I don't think I have to do anything here, just make sure I notice the new
+  // thread when it starts to
+  // run so I can stop it if that's what I want to do.
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+  if (log)
+    log->Printf("Hit New Thread Notification breakpoint.");
+  return false;
 }
 
-
-bool
-ProcessGDBRemote::StartNoticingNewThreads()
-{
-    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (m_thread_create_bp_sp)
-    {
-        if (log && log->GetVerbose())
-            log->Printf("Enabled noticing new thread breakpoint.");
-        m_thread_create_bp_sp->SetEnabled(true);
-    }
-    else
-    {
-        PlatformSP platform_sp (GetTarget().GetPlatform());
-        if (platform_sp)
-        {
-            m_thread_create_bp_sp = platform_sp->SetThreadCreationBreakpoint(GetTarget());
-            if (m_thread_create_bp_sp)
-            {
-                if (log && log->GetVerbose())
-                    log->Printf("Successfully created new thread notification breakpoint %i", m_thread_create_bp_sp->GetID());
-                m_thread_create_bp_sp->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
-            }
-            else
-            {
-                if (log)
-                    log->Printf("Failed to create new thread notification breakpoint.");
-            }
-        }
-    }
-    return m_thread_create_bp_sp.get() != NULL;
-}
-
-bool
-ProcessGDBRemote::StopNoticingNewThreads()
-{
-    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+bool ProcessGDBRemote::StartNoticingNewThreads() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+  if (m_thread_create_bp_sp) {
     if (log && log->GetVerbose())
-        log->Printf ("Disabling new thread notification breakpoint.");
-
-    if (m_thread_create_bp_sp)
-        m_thread_create_bp_sp->SetEnabled(false);
-
-    return true;
-}
-
-DynamicLoader *
-ProcessGDBRemote::GetDynamicLoader ()
-{
-    if (m_dyld_ap.get() == NULL)
-        m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
-    return m_dyld_ap.get();
-}
-
-Error
-ProcessGDBRemote::SendEventData(const char *data)
-{
-    int return_value;
-    bool was_supported;
-
-    Error error;
-
-    return_value = m_gdb_comm.SendLaunchEventDataPacket (data, &was_supported);
-    if (return_value != 0)
-    {
-        if (!was_supported)
-            error.SetErrorString("Sending events is not supported for this process.");
-        else
-            error.SetErrorStringWithFormat("Error sending event data: %d.", return_value);
+      log->Printf("Enabled noticing new thread breakpoint.");
+    m_thread_create_bp_sp->SetEnabled(true);
+  } else {
+    PlatformSP platform_sp(GetTarget().GetPlatform());
+    if (platform_sp) {
+      m_thread_create_bp_sp =
+          platform_sp->SetThreadCreationBreakpoint(GetTarget());
+      if (m_thread_create_bp_sp) {
+        if (log && log->GetVerbose())
+          log->Printf(
+              "Successfully created new thread notification breakpoint %i",
+              m_thread_create_bp_sp->GetID());
+        m_thread_create_bp_sp->SetCallback(
+            ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true);
+      } else {
+        if (log)
+          log->Printf("Failed to create new thread notification breakpoint.");
+      }
     }
-    return error;
+  }
+  return m_thread_create_bp_sp.get() != NULL;
 }
 
-const DataBufferSP
-ProcessGDBRemote::GetAuxvData()
-{
-    DataBufferSP buf;
-    if (m_gdb_comm.GetQXferAuxvReadSupported())
-    {
-        std::string response_string;
-        if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::", response_string) == GDBRemoteCommunication::PacketResult::Success)
-            buf.reset(new DataBufferHeap(response_string.c_str(), response_string.length()));
-    }
-    return buf;
+bool ProcessGDBRemote::StopNoticingNewThreads() {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+  if (log && log->GetVerbose())
+    log->Printf("Disabling new thread notification breakpoint.");
+
+  if (m_thread_create_bp_sp)
+    m_thread_create_bp_sp->SetEnabled(false);
+
+  return true;
+}
+
+DynamicLoader *ProcessGDBRemote::GetDynamicLoader() {
+  if (m_dyld_ap.get() == NULL)
+    m_dyld_ap.reset(DynamicLoader::FindPlugin(this, NULL));
+  return m_dyld_ap.get();
+}
+
+Error ProcessGDBRemote::SendEventData(const char *data) {
+  int return_value;
+  bool was_supported;
+
+  Error error;
+
+  return_value = m_gdb_comm.SendLaunchEventDataPacket(data, &was_supported);
+  if (return_value != 0) {
+    if (!was_supported)
+      error.SetErrorString("Sending events is not supported for this process.");
+    else
+      error.SetErrorStringWithFormat("Error sending event data: %d.",
+                                     return_value);
+  }
+  return error;
+}
+
+const DataBufferSP ProcessGDBRemote::GetAuxvData() {
+  DataBufferSP buf;
+  if (m_gdb_comm.GetQXferAuxvReadSupported()) {
+    std::string response_string;
+    if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::",
+                                                      response_string) ==
+        GDBRemoteCommunication::PacketResult::Success)
+      buf.reset(new DataBufferHeap(response_string.c_str(),
+                                   response_string.length()));
+  }
+  return buf;
 }
 
 StructuredData::ObjectSP
-ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid)
-{
-    StructuredData::ObjectSP object_sp;
+ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) {
+  StructuredData::ObjectSP object_sp;
 
-    if (m_gdb_comm.GetThreadExtendedInfoSupported())
-    {
-        StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
-        SystemRuntime *runtime = GetSystemRuntime();
-        if (runtime)
-        {
-            runtime->AddThreadExtendedInfoPacketHints (args_dict);
-        }
-        args_dict->GetAsDictionary()->AddIntegerItem ("thread", tid);
-
-        StreamString packet;
-        packet << "jThreadExtendedInfo:";
-        args_dict->Dump (packet, false);
-
-        // FIXME the final character of a JSON dictionary, '}', is the escape
-        // character in gdb-remote binary mode.  lldb currently doesn't escape
-        // these characters in its packet output -- so we add the quoted version
-        // of the } character here manually in case we talk to a debugserver which
-        // un-escapes the characters at packet read time.
-        packet << (char) (0x7d ^ 0x20);
-
-        StringExtractorGDBRemote response;
-        response.SetResponseValidatorToJSON();
-        if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
-        {
-            StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
-            if (response_type == StringExtractorGDBRemote::eResponse)
-            {
-                if (!response.Empty())
-                {
-                    object_sp = StructuredData::ParseJSON (response.GetStringRef());
-                }
-            }
-        }
-    }
-    return object_sp;
-}
-
-StructuredData::ObjectSP
-ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count)
-{
-
+  if (m_gdb_comm.GetThreadExtendedInfoSupported()) {
     StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
-    args_dict->GetAsDictionary()->AddIntegerItem ("image_list_address", image_list_address);
-    args_dict->GetAsDictionary()->AddIntegerItem ("image_count", image_count);
-
-    return GetLoadedDynamicLibrariesInfos_sender (args_dict);
-}
-
-StructuredData::ObjectSP
-ProcessGDBRemote::GetLoadedDynamicLibrariesInfos ()
-{
-    StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
-
-    args_dict->GetAsDictionary()->AddBooleanItem ("fetch_all_solibs", true);
-
-    return GetLoadedDynamicLibrariesInfos_sender (args_dict);
-}
-
-StructuredData::ObjectSP
-ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (const std::vector<lldb::addr_t> &load_addresses)
-{
-    StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
-    StructuredData::ArraySP addresses(new StructuredData::Array);
-
-    for (auto addr : load_addresses)
-    {
-        StructuredData::ObjectSP addr_sp (new StructuredData::Integer (addr));
-        addresses->AddItem (addr_sp);
+    SystemRuntime *runtime = GetSystemRuntime();
+    if (runtime) {
+      runtime->AddThreadExtendedInfoPacketHints(args_dict);
     }
+    args_dict->GetAsDictionary()->AddIntegerItem("thread", tid);
 
-    args_dict->GetAsDictionary()->AddItem ("solib_addresses", addresses);
+    StreamString packet;
+    packet << "jThreadExtendedInfo:";
+    args_dict->Dump(packet, false);
 
-    return GetLoadedDynamicLibrariesInfos_sender (args_dict);
-}
+    // FIXME the final character of a JSON dictionary, '}', is the escape
+    // character in gdb-remote binary mode.  lldb currently doesn't escape
+    // these characters in its packet output -- so we add the quoted version
+    // of the } character here manually in case we talk to a debugserver which
+    // un-escapes the characters at packet read time.
+    packet << (char)(0x7d ^ 0x20);
 
-StructuredData::ObjectSP
-ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender (StructuredData::ObjectSP args_dict)
-{
-    StructuredData::ObjectSP object_sp;
-
-    if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported())
-    {
-        // Scope for the scoped timeout object
-        GDBRemoteCommunication::ScopedTimeout timeout (m_gdb_comm, 10);
-
-        StreamString packet;
-        packet << "jGetLoadedDynamicLibrariesInfos:";
-        args_dict->Dump (packet, false);
-
-        // FIXME the final character of a JSON dictionary, '}', is the escape
-        // character in gdb-remote binary mode.  lldb currently doesn't escape
-        // these characters in its packet output -- so we add the quoted version
-        // of the } character here manually in case we talk to a debugserver which
-        // un-escapes the characters at packet read time.
-        packet << (char) (0x7d ^ 0x20);
-
-        StringExtractorGDBRemote response;
-        response.SetResponseValidatorToJSON();
-        if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
-        {
-            StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
-            if (response_type == StringExtractorGDBRemote::eResponse)
-            {
-                if (!response.Empty())
-                {
-                    object_sp = StructuredData::ParseJSON (response.GetStringRef());
-                }
-            }
+    StringExtractorGDBRemote response;
+    response.SetResponseValidatorToJSON();
+    if (m_gdb_comm.SendPacketAndWaitForResponse(
+            packet.GetData(), packet.GetSize(), response, false) ==
+        GDBRemoteCommunication::PacketResult::Success) {
+      StringExtractorGDBRemote::ResponseType response_type =
+          response.GetResponseType();
+      if (response_type == StringExtractorGDBRemote::eResponse) {
+        if (!response.Empty()) {
+          object_sp = StructuredData::ParseJSON(response.GetStringRef());
         }
+      }
     }
-    return object_sp;
+  }
+  return object_sp;
 }
 
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
+    lldb::addr_t image_list_address, lldb::addr_t image_count) {
 
+  StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+  args_dict->GetAsDictionary()->AddIntegerItem("image_list_address",
+                                               image_list_address);
+  args_dict->GetAsDictionary()->AddIntegerItem("image_count", image_count);
 
+  return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos() {
+  StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+
+  args_dict->GetAsDictionary()->AddBooleanItem("fetch_all_solibs", true);
+
+  return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
+
+StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos(
+    const std::vector<lldb::addr_t> &load_addresses) {
+  StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+  StructuredData::ArraySP addresses(new StructuredData::Array);
+
+  for (auto addr : load_addresses) {
+    StructuredData::ObjectSP addr_sp(new StructuredData::Integer(addr));
+    addresses->AddItem(addr_sp);
+  }
+
+  args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses);
+
+  return GetLoadedDynamicLibrariesInfos_sender(args_dict);
+}
 
 StructuredData::ObjectSP
-ProcessGDBRemote::GetSharedCacheInfo ()
-{
-    StructuredData::ObjectSP object_sp;
-    StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender(
+    StructuredData::ObjectSP args_dict) {
+  StructuredData::ObjectSP object_sp;
 
-    if (m_gdb_comm.GetSharedCacheInfoSupported())
-    {
-        StreamString packet;
-        packet << "jGetSharedCacheInfo:";
-        args_dict->Dump (packet, false);
+  if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) {
+    // Scope for the scoped timeout object
+    GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm, 10);
 
-        // FIXME the final character of a JSON dictionary, '}', is the escape
-        // character in gdb-remote binary mode.  lldb currently doesn't escape
-        // these characters in its packet output -- so we add the quoted version
-        // of the } character here manually in case we talk to a debugserver which
-        // un-escapes the characters at packet read time.
-        packet << (char) (0x7d ^ 0x20);
+    StreamString packet;
+    packet << "jGetLoadedDynamicLibrariesInfos:";
+    args_dict->Dump(packet, false);
 
-        StringExtractorGDBRemote response;
-        response.SetResponseValidatorToJSON();
-        if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success)
-        {
-            StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType();
-            if (response_type == StringExtractorGDBRemote::eResponse)
-            {
-                if (!response.Empty())
-                {
-                    object_sp = StructuredData::ParseJSON (response.GetStringRef());
-                }
-            }
+    // FIXME the final character of a JSON dictionary, '}', is the escape
+    // character in gdb-remote binary mode.  lldb currently doesn't escape
+    // these characters in its packet output -- so we add the quoted version
+    // of the } character here manually in case we talk to a debugserver which
+    // un-escapes the characters at packet read time.
+    packet << (char)(0x7d ^ 0x20);
+
+    StringExtractorGDBRemote response;
+    response.SetResponseValidatorToJSON();
+    if (m_gdb_comm.SendPacketAndWaitForResponse(
+            packet.GetData(), packet.GetSize(), response, false) ==
+        GDBRemoteCommunication::PacketResult::Success) {
+      StringExtractorGDBRemote::ResponseType response_type =
+          response.GetResponseType();
+      if (response_type == StringExtractorGDBRemote::eResponse) {
+        if (!response.Empty()) {
+          object_sp = StructuredData::ParseJSON(response.GetStringRef());
         }
+      }
     }
-    return object_sp;
+  }
+  return object_sp;
 }
 
-Error
-ProcessGDBRemote::ConfigureStructuredData(const ConstString &type_name,
-                                          const StructuredData::ObjectSP
-                                          &config_sp)
-{
-    return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
+StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() {
+  StructuredData::ObjectSP object_sp;
+  StructuredData::ObjectSP args_dict(new StructuredData::Dictionary());
+
+  if (m_gdb_comm.GetSharedCacheInfoSupported()) {
+    StreamString packet;
+    packet << "jGetSharedCacheInfo:";
+    args_dict->Dump(packet, false);
+
+    // FIXME the final character of a JSON dictionary, '}', is the escape
+    // character in gdb-remote binary mode.  lldb currently doesn't escape
+    // these characters in its packet output -- so we add the quoted version
+    // of the } character here manually in case we talk to a debugserver which
+    // un-escapes the characters at packet read time.
+    packet << (char)(0x7d ^ 0x20);
+
+    StringExtractorGDBRemote response;
+    response.SetResponseValidatorToJSON();
+    if (m_gdb_comm.SendPacketAndWaitForResponse(
+            packet.GetData(), packet.GetSize(), response, false) ==
+        GDBRemoteCommunication::PacketResult::Success) {
+      StringExtractorGDBRemote::ResponseType response_type =
+          response.GetResponseType();
+      if (response_type == StringExtractorGDBRemote::eResponse) {
+        if (!response.Empty()) {
+          object_sp = StructuredData::ParseJSON(response.GetStringRef());
+        }
+      }
+    }
+  }
+  return object_sp;
+}
+
+Error ProcessGDBRemote::ConfigureStructuredData(
+    const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
+  return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp);
 }
 
 // Establish the largest memory read/write payloads we should use.
@@ -4334,100 +3971,82 @@
 // If the remote stub doesn't advertise a max packet size, use a
 // conservative default.
 
-void
-ProcessGDBRemote::GetMaxMemorySize()
-{
-    const uint64_t reasonable_largeish_default = 128 * 1024;
-    const uint64_t conservative_default = 512;
+void ProcessGDBRemote::GetMaxMemorySize() {
+  const uint64_t reasonable_largeish_default = 128 * 1024;
+  const uint64_t conservative_default = 512;
 
-    if (m_max_memory_size == 0)
-    {
-        uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();
-        if (stub_max_size != UINT64_MAX && stub_max_size != 0)
-        {
-            // Save the stub's claimed maximum packet size
-            m_remote_stub_max_memory_size = stub_max_size;
+  if (m_max_memory_size == 0) {
+    uint64_t stub_max_size = m_gdb_comm.GetRemoteMaxPacketSize();
+    if (stub_max_size != UINT64_MAX && stub_max_size != 0) {
+      // Save the stub's claimed maximum packet size
+      m_remote_stub_max_memory_size = stub_max_size;
 
-            // Even if the stub says it can support ginormous packets,
-            // don't exceed our reasonable largeish default packet size.
-            if (stub_max_size > reasonable_largeish_default)
-            {
-                stub_max_size = reasonable_largeish_default;
-            }
+      // Even if the stub says it can support ginormous packets,
+      // don't exceed our reasonable largeish default packet size.
+      if (stub_max_size > reasonable_largeish_default) {
+        stub_max_size = reasonable_largeish_default;
+      }
 
-            m_max_memory_size = stub_max_size;
-        }
-        else
-        {
-            m_max_memory_size = conservative_default;
-        }
+      m_max_memory_size = stub_max_size;
+    } else {
+      m_max_memory_size = conservative_default;
     }
+  }
 }
 
-void
-ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max)
-{
-    if (user_specified_max != 0)
-    {
-        GetMaxMemorySize ();
+void ProcessGDBRemote::SetUserSpecifiedMaxMemoryTransferSize(
+    uint64_t user_specified_max) {
+  if (user_specified_max != 0) {
+    GetMaxMemorySize();
 
-        if (m_remote_stub_max_memory_size != 0)
-        {
-            if (m_remote_stub_max_memory_size < user_specified_max)
-            {
-                m_max_memory_size = m_remote_stub_max_memory_size;   // user specified a packet size too big, go as big
-                                                                     // as the remote stub says we can go.
-            }
-            else
-            {
-                m_max_memory_size = user_specified_max;             // user's packet size is good
-            }
-        }
-        else
-        {
-            m_max_memory_size = user_specified_max;                 // user's packet size is probably fine
-        }
+    if (m_remote_stub_max_memory_size != 0) {
+      if (m_remote_stub_max_memory_size < user_specified_max) {
+        m_max_memory_size = m_remote_stub_max_memory_size; // user specified a
+                                                           // packet size too
+                                                           // big, go as big
+        // as the remote stub says we can go.
+      } else {
+        m_max_memory_size = user_specified_max; // user's packet size is good
+      }
+    } else {
+      m_max_memory_size =
+          user_specified_max; // user's packet size is probably fine
     }
+  }
 }
 
-bool
-ProcessGDBRemote::GetModuleSpec(const FileSpec& module_file_spec,
-                                const ArchSpec& arch,
-                                ModuleSpec &module_spec)
-{
-    Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+bool ProcessGDBRemote::GetModuleSpec(const FileSpec &module_file_spec,
+                                     const ArchSpec &arch,
+                                     ModuleSpec &module_spec) {
+  Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
 
-    if (!m_gdb_comm.GetModuleInfo (module_file_spec, arch, module_spec))
-    {
-        if (log)
-            log->Printf ("ProcessGDBRemote::%s - failed to get module info for %s:%s",
-                         __FUNCTION__, module_file_spec.GetPath ().c_str (),
-                         arch.GetTriple ().getTriple ().c_str ());
-        return false;
-    }
-
+  if (!m_gdb_comm.GetModuleInfo(module_file_spec, arch, module_spec)) {
     if (log)
-    {
-        StreamString stream;
-        module_spec.Dump (stream);
-        log->Printf ("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
-                     __FUNCTION__, module_file_spec.GetPath ().c_str (),
-                     arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
-    }
+      log->Printf("ProcessGDBRemote::%s - failed to get module info for %s:%s",
+                  __FUNCTION__, module_file_spec.GetPath().c_str(),
+                  arch.GetTriple().getTriple().c_str());
+    return false;
+  }
 
-    return true;
+  if (log) {
+    StreamString stream;
+    module_spec.Dump(stream);
+    log->Printf("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
+                __FUNCTION__, module_file_spec.GetPath().c_str(),
+                arch.GetTriple().getTriple().c_str(),
+                stream.GetString().c_str());
+  }
+
+  return true;
 }
 
-bool
-ProcessGDBRemote::GetHostOSVersion(uint32_t &major,
-                                   uint32_t &minor,
-                                   uint32_t &update)
-{
-    if (m_gdb_comm.GetOSVersion(major, minor, update))
-        return true;
-    // We failed to get the host OS version, defer to the base
-    // implementation to correctly invalidate the arguments.
-    return Process::GetHostOSVersion(major, minor, update);
+bool ProcessGDBRemote::GetHostOSVersion(uint32_t &major, uint32_t &minor,
+                                        uint32_t &update) {
+  if (m_gdb_comm.GetOSVersion(major, minor, update))
+    return true;
+  // We failed to get the host OS version, defer to the base
+  // implementation to correctly invalidate the arguments.
+  return Process::GetHostOSVersion(major, minor, update);
 }
 
 namespace {
@@ -4435,29 +4054,29 @@
 typedef std::vector<std::string> stringVec;
 
 typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
-struct RegisterSetInfo
-{
-    ConstString name;
+struct RegisterSetInfo {
+  ConstString name;
 };
 
 typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
 
-struct GdbServerTargetInfo
-{
-    std::string arch;
-    std::string osabi;
-    stringVec includes;
-    RegisterSetMap reg_set_map;
-    XMLNode feature_node;
+struct GdbServerTargetInfo {
+  std::string arch;
+  std::string osabi;
+  stringVec includes;
+  RegisterSetMap reg_set_map;
+  XMLNode feature_node;
 };
 
-bool
-ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp, uint32_t &cur_reg_num, uint32_t &reg_offset)
-{
-    if (!feature_node)
-        return false;
+bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info,
+                    GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp,
+                    uint32_t &cur_reg_num, uint32_t &reg_offset) {
+  if (!feature_node)
+    return false;
 
-    feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset, &abi_sp](const XMLNode &reg_node) -> bool {
+  feature_node.ForEachChildElementWithName(
+      "reg", [&target_info, &dyn_reg_info, &cur_reg_num, &reg_offset,
+              &abi_sp](const XMLNode &reg_node) -> bool {
         std::string gdb_group;
         std::string gdb_type;
         ConstString reg_name;
@@ -4468,1076 +4087,1001 @@
         std::vector<uint8_t> dwarf_opcode_bytes;
         bool encoding_set = false;
         bool format_set = false;
-        RegisterInfo reg_info = { NULL,                 // Name
-            NULL,                 // Alt name
-            0,                    // byte size
-            reg_offset,           // offset
-            eEncodingUint,        // encoding
-            eFormatHex,           // format
+        RegisterInfo reg_info = {
+            NULL,          // Name
+            NULL,          // Alt name
+            0,             // byte size
+            reg_offset,    // offset
+            eEncodingUint, // encoding
+            eFormatHex,    // format
             {
                 LLDB_INVALID_REGNUM, // eh_frame reg num
                 LLDB_INVALID_REGNUM, // DWARF reg num
                 LLDB_INVALID_REGNUM, // generic reg num
-                cur_reg_num,        // process plugin reg num
-                cur_reg_num         // native register number
+                cur_reg_num,         // process plugin reg num
+                cur_reg_num          // native register number
             },
             NULL,
             NULL,
-            NULL,  // Dwarf Expression opcode bytes pointer
-            0      // Dwarf Expression opcode bytes length 
+            NULL, // Dwarf Expression opcode bytes pointer
+            0     // Dwarf Expression opcode bytes length
         };
 
-        reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, &reg_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, &reg_info, &cur_reg_num, &reg_offset, &dwarf_opcode_bytes](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
-            if (name == "name")
-            {
-                reg_name.SetString(value);
+        reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type,
+                                   &reg_name, &alt_name, &set_name, &value_regs,
+                                   &invalidate_regs, &encoding_set, &format_set,
+                                   &reg_info, &cur_reg_num, &reg_offset,
+                                   &dwarf_opcode_bytes](
+                                      const llvm::StringRef &name,
+                                      const llvm::StringRef &value) -> bool {
+          if (name == "name") {
+            reg_name.SetString(value);
+          } else if (name == "bitsize") {
+            reg_info.byte_size =
+                StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
+          } else if (name == "type") {
+            gdb_type = value.str();
+          } else if (name == "group") {
+            gdb_group = value.str();
+          } else if (name == "regnum") {
+            const uint32_t regnum =
+                StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+            if (regnum != LLDB_INVALID_REGNUM) {
+              reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
             }
-            else if (name == "bitsize")
-            {
-                reg_info.byte_size = StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
-            }
-            else if (name == "type")
-            {
-                gdb_type = value.str();
-            }
-            else if (name == "group")
-            {
-                gdb_group = value.str();
-            }
-            else if (name == "regnum")
-            {
-                const uint32_t regnum = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
-                if (regnum != LLDB_INVALID_REGNUM)
-                {
-                    reg_info.kinds[eRegisterKindProcessPlugin] = regnum;
-                }
-            }
-            else if (name == "offset")
-            {
-                reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
-            }
-            else if (name == "altname")
-            {
-                alt_name.SetString(value);
-            }
-            else if (name == "encoding")
-            {
-                encoding_set = true;
-                reg_info.encoding = Args::StringToEncoding (value.data(), eEncodingUint);
-            }
-            else if (name == "format")
-            {
-                format_set = true;
-                Format format = eFormatInvalid;
-                if (Args::StringToFormat (value.data(), format, NULL).Success())
-                    reg_info.format = format;
-                else if (value == "vector-sint8")
-                    reg_info.format = eFormatVectorOfSInt8;
-                else if (value == "vector-uint8")
-                    reg_info.format = eFormatVectorOfUInt8;
-                else if (value == "vector-sint16")
-                    reg_info.format = eFormatVectorOfSInt16;
-                else if (value == "vector-uint16")
-                    reg_info.format = eFormatVectorOfUInt16;
-                else if (value == "vector-sint32")
-                    reg_info.format = eFormatVectorOfSInt32;
-                else if (value == "vector-uint32")
-                    reg_info.format = eFormatVectorOfUInt32;
-                else if (value == "vector-float32")
-                    reg_info.format = eFormatVectorOfFloat32;
-                else if (value == "vector-uint128")
-                    reg_info.format = eFormatVectorOfUInt128;
-            }
-            else if (name == "group_id")
-            {
-                const uint32_t set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
-                RegisterSetMap::const_iterator pos = target_info.reg_set_map.find(set_id);
-                if (pos != target_info.reg_set_map.end())
-                    set_name = pos->second.name;
-            }
-            else if (name == "gcc_regnum" || name == "ehframe_regnum")
-            {
-                reg_info.kinds[eRegisterKindEHFrame] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
-            }
-            else if (name == "dwarf_regnum")
-            {
-                reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
-            }
-            else if (name == "generic")
-            {
-                reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value.data());
-            }
-            else if (name == "value_regnums")
-            {
-                SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
-            }
-            else if (name == "invalidate_regnums")
-            {
-                SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
-            }
-            else if (name == "dynamic_size_dwarf_expr_bytes")
-            {
-                StringExtractor opcode_extractor;
-                std::string opcode_string = value.str ();
-                size_t dwarf_opcode_len = opcode_string.length () / 2;
-                assert (dwarf_opcode_len > 0);
+          } else if (name == "offset") {
+            reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+          } else if (name == "altname") {
+            alt_name.SetString(value);
+          } else if (name == "encoding") {
+            encoding_set = true;
+            reg_info.encoding =
+                Args::StringToEncoding(value.data(), eEncodingUint);
+          } else if (name == "format") {
+            format_set = true;
+            Format format = eFormatInvalid;
+            if (Args::StringToFormat(value.data(), format, NULL).Success())
+              reg_info.format = format;
+            else if (value == "vector-sint8")
+              reg_info.format = eFormatVectorOfSInt8;
+            else if (value == "vector-uint8")
+              reg_info.format = eFormatVectorOfUInt8;
+            else if (value == "vector-sint16")
+              reg_info.format = eFormatVectorOfSInt16;
+            else if (value == "vector-uint16")
+              reg_info.format = eFormatVectorOfUInt16;
+            else if (value == "vector-sint32")
+              reg_info.format = eFormatVectorOfSInt32;
+            else if (value == "vector-uint32")
+              reg_info.format = eFormatVectorOfUInt32;
+            else if (value == "vector-float32")
+              reg_info.format = eFormatVectorOfFloat32;
+            else if (value == "vector-uint128")
+              reg_info.format = eFormatVectorOfUInt128;
+          } else if (name == "group_id") {
+            const uint32_t set_id =
+                StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+            RegisterSetMap::const_iterator pos =
+                target_info.reg_set_map.find(set_id);
+            if (pos != target_info.reg_set_map.end())
+              set_name = pos->second.name;
+          } else if (name == "gcc_regnum" || name == "ehframe_regnum") {
+            reg_info.kinds[eRegisterKindEHFrame] =
+                StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+          } else if (name == "dwarf_regnum") {
+            reg_info.kinds[eRegisterKindDWARF] =
+                StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+          } else if (name == "generic") {
+            reg_info.kinds[eRegisterKindGeneric] =
+                Args::StringToGenericRegister(value.data());
+          } else if (name == "value_regnums") {
+            SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
+          } else if (name == "invalidate_regnums") {
+            SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
+          } else if (name == "dynamic_size_dwarf_expr_bytes") {
+            StringExtractor opcode_extractor;
+            std::string opcode_string = value.str();
+            size_t dwarf_opcode_len = opcode_string.length() / 2;
+            assert(dwarf_opcode_len > 0);
 
-                dwarf_opcode_bytes.resize (dwarf_opcode_len);
-                reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
-                opcode_extractor.GetStringRef ().swap (opcode_string);
-                uint32_t ret_val = opcode_extractor.GetHexBytesAvail (dwarf_opcode_bytes);
-                assert (dwarf_opcode_len == ret_val);
+            dwarf_opcode_bytes.resize(dwarf_opcode_len);
+            reg_info.dynamic_size_dwarf_len = dwarf_opcode_len;
+            opcode_extractor.GetStringRef().swap(opcode_string);
+            uint32_t ret_val =
+                opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes);
+            assert(dwarf_opcode_len == ret_val);
 
-                reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data ();
-            }
-            else
-            {
-                printf("unhandled attribute %s = %s\n", name.data(), value.data());
-            }
-            return true; // Keep iterating through all attributes
+            reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data();
+          } else {
+            printf("unhandled attribute %s = %s\n", name.data(), value.data());
+          }
+          return true; // Keep iterating through all attributes
         });
 
-        if (!gdb_type.empty() && !(encoding_set || format_set))
-        {
-            if (gdb_type.find("int") == 0)
-            {
-                reg_info.format = eFormatHex;
-                reg_info.encoding = eEncodingUint;
-            }
-            else if (gdb_type == "data_ptr" || gdb_type == "code_ptr")
-            {
-                reg_info.format = eFormatAddressInfo;
-                reg_info.encoding = eEncodingUint;
-            }
-            else if (gdb_type == "i387_ext" || gdb_type == "float")
-            {
-                reg_info.format = eFormatFloat;
-                reg_info.encoding = eEncodingIEEE754;
-            }
+        if (!gdb_type.empty() && !(encoding_set || format_set)) {
+          if (gdb_type.find("int") == 0) {
+            reg_info.format = eFormatHex;
+            reg_info.encoding = eEncodingUint;
+          } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") {
+            reg_info.format = eFormatAddressInfo;
+            reg_info.encoding = eEncodingUint;
+          } else if (gdb_type == "i387_ext" || gdb_type == "float") {
+            reg_info.format = eFormatFloat;
+            reg_info.encoding = eEncodingIEEE754;
+          }
         }
 
-        // Only update the register set name if we didn't get a "reg_set" attribute.
+        // Only update the register set name if we didn't get a "reg_set"
+        // attribute.
         // "set_name" will be empty if we didn't have a "reg_set" attribute.
         if (!set_name && !gdb_group.empty())
-            set_name.SetCString(gdb_group.c_str());
+          set_name.SetCString(gdb_group.c_str());
 
         reg_info.byte_offset = reg_offset;
-        assert (reg_info.byte_size != 0);
+        assert(reg_info.byte_size != 0);
         reg_offset += reg_info.byte_size;
-        if (!value_regs.empty())
-        {
-            value_regs.push_back(LLDB_INVALID_REGNUM);
-            reg_info.value_regs = value_regs.data();
+        if (!value_regs.empty()) {
+          value_regs.push_back(LLDB_INVALID_REGNUM);
+          reg_info.value_regs = value_regs.data();
         }
-        if (!invalidate_regs.empty())
-        {
-            invalidate_regs.push_back(LLDB_INVALID_REGNUM);
-            reg_info.invalidate_regs = invalidate_regs.data();
+        if (!invalidate_regs.empty()) {
+          invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+          reg_info.invalidate_regs = invalidate_regs.data();
         }
 
         ++cur_reg_num;
-        AugmentRegisterInfoViaABI (reg_info, reg_name, abi_sp);
+        AugmentRegisterInfoViaABI(reg_info, reg_name, abi_sp);
         dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name);
 
         return true; // Keep iterating through all "reg" elements
-    });
-    return true;
+      });
+  return true;
 }
 
 } // namespace {}
 
-
 // query the target of gdb-remote for extended target information
 // return:  'true'  on success
 //          'false' on failure
-bool
-ProcessGDBRemote::GetGDBServerRegisterInfo (ArchSpec &arch_to_use)
-{
-    // Make sure LLDB has an XML parser it can use first
-    if (!XMLDocument::XMLEnabled())
-        return false;
+bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) {
+  // Make sure LLDB has an XML parser it can use first
+  if (!XMLDocument::XMLEnabled())
+    return false;
 
-    // redirect libxml2's error handler since the default prints to stdout
+  // redirect libxml2's error handler since the default prints to stdout
 
-    GDBRemoteCommunicationClient & comm = m_gdb_comm;
+  GDBRemoteCommunicationClient &comm = m_gdb_comm;
 
-    // check that we have extended feature read support
-    if ( !comm.GetQXferFeaturesReadSupported( ) )
-        return false;
+  // check that we have extended feature read support
+  if (!comm.GetQXferFeaturesReadSupported())
+    return false;
 
-    // request the target xml file
-    std::string raw;
-    lldb_private::Error lldberr;
-    if (!comm.ReadExtFeature(ConstString("features"),
-                             ConstString("target.xml"),
-                             raw,
-                             lldberr))
-    {
-        return false;
-    }
+  // request the target xml file
+  std::string raw;
+  lldb_private::Error lldberr;
+  if (!comm.ReadExtFeature(ConstString("features"), ConstString("target.xml"),
+                           raw, lldberr)) {
+    return false;
+  }
 
+  XMLDocument xml_document;
 
-    XMLDocument xml_document;
+  if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml")) {
+    GdbServerTargetInfo target_info;
 
-    if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml"))
-    {
-        GdbServerTargetInfo target_info;
+    XMLNode target_node = xml_document.GetRootElement("target");
+    if (target_node) {
+      XMLNode feature_node;
+      target_node.ForEachChildElement([&target_info, this, &feature_node](
+                                          const XMLNode &node) -> bool {
+        llvm::StringRef name = node.GetName();
+        if (name == "architecture") {
+          node.GetElementText(target_info.arch);
+        } else if (name == "osabi") {
+          node.GetElementText(target_info.osabi);
+        } else if (name == "xi:include" || name == "include") {
+          llvm::StringRef href = node.GetAttributeValue("href");
+          if (!href.empty())
+            target_info.includes.push_back(href.str());
+        } else if (name == "feature") {
+          feature_node = node;
+        } else if (name == "groups") {
+          node.ForEachChildElementWithName(
+              "group", [&target_info](const XMLNode &node) -> bool {
+                uint32_t set_id = UINT32_MAX;
+                RegisterSetInfo set_info;
 
-        XMLNode target_node = xml_document.GetRootElement("target");
-        if (target_node)
-        {
-            XMLNode feature_node;
-            target_node.ForEachChildElement([&target_info, this, &feature_node](const XMLNode &node) -> bool
-            {
-                llvm::StringRef name = node.GetName();
-                if (name == "architecture")
-                {
-                    node.GetElementText(target_info.arch);
-                }
-                else if (name == "osabi")
-                {
-                    node.GetElementText(target_info.osabi);
-                }
-                else if (name == "xi:include" || name == "include")
-                {
-                    llvm::StringRef href = node.GetAttributeValue("href");
-                    if (!href.empty())
-                        target_info.includes.push_back(href.str());
-                }
-                else if (name == "feature")
-                {
-                    feature_node = node;
-                }
-                else if (name == "groups")
-                {
-                    node.ForEachChildElementWithName("group", [&target_info](const XMLNode &node) -> bool {
-                        uint32_t set_id = UINT32_MAX;
-                        RegisterSetInfo set_info;
-
-                        node.ForEachAttribute([&set_id, &set_info](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
-                            if (name == "id")
-                                set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
-                            if (name == "name")
-                                set_info.name = ConstString(value);
-                            return true; // Keep iterating through all attributes
-                        });
-
-                        if (set_id != UINT32_MAX)
-                            target_info.reg_set_map[set_id] = set_info;
-                        return true; // Keep iterating through all "group" elements
+                node.ForEachAttribute(
+                    [&set_id, &set_info](const llvm::StringRef &name,
+                                         const llvm::StringRef &value) -> bool {
+                      if (name == "id")
+                        set_id = StringConvert::ToUInt32(value.data(),
+                                                         UINT32_MAX, 0);
+                      if (name == "name")
+                        set_info.name = ConstString(value);
+                      return true; // Keep iterating through all attributes
                     });
-                }
-                return true; // Keep iterating through all children of the target_node
-            });
 
-            // Initialize these outside of ParseRegisters, since they should not be reset inside each include feature
-            uint32_t cur_reg_num = 0;
-            uint32_t reg_offset = 0;
-
-            // Don't use Process::GetABI, this code gets called from DidAttach, and in that context we haven't
-            // set the Target's architecture yet, so the ABI is also potentially incorrect.
-            ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
-            if (feature_node)
-            {
-                ParseRegisters(feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
-            }
-
-            for (const auto &include : target_info.includes)
-            {
-                // request register file
-                std::string xml_data;
-                if (!comm.ReadExtFeature(ConstString("features"),
-                                         ConstString(include),
-                                         xml_data,
-                                         lldberr))
-                    continue;
-
-                XMLDocument include_xml_document;
-                include_xml_document.ParseMemory(xml_data.data(), xml_data.size(), include.c_str());
-                XMLNode include_feature_node = include_xml_document.GetRootElement("feature");
-                if (include_feature_node)
-                {
-                    ParseRegisters(include_feature_node, target_info, this->m_register_info, abi_to_use_sp, cur_reg_num, reg_offset);
-                }
-            }
-            this->m_register_info.Finalize(arch_to_use);
+                if (set_id != UINT32_MAX)
+                  target_info.reg_set_map[set_id] = set_info;
+                return true; // Keep iterating through all "group" elements
+              });
         }
-    }
+        return true; // Keep iterating through all children of the target_node
+      });
 
-    return m_register_info.GetNumRegisters() > 0;
+      // Initialize these outside of ParseRegisters, since they should not be
+      // reset inside each include feature
+      uint32_t cur_reg_num = 0;
+      uint32_t reg_offset = 0;
+
+      // Don't use Process::GetABI, this code gets called from DidAttach, and in
+      // that context we haven't
+      // set the Target's architecture yet, so the ABI is also potentially
+      // incorrect.
+      ABISP abi_to_use_sp = ABI::FindPlugin(arch_to_use);
+      if (feature_node) {
+        ParseRegisters(feature_node, target_info, this->m_register_info,
+                       abi_to_use_sp, cur_reg_num, reg_offset);
+      }
+
+      for (const auto &include : target_info.includes) {
+        // request register file
+        std::string xml_data;
+        if (!comm.ReadExtFeature(ConstString("features"), ConstString(include),
+                                 xml_data, lldberr))
+          continue;
+
+        XMLDocument include_xml_document;
+        include_xml_document.ParseMemory(xml_data.data(), xml_data.size(),
+                                         include.c_str());
+        XMLNode include_feature_node =
+            include_xml_document.GetRootElement("feature");
+        if (include_feature_node) {
+          ParseRegisters(include_feature_node, target_info,
+                         this->m_register_info, abi_to_use_sp, cur_reg_num,
+                         reg_offset);
+        }
+      }
+      this->m_register_info.Finalize(arch_to_use);
+    }
+  }
+
+  return m_register_info.GetNumRegisters() > 0;
 }
 
-Error
-ProcessGDBRemote::GetLoadedModuleList (LoadedModuleInfoList & list)
-{
-    // Make sure LLDB has an XML parser it can use first
-    if (!XMLDocument::XMLEnabled())
-        return Error (0, ErrorType::eErrorTypeGeneric);
+Error ProcessGDBRemote::GetLoadedModuleList(LoadedModuleInfoList &list) {
+  // Make sure LLDB has an XML parser it can use first
+  if (!XMLDocument::XMLEnabled())
+    return Error(0, ErrorType::eErrorTypeGeneric);
 
-    Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS);
+  Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS);
+  if (log)
+    log->Printf("ProcessGDBRemote::%s", __FUNCTION__);
+
+  GDBRemoteCommunicationClient &comm = m_gdb_comm;
+
+  // check that we have extended feature read support
+  if (comm.GetQXferLibrariesSVR4ReadSupported()) {
+    list.clear();
+
+    // request the loaded library list
+    std::string raw;
+    lldb_private::Error lldberr;
+
+    if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""),
+                             raw, lldberr))
+      return Error(0, ErrorType::eErrorTypeGeneric);
+
+    // parse the xml file in memory
     if (log)
-        log->Printf ("ProcessGDBRemote::%s", __FUNCTION__);
+      log->Printf("parsing: %s", raw.c_str());
+    XMLDocument doc;
 
-    GDBRemoteCommunicationClient & comm = m_gdb_comm;
+    if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
+      return Error(0, ErrorType::eErrorTypeGeneric);
 
-    // check that we have extended feature read support
-    if (comm.GetQXferLibrariesSVR4ReadSupported ()) {
-        list.clear ();
+    XMLNode root_element = doc.GetRootElement("library-list-svr4");
+    if (!root_element)
+      return Error();
 
-        // request the loaded library list
-        std::string raw;
-        lldb_private::Error lldberr;
+    // main link map structure
+    llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
+    if (!main_lm.empty()) {
+      list.m_link_map =
+          StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
+    }
 
-        if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr))
-          return Error (0, ErrorType::eErrorTypeGeneric);
+    root_element.ForEachChildElementWithName(
+        "library", [log, &list](const XMLNode &library) -> bool {
 
-        // parse the xml file in memory
-        if (log)
-            log->Printf ("parsing: %s", raw.c_str());
-        XMLDocument doc;
+          LoadedModuleInfoList::LoadedModuleInfo module;
 
-        if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
-            return Error (0, ErrorType::eErrorTypeGeneric);
-
-        XMLNode root_element = doc.GetRootElement("library-list-svr4");
-        if (!root_element)
-            return Error();
-
-        // main link map structure
-        llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
-        if (!main_lm.empty())
-        {
-            list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
-        }
-
-        root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
-
-            LoadedModuleInfoList::LoadedModuleInfo module;
-
-            library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+          library.ForEachAttribute(
+              [log, &module](const llvm::StringRef &name,
+                             const llvm::StringRef &value) -> bool {
 
                 if (name == "name")
-                    module.set_name (value.str());
-                else if (name == "lm")
-                {
-                    // the address of the link_map struct.
-                    module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
-                }
-                else if (name == "l_addr")
-                {
-                    // the displacement as read from the field 'l_addr' of the link_map struct.
-                    module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
-                    // base address is always a displacement, not an absolute value.
-                    module.set_base_is_offset(true);
-                }
-                else if (name == "l_ld")
-                {
-                    // the memory address of the libraries PT_DYAMIC section.
-                    module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
+                  module.set_name(value.str());
+                else if (name == "lm") {
+                  // the address of the link_map struct.
+                  module.set_link_map(StringConvert::ToUInt64(
+                      value.data(), LLDB_INVALID_ADDRESS, 0));
+                } else if (name == "l_addr") {
+                  // the displacement as read from the field 'l_addr' of the
+                  // link_map struct.
+                  module.set_base(StringConvert::ToUInt64(
+                      value.data(), LLDB_INVALID_ADDRESS, 0));
+                  // base address is always a displacement, not an absolute
+                  // value.
+                  module.set_base_is_offset(true);
+                } else if (name == "l_ld") {
+                  // the memory address of the libraries PT_DYAMIC section.
+                  module.set_dynamic(StringConvert::ToUInt64(
+                      value.data(), LLDB_INVALID_ADDRESS, 0));
                 }
 
                 return true; // Keep iterating over all properties of "library"
-            });
+              });
 
-            if (log)
-            {
-                std::string name;
-                lldb::addr_t lm=0, base=0, ld=0;
-                bool base_is_offset;
+          if (log) {
+            std::string name;
+            lldb::addr_t lm = 0, base = 0, ld = 0;
+            bool base_is_offset;
 
-                module.get_name (name);
-                module.get_link_map (lm);
-                module.get_base (base);
-                module.get_base_is_offset (base_is_offset);
-                module.get_dynamic (ld);
+            module.get_name(name);
+            module.get_link_map(lm);
+            module.get_base(base);
+            module.get_base_is_offset(base_is_offset);
+            module.get_dynamic(ld);
 
-                log->Printf ("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64 "[%s], ld:0x%08" PRIx64 ", name:'%s')", lm, base, (base_is_offset ? "offset" : "absolute"), ld, name.c_str());
-            }
+            log->Printf("found (link_map:0x%08" PRIx64 ", base:0x%08" PRIx64
+                        "[%s], ld:0x%08" PRIx64 ", name:'%s')",
+                        lm, base, (base_is_offset ? "offset" : "absolute"), ld,
+                        name.c_str());
+          }
 
-            list.add (module);
-            return true; // Keep iterating over all "library" elements in the root node
+          list.add(module);
+          return true; // Keep iterating over all "library" elements in the root
+                       // node
         });
 
-        if (log)
-            log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
-    } else if (comm.GetQXferLibrariesReadSupported ()) {
-        list.clear ();
+    if (log)
+      log->Printf("found %" PRId32 " modules in total",
+                  (int)list.m_list.size());
+  } else if (comm.GetQXferLibrariesReadSupported()) {
+    list.clear();
 
-        // request the loaded library list
-        std::string raw;
-        lldb_private::Error lldberr;
+    // request the loaded library list
+    std::string raw;
+    lldb_private::Error lldberr;
 
-        if (!comm.ReadExtFeature (ConstString ("libraries"), ConstString (""), raw, lldberr))
-          return Error (0, ErrorType::eErrorTypeGeneric);
+    if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw,
+                             lldberr))
+      return Error(0, ErrorType::eErrorTypeGeneric);
 
-        if (log)
-            log->Printf ("parsing: %s", raw.c_str());
-        XMLDocument doc;
+    if (log)
+      log->Printf("parsing: %s", raw.c_str());
+    XMLDocument doc;
 
-        if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
-            return Error (0, ErrorType::eErrorTypeGeneric);
+    if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
+      return Error(0, ErrorType::eErrorTypeGeneric);
 
-        XMLNode root_element = doc.GetRootElement("library-list");
-        if (!root_element)
-            return Error();
+    XMLNode root_element = doc.GetRootElement("library-list");
+    if (!root_element)
+      return Error();
 
-        root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
-            LoadedModuleInfoList::LoadedModuleInfo module;
+    root_element.ForEachChildElementWithName(
+        "library", [log, &list](const XMLNode &library) -> bool {
+          LoadedModuleInfoList::LoadedModuleInfo module;
 
-            llvm::StringRef name = library.GetAttributeValue("name");
-            module.set_name(name.str());
+          llvm::StringRef name = library.GetAttributeValue("name");
+          module.set_name(name.str());
 
-            // The base address of a given library will be the address of its
-            // first section. Most remotes send only one section for Windows
-            // targets for example.
-            const XMLNode &section = library.FindFirstChildElementWithName("section");
-            llvm::StringRef address = section.GetAttributeValue("address");
-            module.set_base(StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0));
-            // These addresses are absolute values.
-            module.set_base_is_offset(false);
+          // The base address of a given library will be the address of its
+          // first section. Most remotes send only one section for Windows
+          // targets for example.
+          const XMLNode &section =
+              library.FindFirstChildElementWithName("section");
+          llvm::StringRef address = section.GetAttributeValue("address");
+          module.set_base(
+              StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0));
+          // These addresses are absolute values.
+          module.set_base_is_offset(false);
 
-            if (log)
-            {
-                std::string name;
-                lldb::addr_t base = 0;
-                bool base_is_offset;
-                module.get_name (name);
-                module.get_base (base);
-                module.get_base_is_offset (base_is_offset);
+          if (log) {
+            std::string name;
+            lldb::addr_t base = 0;
+            bool base_is_offset;
+            module.get_name(name);
+            module.get_base(base);
+            module.get_base_is_offset(base_is_offset);
 
-                log->Printf ("found (base:0x%08" PRIx64 "[%s], name:'%s')", base, (base_is_offset ? "offset" : "absolute"), name.c_str());
-            }
+            log->Printf("found (base:0x%08" PRIx64 "[%s], name:'%s')", base,
+                        (base_is_offset ? "offset" : "absolute"), name.c_str());
+          }
 
-            list.add (module);
-            return true; // Keep iterating over all "library" elements in the root node
+          list.add(module);
+          return true; // Keep iterating over all "library" elements in the root
+                       // node
         });
 
-        if (log)
-            log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
-    } else {
-        return Error (0, ErrorType::eErrorTypeGeneric);
+    if (log)
+      log->Printf("found %" PRId32 " modules in total",
+                  (int)list.m_list.size());
+  } else {
+    return Error(0, ErrorType::eErrorTypeGeneric);
+  }
+
+  return Error();
+}
+
+lldb::ModuleSP ProcessGDBRemote::LoadModuleAtAddress(const FileSpec &file,
+                                                     lldb::addr_t link_map,
+                                                     lldb::addr_t base_addr,
+                                                     bool value_is_offset) {
+  DynamicLoader *loader = GetDynamicLoader();
+  if (!loader)
+    return nullptr;
+
+  return loader->LoadModuleAtAddress(file, link_map, base_addr,
+                                     value_is_offset);
+}
+
+size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) {
+  using lldb_private::process_gdb_remote::ProcessGDBRemote;
+
+  // request a list of loaded libraries from GDBServer
+  if (GetLoadedModuleList(module_list).Fail())
+    return 0;
+
+  // get a list of all the modules
+  ModuleList new_modules;
+
+  for (LoadedModuleInfoList::LoadedModuleInfo &modInfo : module_list.m_list) {
+    std::string mod_name;
+    lldb::addr_t mod_base;
+    lldb::addr_t link_map;
+    bool mod_base_is_offset;
+
+    bool valid = true;
+    valid &= modInfo.get_name(mod_name);
+    valid &= modInfo.get_base(mod_base);
+    valid &= modInfo.get_base_is_offset(mod_base_is_offset);
+    if (!valid)
+      continue;
+
+    if (!modInfo.get_link_map(link_map))
+      link_map = LLDB_INVALID_ADDRESS;
+
+    FileSpec file(mod_name.c_str(), true);
+    lldb::ModuleSP module_sp =
+        LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset);
+
+    if (module_sp.get())
+      new_modules.Append(module_sp);
+  }
+
+  if (new_modules.GetSize() > 0) {
+    ModuleList removed_modules;
+    Target &target = GetTarget();
+    ModuleList &loaded_modules = m_process->GetTarget().GetImages();
+
+    for (size_t i = 0; i < loaded_modules.GetSize(); ++i) {
+      const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
+
+      bool found = false;
+      for (size_t j = 0; j < new_modules.GetSize(); ++j) {
+        if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
+          found = true;
+      }
+
+      // The main executable will never be included in libraries-svr4, don't
+      // remove it
+      if (!found &&
+          loaded_module.get() != target.GetExecutableModulePointer()) {
+        removed_modules.Append(loaded_module);
+      }
     }
 
+    loaded_modules.Remove(removed_modules);
+    m_process->GetTarget().ModulesDidUnload(removed_modules, false);
+
+    new_modules.ForEach([&target](const lldb::ModuleSP module_sp) -> bool {
+      lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
+      if (!obj)
+        return true;
+
+      if (obj->GetType() != ObjectFile::Type::eTypeExecutable)
+        return true;
+
+      lldb::ModuleSP module_copy_sp = module_sp;
+      target.SetExecutableModule(module_copy_sp, false);
+      return false;
+    });
+
+    loaded_modules.AppendIfNeeded(new_modules);
+    m_process->GetTarget().ModulesDidLoad(new_modules);
+  }
+
+  return new_modules.GetSize();
+}
+
+size_t ProcessGDBRemote::LoadModules() {
+  LoadedModuleInfoList module_list;
+  return LoadModules(module_list);
+}
+
+Error ProcessGDBRemote::GetFileLoadAddress(const FileSpec &file,
+                                           bool &is_loaded,
+                                           lldb::addr_t &load_addr) {
+  is_loaded = false;
+  load_addr = LLDB_INVALID_ADDRESS;
+
+  std::string file_path = file.GetPath(false);
+  if (file_path.empty())
+    return Error("Empty file name specified");
+
+  StreamString packet;
+  packet.PutCString("qFileLoadAddress:");
+  packet.PutCStringAsRawHex8(file_path.c_str());
+
+  StringExtractorGDBRemote response;
+  if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
+                                              response, false) !=
+      GDBRemoteCommunication::PacketResult::Success)
+    return Error("Sending qFileLoadAddress packet failed");
+
+  if (response.IsErrorResponse()) {
+    if (response.GetError() == 1) {
+      // The file is not loaded into the inferior
+      is_loaded = false;
+      load_addr = LLDB_INVALID_ADDRESS;
+      return Error();
+    }
+
+    return Error(
+        "Fetching file load address from remote server returned an error");
+  }
+
+  if (response.IsNormalResponse()) {
+    is_loaded = true;
+    load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
     return Error();
+  }
+
+  return Error("Unknown error happened during sending the load address packet");
 }
 
-lldb::ModuleSP
-ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map,
-                                       lldb::addr_t base_addr, bool value_is_offset)
-{
-    DynamicLoader *loader = GetDynamicLoader();
-    if (!loader)
-        return nullptr;
+void ProcessGDBRemote::ModulesDidLoad(ModuleList &module_list) {
+  // We must call the lldb_private::Process::ModulesDidLoad () first before we
+  // do anything
+  Process::ModulesDidLoad(module_list);
 
-    return loader->LoadModuleAtAddress(file, link_map, base_addr, value_is_offset);
+  // After loading shared libraries, we can ask our remote GDB server if
+  // it needs any symbols.
+  m_gdb_comm.ServeSymbolLookups(this);
 }
 
-size_t
-ProcessGDBRemote::LoadModules (LoadedModuleInfoList &module_list)
-{
-    using lldb_private::process_gdb_remote::ProcessGDBRemote;
-
-    // request a list of loaded libraries from GDBServer
-    if (GetLoadedModuleList (module_list).Fail())
-        return 0;
-
-    // get a list of all the modules
-    ModuleList new_modules;
-
-    for (LoadedModuleInfoList::LoadedModuleInfo & modInfo : module_list.m_list)
-    {
-        std::string  mod_name;
-        lldb::addr_t mod_base;
-        lldb::addr_t link_map;
-        bool         mod_base_is_offset;
-
-        bool valid = true;
-        valid &= modInfo.get_name (mod_name);
-        valid &= modInfo.get_base (mod_base);
-        valid &= modInfo.get_base_is_offset (mod_base_is_offset);
-        if (!valid)
-            continue;
-
-        if (!modInfo.get_link_map (link_map))
-            link_map = LLDB_INVALID_ADDRESS;
-
-        FileSpec file (mod_name.c_str(), true);
-        lldb::ModuleSP module_sp = LoadModuleAtAddress (file, link_map, mod_base,
-                                                        mod_base_is_offset);
-
-        if (module_sp.get())
-            new_modules.Append (module_sp);
-    }
-
-    if (new_modules.GetSize() > 0)
-    {
-        ModuleList removed_modules;
-        Target &target = GetTarget();
-        ModuleList &loaded_modules = m_process->GetTarget().GetImages();
-
-        for (size_t i = 0; i < loaded_modules.GetSize(); ++i)
-        {
-            const lldb::ModuleSP loaded_module = loaded_modules.GetModuleAtIndex(i);
-
-            bool found = false;
-            for (size_t j = 0; j < new_modules.GetSize(); ++j)
-            {
-                if (new_modules.GetModuleAtIndex(j).get() == loaded_module.get())
-                    found = true;
-            }
-
-            // The main executable will never be included in libraries-svr4, don't remove it
-            if (!found && loaded_module.get() != target.GetExecutableModulePointer())
-            {
-                removed_modules.Append (loaded_module);
-            }
-        }
-
-        loaded_modules.Remove (removed_modules);
-        m_process->GetTarget().ModulesDidUnload (removed_modules, false);
-
-        new_modules.ForEach ([&target](const lldb::ModuleSP module_sp) -> bool
-        {
-            lldb_private::ObjectFile * obj = module_sp->GetObjectFile ();
-            if (!obj)
-                return true;
-
-            if (obj->GetType () != ObjectFile::Type::eTypeExecutable)
-                return true;
-
-            lldb::ModuleSP module_copy_sp = module_sp;
-            target.SetExecutableModule (module_copy_sp, false);
-            return false;
-        });
-
-        loaded_modules.AppendIfNeeded (new_modules);
-        m_process->GetTarget().ModulesDidLoad (new_modules);
-    }
-
-    return new_modules.GetSize();
-}
-
-size_t
-ProcessGDBRemote::LoadModules ()
-{
-    LoadedModuleInfoList module_list;
-    return LoadModules (module_list);
-}
-
-Error
-ProcessGDBRemote::GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr)
-{
-    is_loaded = false;
-    load_addr = LLDB_INVALID_ADDRESS;
-
-    std::string file_path = file.GetPath(false);
-    if (file_path.empty ())
-        return Error("Empty file name specified");
-
-    StreamString packet;
-    packet.PutCString("qFileLoadAddress:");
-    packet.PutCStringAsRawHex8(file_path.c_str());
-
-    StringExtractorGDBRemote response;
-    if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), response, false) != GDBRemoteCommunication::PacketResult::Success)
-        return Error("Sending qFileLoadAddress packet failed");
-
-    if (response.IsErrorResponse())
-    {
-        if (response.GetError() == 1)
-        {
-            // The file is not loaded into the inferior
-            is_loaded = false;
-            load_addr = LLDB_INVALID_ADDRESS;
-            return Error();
-        }
-
-        return Error("Fetching file load address from remote server returned an error");
-    }
-
-    if (response.IsNormalResponse())
-    {
-        is_loaded = true;
-        load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
-        return Error();
-    }
-
-    return Error("Unknown error happened during sending the load address packet");
-}
-
-
-void
-ProcessGDBRemote::ModulesDidLoad (ModuleList &module_list)
-{
-    // We must call the lldb_private::Process::ModulesDidLoad () first before we do anything
-    Process::ModulesDidLoad (module_list);
-
-    // After loading shared libraries, we can ask our remote GDB server if
-    // it needs any symbols.
-    m_gdb_comm.ServeSymbolLookups(this);
-}
-
-void
-ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out)
-{
-    AppendSTDOUT(out.data(), out.size());
+void ProcessGDBRemote::HandleAsyncStdout(llvm::StringRef out) {
+  AppendSTDOUT(out.data(), out.size());
 }
 
 static const char *end_delimiter = "--end--;";
 static const int end_delimiter_len = 8;
 
-void
-ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data)
-{
-    std::string input = data.str(); // '1' to move beyond 'A'
-    if (m_partial_profile_data.length() > 0)
-    {
-        m_partial_profile_data.append(input);
-        input = m_partial_profile_data;
-        m_partial_profile_data.clear();
-    }
+void ProcessGDBRemote::HandleAsyncMisc(llvm::StringRef data) {
+  std::string input = data.str(); // '1' to move beyond 'A'
+  if (m_partial_profile_data.length() > 0) {
+    m_partial_profile_data.append(input);
+    input = m_partial_profile_data;
+    m_partial_profile_data.clear();
+  }
 
-    size_t found, pos = 0, len = input.length();
-    while ((found = input.find(end_delimiter, pos)) != std::string::npos)
-    {
-        StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
-        std::string profile_data = HarmonizeThreadIdsForProfileData(profileDataExtractor);
-        BroadcastAsyncProfileData(profile_data);
+  size_t found, pos = 0, len = input.length();
+  while ((found = input.find(end_delimiter, pos)) != std::string::npos) {
+    StringExtractorGDBRemote profileDataExtractor(
+        input.substr(pos, found).c_str());
+    std::string profile_data =
+        HarmonizeThreadIdsForProfileData(profileDataExtractor);
+    BroadcastAsyncProfileData(profile_data);
 
-        pos = found + end_delimiter_len;
-    }
+    pos = found + end_delimiter_len;
+  }
 
-    if (pos < len)
-    {
-        // Last incomplete chunk.
-        m_partial_profile_data = input.substr(pos);
-    }
+  if (pos < len) {
+    // Last incomplete chunk.
+    m_partial_profile_data = input.substr(pos);
+  }
 }
 
-std::string
-ProcessGDBRemote::HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &profileDataExtractor)
-{
-    std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
-    std::string output;
-    llvm::raw_string_ostream output_stream(output);
-    llvm::StringRef name, value;
+std::string ProcessGDBRemote::HarmonizeThreadIdsForProfileData(
+    StringExtractorGDBRemote &profileDataExtractor) {
+  std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
+  std::string output;
+  llvm::raw_string_ostream output_stream(output);
+  llvm::StringRef name, value;
 
-    // Going to assuming thread_used_usec comes first, else bail out.
-    while (profileDataExtractor.GetNameColonValue(name, value))
-    {
-        if (name.compare("thread_used_id") == 0)
-        {
-            StringExtractor threadIDHexExtractor(value);
-            uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
+  // Going to assuming thread_used_usec comes first, else bail out.
+  while (profileDataExtractor.GetNameColonValue(name, value)) {
+    if (name.compare("thread_used_id") == 0) {
+      StringExtractor threadIDHexExtractor(value);
+      uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
 
-            bool has_used_usec = false;
-            uint32_t curr_used_usec = 0;
-            llvm::StringRef usec_name, usec_value;
-            uint32_t input_file_pos = profileDataExtractor.GetFilePos();
-            if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
-            {
-                if (usec_name.equals("thread_used_usec"))
-                {
-                    has_used_usec = true;
-                    usec_value.getAsInteger(0, curr_used_usec);
-                }
-                else
-                {
-                    // We didn't find what we want, it is probably
-                    // an older version. Bail out.
-                    profileDataExtractor.SetFilePos(input_file_pos);
-                }
-            }
-
-            if (has_used_usec)
-            {
-                uint32_t prev_used_usec = 0;
-                std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
-                if (iterator != m_thread_id_to_used_usec_map.end())
-                {
-                    prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
-                }
-
-                uint32_t real_used_usec = curr_used_usec - prev_used_usec;
-                // A good first time record is one that runs for at least 0.25 sec
-                bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
-                bool good_subsequent_time =
-                    (prev_used_usec > 0) && ((real_used_usec > 0) || (HasAssignedIndexIDToThread(thread_id)));
-
-                if (good_first_time || good_subsequent_time)
-                {
-                    // We try to avoid doing too many index id reservation,
-                    // resulting in fast increase of index ids.
-
-                    output_stream << name << ":";
-                    int32_t index_id = AssignIndexIDToThread(thread_id);
-                    output_stream << index_id << ";";
-
-                    output_stream << usec_name << ":" << usec_value << ";";
-                }
-                else
-                {
-                    // Skip past 'thread_used_name'.
-                    llvm::StringRef local_name, local_value;
-                    profileDataExtractor.GetNameColonValue(local_name, local_value);
-                }
-
-                // Store current time as previous time so that they can be compared later.
-                new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
-            }
-            else
-            {
-                // Bail out and use old string.
-                output_stream << name << ":" << value << ";";
-            }
+      bool has_used_usec = false;
+      uint32_t curr_used_usec = 0;
+      llvm::StringRef usec_name, usec_value;
+      uint32_t input_file_pos = profileDataExtractor.GetFilePos();
+      if (profileDataExtractor.GetNameColonValue(usec_name, usec_value)) {
+        if (usec_name.equals("thread_used_usec")) {
+          has_used_usec = true;
+          usec_value.getAsInteger(0, curr_used_usec);
+        } else {
+          // We didn't find what we want, it is probably
+          // an older version. Bail out.
+          profileDataExtractor.SetFilePos(input_file_pos);
         }
-        else
-        {
-            output_stream << name << ":" << value << ";";
+      }
+
+      if (has_used_usec) {
+        uint32_t prev_used_usec = 0;
+        std::map<uint64_t, uint32_t>::iterator iterator =
+            m_thread_id_to_used_usec_map.find(thread_id);
+        if (iterator != m_thread_id_to_used_usec_map.end()) {
+          prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
         }
+
+        uint32_t real_used_usec = curr_used_usec - prev_used_usec;
+        // A good first time record is one that runs for at least 0.25 sec
+        bool good_first_time =
+            (prev_used_usec == 0) && (real_used_usec > 250000);
+        bool good_subsequent_time =
+            (prev_used_usec > 0) &&
+            ((real_used_usec > 0) || (HasAssignedIndexIDToThread(thread_id)));
+
+        if (good_first_time || good_subsequent_time) {
+          // We try to avoid doing too many index id reservation,
+          // resulting in fast increase of index ids.
+
+          output_stream << name << ":";
+          int32_t index_id = AssignIndexIDToThread(thread_id);
+          output_stream << index_id << ";";
+
+          output_stream << usec_name << ":" << usec_value << ";";
+        } else {
+          // Skip past 'thread_used_name'.
+          llvm::StringRef local_name, local_value;
+          profileDataExtractor.GetNameColonValue(local_name, local_value);
+        }
+
+        // Store current time as previous time so that they can be compared
+        // later.
+        new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
+      } else {
+        // Bail out and use old string.
+        output_stream << name << ":" << value << ";";
+      }
+    } else {
+      output_stream << name << ":" << value << ";";
     }
-    output_stream << end_delimiter;
-    m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
+  }
+  output_stream << end_delimiter;
+  m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
 
-    return output_stream.str();
+  return output_stream.str();
 }
 
-void
-ProcessGDBRemote::HandleStopReply()
-{
-    if (GetStopID() != 0)
-        return;
+void ProcessGDBRemote::HandleStopReply() {
+  if (GetStopID() != 0)
+    return;
 
-    if (GetID() == LLDB_INVALID_PROCESS_ID)
-    {
-        lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
-        if (pid != LLDB_INVALID_PROCESS_ID)
-            SetID(pid);
-    }
-    BuildDynamicRegisterInfo(true);
+  if (GetID() == LLDB_INVALID_PROCESS_ID) {
+    lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID();
+    if (pid != LLDB_INVALID_PROCESS_ID)
+      SetID(pid);
+  }
+  BuildDynamicRegisterInfo(true);
 }
 
-bool
-ProcessGDBRemote::HandleAsyncStructuredData(const StructuredData::ObjectSP
-                                            &object_sp)
-{
-    return RouteAsyncStructuredData(object_sp);
+bool ProcessGDBRemote::HandleAsyncStructuredData(
+    const StructuredData::ObjectSP &object_sp) {
+  return RouteAsyncStructuredData(object_sp);
 }
 
-class CommandObjectProcessGDBRemoteSpeedTest: public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed {
 public:
-    CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter,
-                             "process plugin packet speed-test",
-                             "Tests packet speeds of various sizes to determine the performance characteristics of the GDB remote connection. ",
-                             NULL),
-        m_option_group (),
-        m_num_packets (LLDB_OPT_SET_1, false, "count",       'c', 0, eArgTypeCount, "The number of packets to send of each varying size (default is 1000).", 1000),
-        m_max_send    (LLDB_OPT_SET_1, false, "max-send",    's', 0, eArgTypeCount, "The maximum number of bytes to send in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
-        m_max_recv    (LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount, "The maximum number of bytes to receive in a packet. Sizes increase in powers of 2 while the size is less than or equal to this option value. (default 1024).", 1024),
-        m_json        (LLDB_OPT_SET_1, false, "json",        'j', "Print the output as JSON data for easy parsing.", false, true)
-    {
-        m_option_group.Append (&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
-        m_option_group.Append (&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
-        m_option_group.Append (&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
-        m_option_group.Append (&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
-        m_option_group.Finalize();
-    }
+  CommandObjectProcessGDBRemoteSpeedTest(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "process plugin packet speed-test",
+                            "Tests packet speeds of various sizes to determine "
+                            "the performance characteristics of the GDB remote "
+                            "connection. ",
+                            NULL),
+        m_option_group(),
+        m_num_packets(LLDB_OPT_SET_1, false, "count", 'c', 0, eArgTypeCount,
+                      "The number of packets to send of each varying size "
+                      "(default is 1000).",
+                      1000),
+        m_max_send(LLDB_OPT_SET_1, false, "max-send", 's', 0, eArgTypeCount,
+                   "The maximum number of bytes to send in a packet. Sizes "
+                   "increase in powers of 2 while the size is less than or "
+                   "equal to this option value. (default 1024).",
+                   1024),
+        m_max_recv(LLDB_OPT_SET_1, false, "max-receive", 'r', 0, eArgTypeCount,
+                   "The maximum number of bytes to receive in a packet. Sizes "
+                   "increase in powers of 2 while the size is less than or "
+                   "equal to this option value. (default 1024).",
+                   1024),
+        m_json(LLDB_OPT_SET_1, false, "json", 'j',
+               "Print the output as JSON data for easy parsing.", false, true) {
+    m_option_group.Append(&m_num_packets, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    m_option_group.Append(&m_max_send, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    m_option_group.Append(&m_max_recv, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    m_option_group.Append(&m_json, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    m_option_group.Finalize();
+  }
 
-    ~CommandObjectProcessGDBRemoteSpeedTest ()
-    {
-    }
+  ~CommandObjectProcessGDBRemoteSpeedTest() {}
 
+  Options *GetOptions() override { return &m_option_group; }
 
-    Options *
-    GetOptions () override
-    {
-        return &m_option_group;
-    }
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    const size_t argc = command.GetArgumentCount();
+    if (argc == 0) {
+      ProcessGDBRemote *process =
+          (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
+              .GetProcessPtr();
+      if (process) {
+        StreamSP output_stream_sp(
+            m_interpreter.GetDebugger().GetAsyncOutputStream());
+        result.SetImmediateOutputStream(output_stream_sp);
 
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
-    {
-        const size_t argc = command.GetArgumentCount();
-        if (argc == 0)
-        {
-            ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
-            if (process)
-            {
-                StreamSP output_stream_sp (m_interpreter.GetDebugger().GetAsyncOutputStream());
-                result.SetImmediateOutputStream (output_stream_sp);
-
-                const uint32_t num_packets = (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
-                const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
-                const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
-                const bool json = m_json.GetOptionValue().GetCurrentValue();
-                if (output_stream_sp)
-                    process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, *output_stream_sp);
-                else
-                {
-                    process->GetGDBRemote().TestPacketSpeed (num_packets, max_send, max_recv, json, result.GetOutputStream());
-                }
-                result.SetStatus (eReturnStatusSuccessFinishResult);
-                return true;
-            }
+        const uint32_t num_packets =
+            (uint32_t)m_num_packets.GetOptionValue().GetCurrentValue();
+        const uint64_t max_send = m_max_send.GetOptionValue().GetCurrentValue();
+        const uint64_t max_recv = m_max_recv.GetOptionValue().GetCurrentValue();
+        const bool json = m_json.GetOptionValue().GetCurrentValue();
+        if (output_stream_sp)
+          process->GetGDBRemote().TestPacketSpeed(
+              num_packets, max_send, max_recv, json, *output_stream_sp);
+        else {
+          process->GetGDBRemote().TestPacketSpeed(
+              num_packets, max_send, max_recv, json, result.GetOutputStream());
         }
-        else
-        {
-            result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
-        }
-        result.SetStatus (eReturnStatusFailed);
-        return false;
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return true;
+      }
+    } else {
+      result.AppendErrorWithFormat("'%s' takes no arguments",
+                                   m_cmd_name.c_str());
     }
+    result.SetStatus(eReturnStatusFailed);
+    return false;
+  }
+
 protected:
-    OptionGroupOptions m_option_group;
-    OptionGroupUInt64 m_num_packets;
-    OptionGroupUInt64 m_max_send;
-    OptionGroupUInt64 m_max_recv;
-    OptionGroupBoolean m_json;
-
+  OptionGroupOptions m_option_group;
+  OptionGroupUInt64 m_num_packets;
+  OptionGroupUInt64 m_max_send;
+  OptionGroupUInt64 m_max_recv;
+  OptionGroupBoolean m_json;
 };
 
-class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed {
 private:
-
 public:
-    CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter) :
-    CommandObjectParsed (interpreter,
-                         "process plugin packet history",
-                         "Dumps the packet history buffer. ",
-                         NULL)
-    {
+  CommandObjectProcessGDBRemotePacketHistory(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "process plugin packet history",
+                            "Dumps the packet history buffer. ", NULL) {}
+
+  ~CommandObjectProcessGDBRemotePacketHistory() {}
+
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    const size_t argc = command.GetArgumentCount();
+    if (argc == 0) {
+      ProcessGDBRemote *process =
+          (ProcessGDBRemote *)m_interpreter.GetExecutionContext()
+              .GetProcessPtr();
+      if (process) {
+        process->GetGDBRemote().DumpHistory(result.GetOutputStream());
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return true;
+      }
+    } else {
+      result.AppendErrorWithFormat("'%s' takes no arguments",
+                                   m_cmd_name.c_str());
+    }
+    result.SetStatus(eReturnStatusFailed);
+    return false;
+  }
+};
+
+class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed {
+private:
+public:
+  CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter)
+      : CommandObjectParsed(
+            interpreter, "process plugin packet xfer-size",
+            "Maximum size that lldb will try to read/write one one chunk.",
+            NULL) {}
+
+  ~CommandObjectProcessGDBRemotePacketXferSize() {}
+
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    const size_t argc = command.GetArgumentCount();
+    if (argc == 0) {
+      result.AppendErrorWithFormat("'%s' takes an argument to specify the max "
+                                   "amount to be transferred when "
+                                   "reading/writing",
+                                   m_cmd_name.c_str());
+      result.SetStatus(eReturnStatusFailed);
+      return false;
     }
 
-    ~CommandObjectProcessGDBRemotePacketHistory ()
-    {
+    ProcessGDBRemote *process =
+        (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+    if (process) {
+      const char *packet_size = command.GetArgumentAtIndex(0);
+      errno = 0;
+      uint64_t user_specified_max = strtoul(packet_size, NULL, 10);
+      if (errno == 0 && user_specified_max != 0) {
+        process->SetUserSpecifiedMaxMemoryTransferSize(user_specified_max);
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return true;
+      }
+    }
+    result.SetStatus(eReturnStatusFailed);
+    return false;
+  }
+};
+
+class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed {
+private:
+public:
+  CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "process plugin packet send",
+                            "Send a custom packet through the GDB remote "
+                            "protocol and print the answer. "
+                            "The packet header and footer will automatically "
+                            "be added to the packet prior to sending and "
+                            "stripped from the result.",
+                            NULL) {}
+
+  ~CommandObjectProcessGDBRemotePacketSend() {}
+
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    const size_t argc = command.GetArgumentCount();
+    if (argc == 0) {
+      result.AppendErrorWithFormat(
+          "'%s' takes a one or more packet content arguments",
+          m_cmd_name.c_str());
+      result.SetStatus(eReturnStatusFailed);
+      return false;
     }
 
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
-    {
-        const size_t argc = command.GetArgumentCount();
-        if (argc == 0)
-        {
-            ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
-            if (process)
-            {
-                process->GetGDBRemote().DumpHistory(result.GetOutputStream());
-                result.SetStatus (eReturnStatusSuccessFinishResult);
-                return true;
-            }
+    ProcessGDBRemote *process =
+        (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+    if (process) {
+      for (size_t i = 0; i < argc; ++i) {
+        const char *packet_cstr = command.GetArgumentAtIndex(0);
+        bool send_async = true;
+        StringExtractorGDBRemote response;
+        process->GetGDBRemote().SendPacketAndWaitForResponse(
+            packet_cstr, response, send_async);
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        Stream &output_strm = result.GetOutputStream();
+        output_strm.Printf("  packet: %s\n", packet_cstr);
+        std::string &response_str = response.GetStringRef();
+
+        if (strstr(packet_cstr, "qGetProfileData") != NULL) {
+          response_str = process->HarmonizeThreadIdsForProfileData(response);
         }
+
+        if (response_str.empty())
+          output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
         else
-        {
-            result.AppendErrorWithFormat ("'%s' takes no arguments", m_cmd_name.c_str());
-        }
-        result.SetStatus (eReturnStatusFailed);
-        return false;
+          output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
+      }
     }
+    return true;
+  }
 };
 
-class CommandObjectProcessGDBRemotePacketXferSize : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw {
 private:
-
 public:
-    CommandObjectProcessGDBRemotePacketXferSize(CommandInterpreter &interpreter) :
-    CommandObjectParsed (interpreter,
-                         "process plugin packet xfer-size",
-                         "Maximum size that lldb will try to read/write one one chunk.",
-                         NULL)
-    {
+  CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter)
+      : CommandObjectRaw(interpreter, "process plugin packet monitor",
+                         "Send a qRcmd packet through the GDB remote protocol "
+                         "and print the response."
+                         "The argument passed to this command will be hex "
+                         "encoded into a valid 'qRcmd' packet, sent and the "
+                         "response will be printed.",
+                         NULL) {}
+
+  ~CommandObjectProcessGDBRemotePacketMonitor() {}
+
+  bool DoExecute(const char *command, CommandReturnObject &result) override {
+    if (command == NULL || command[0] == '\0') {
+      result.AppendErrorWithFormat("'%s' takes a command string argument",
+                                   m_cmd_name.c_str());
+      result.SetStatus(eReturnStatusFailed);
+      return false;
     }
 
-    ~CommandObjectProcessGDBRemotePacketXferSize ()
-    {
-    }
+    ProcessGDBRemote *process =
+        (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+    if (process) {
+      StreamString packet;
+      packet.PutCString("qRcmd,");
+      packet.PutBytesAsRawHex8(command, strlen(command));
+      const char *packet_cstr = packet.GetString().c_str();
 
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
-    {
-        const size_t argc = command.GetArgumentCount();
-        if (argc == 0)
-        {
-            result.AppendErrorWithFormat ("'%s' takes an argument to specify the max amount to be transferred when reading/writing", m_cmd_name.c_str());
-            result.SetStatus (eReturnStatusFailed);
-            return false;
-        }
+      bool send_async = true;
+      StringExtractorGDBRemote response;
+      process->GetGDBRemote().SendPacketAndWaitForResponse(
+          packet_cstr, response, send_async);
+      result.SetStatus(eReturnStatusSuccessFinishResult);
+      Stream &output_strm = result.GetOutputStream();
+      output_strm.Printf("  packet: %s\n", packet_cstr);
+      const std::string &response_str = response.GetStringRef();
 
-        ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
-        if (process)
-        {
-            const char *packet_size = command.GetArgumentAtIndex(0);
-            errno = 0;
-            uint64_t user_specified_max = strtoul (packet_size, NULL, 10);
-            if (errno == 0 && user_specified_max != 0)
-            {
-                process->SetUserSpecifiedMaxMemoryTransferSize (user_specified_max);
-                result.SetStatus (eReturnStatusSuccessFinishResult);
-                return true;
-            }
-        }
-        result.SetStatus (eReturnStatusFailed);
-        return false;
+      if (response_str.empty())
+        output_strm.PutCString("response: \nerror: UNIMPLEMENTED\n");
+      else
+        output_strm.Printf("response: %s\n", response.GetStringRef().c_str());
     }
+    return true;
+  }
 };
 
-
-class CommandObjectProcessGDBRemotePacketSend : public CommandObjectParsed
-{
+class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword {
 private:
-
 public:
-    CommandObjectProcessGDBRemotePacketSend(CommandInterpreter &interpreter) :
-        CommandObjectParsed (interpreter,
-                             "process plugin packet send",
-                             "Send a custom packet through the GDB remote protocol and print the answer. "
-                             "The packet header and footer will automatically be added to the packet prior to sending and stripped from the result.",
-                             NULL)
-    {
-    }
+  CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter)
+      : CommandObjectMultiword(interpreter, "process plugin packet",
+                               "Commands that deal with GDB remote packets.",
+                               NULL) {
+    LoadSubCommand(
+        "history",
+        CommandObjectSP(
+            new CommandObjectProcessGDBRemotePacketHistory(interpreter)));
+    LoadSubCommand(
+        "send", CommandObjectSP(
+                    new CommandObjectProcessGDBRemotePacketSend(interpreter)));
+    LoadSubCommand(
+        "monitor",
+        CommandObjectSP(
+            new CommandObjectProcessGDBRemotePacketMonitor(interpreter)));
+    LoadSubCommand(
+        "xfer-size",
+        CommandObjectSP(
+            new CommandObjectProcessGDBRemotePacketXferSize(interpreter)));
+    LoadSubCommand("speed-test",
+                   CommandObjectSP(new CommandObjectProcessGDBRemoteSpeedTest(
+                       interpreter)));
+  }
 
-    ~CommandObjectProcessGDBRemotePacketSend ()
-    {
-    }
-
-    bool
-    DoExecute (Args& command, CommandReturnObject &result) override
-    {
-        const size_t argc = command.GetArgumentCount();
-        if (argc == 0)
-        {
-            result.AppendErrorWithFormat ("'%s' takes a one or more packet content arguments", m_cmd_name.c_str());
-            result.SetStatus (eReturnStatusFailed);
-            return false;
-        }
-
-        ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
-        if (process)
-        {
-            for (size_t i=0; i<argc; ++ i)
-            {
-                const char *packet_cstr = command.GetArgumentAtIndex(0);
-                bool send_async = true;
-                StringExtractorGDBRemote response;
-                process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
-                result.SetStatus (eReturnStatusSuccessFinishResult);
-                Stream &output_strm = result.GetOutputStream();
-                output_strm.Printf ("  packet: %s\n", packet_cstr);
-                std::string &response_str = response.GetStringRef();
-
-                if (strstr(packet_cstr, "qGetProfileData") != NULL)
-                {
-                    response_str = process->HarmonizeThreadIdsForProfileData(response);
-                }
-
-                if (response_str.empty())
-                    output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
-                else
-                    output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
-            }
-        }
-        return true;
-    }
+  ~CommandObjectProcessGDBRemotePacket() {}
 };
 
-class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw
-{
-private:
-
+class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword {
 public:
-    CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter) :
-        CommandObjectRaw (interpreter,
-                         "process plugin packet monitor",
-                         "Send a qRcmd packet through the GDB remote protocol and print the response."
-                         "The argument passed to this command will be hex encoded into a valid 'qRcmd' packet, sent and the response will be printed.",
-                         NULL)
-    {
-    }
+  CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
+      : CommandObjectMultiword(
+            interpreter, "process plugin",
+            "Commands for operating on a ProcessGDBRemote process.",
+            "process plugin <subcommand> [<subcommand-options>]") {
+    LoadSubCommand(
+        "packet",
+        CommandObjectSP(new CommandObjectProcessGDBRemotePacket(interpreter)));
+  }
 
-    ~CommandObjectProcessGDBRemotePacketMonitor ()
-    {
-    }
-
-    bool
-    DoExecute (const char *command, CommandReturnObject &result) override
-    {
-        if (command == NULL || command[0] == '\0')
-        {
-            result.AppendErrorWithFormat ("'%s' takes a command string argument", m_cmd_name.c_str());
-            result.SetStatus (eReturnStatusFailed);
-            return false;
-        }
-
-        ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
-        if (process)
-        {
-            StreamString packet;
-            packet.PutCString("qRcmd,");
-            packet.PutBytesAsRawHex8(command, strlen(command));
-            const char *packet_cstr = packet.GetString().c_str();
-
-            bool send_async = true;
-            StringExtractorGDBRemote response;
-            process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
-            result.SetStatus (eReturnStatusSuccessFinishResult);
-            Stream &output_strm = result.GetOutputStream();
-            output_strm.Printf ("  packet: %s\n", packet_cstr);
-            const std::string &response_str = response.GetStringRef();
-
-            if (response_str.empty())
-                output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
-            else
-                output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
-        }
-        return true;
-    }
+  ~CommandObjectMultiwordProcessGDBRemote() {}
 };
 
-class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword
-{
-private:
-
-public:
-    CommandObjectProcessGDBRemotePacket(CommandInterpreter &interpreter) :
-        CommandObjectMultiword (interpreter,
-                                "process plugin packet",
-                                "Commands that deal with GDB remote packets.",
-                                NULL)
-    {
-        LoadSubCommand ("history", CommandObjectSP (new CommandObjectProcessGDBRemotePacketHistory (interpreter)));
-        LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
-        LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
-        LoadSubCommand ("xfer-size", CommandObjectSP (new CommandObjectProcessGDBRemotePacketXferSize (interpreter)));
-        LoadSubCommand ("speed-test", CommandObjectSP (new CommandObjectProcessGDBRemoteSpeedTest (interpreter)));
-    }
-
-    ~CommandObjectProcessGDBRemotePacket ()
-    {
-    }
-};
-
-class CommandObjectMultiwordProcessGDBRemote : public CommandObjectMultiword
-{
-public:
-    CommandObjectMultiwordProcessGDBRemote(CommandInterpreter &interpreter)
-        : CommandObjectMultiword(interpreter, "process plugin", "Commands for operating on a ProcessGDBRemote process.",
-                                 "process plugin <subcommand> [<subcommand-options>]")
-    {
-        LoadSubCommand ("packet", CommandObjectSP (new CommandObjectProcessGDBRemotePacket    (interpreter)));
-    }
-
-    ~CommandObjectMultiwordProcessGDBRemote ()
-    {
-    }
-};
-
-CommandObject *
-ProcessGDBRemote::GetPluginCommandObject()
-{
-    if (!m_command_sp)
-        m_command_sp.reset (new CommandObjectMultiwordProcessGDBRemote (GetTarget().GetDebugger().GetCommandInterpreter()));
-    return m_command_sp.get();
+CommandObject *ProcessGDBRemote::GetPluginCommandObject() {
+  if (!m_command_sp)
+    m_command_sp.reset(new CommandObjectMultiwordProcessGDBRemote(
+        GetTarget().GetDebugger().GetCommandInterpreter()));
+  return m_command_sp.get();
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 3a0dd2f..f2a58db 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -24,16 +24,16 @@
 #include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
+#include "lldb/Core/LoadedModuleInfoList.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/StringList.h"
 #include "lldb/Core/StructuredData.h"
 #include "lldb/Core/ThreadSafeValue.h"
-#include "lldb/Core/LoadedModuleInfoList.h"
 #include "lldb/Host/HostThread.h"
-#include "lldb/lldb-private-forward.h"
-#include "lldb/Utility/StringExtractor.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Utility/StringExtractor.h"
+#include "lldb/lldb-private-forward.h"
 
 #include "GDBRemoteCommunicationClient.h"
 #include "GDBRemoteRegisterContext.h"
@@ -43,478 +43,376 @@
 
 class ThreadGDBRemote;
 
-class ProcessGDBRemote : public Process, private GDBRemoteClientBase::ContinueDelegate
-{
+class ProcessGDBRemote : public Process,
+                         private GDBRemoteClientBase::ContinueDelegate {
 public:
-    ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
+  ProcessGDBRemote(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
 
-    ~ProcessGDBRemote() override;
+  ~ProcessGDBRemote() override;
 
-    static lldb::ProcessSP
-    CreateInstance (lldb::TargetSP target_sp,
-                    lldb::ListenerSP listener_sp,
-                    const FileSpec *crash_file_path);
+  static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
+                                        lldb::ListenerSP listener_sp,
+                                        const FileSpec *crash_file_path);
 
-    static void
-    Initialize();
+  static void Initialize();
 
-    static void
-    DebuggerInitialize (Debugger &debugger);
+  static void DebuggerInitialize(Debugger &debugger);
 
-    static void
-    Terminate();
+  static void Terminate();
 
-    static ConstString
-    GetPluginNameStatic();
+  static ConstString GetPluginNameStatic();
 
-    static const char *
-    GetPluginDescriptionStatic();
+  static const char *GetPluginDescriptionStatic();
 
-    //------------------------------------------------------------------
-    // Check if a given Process
-    //------------------------------------------------------------------
-    bool
-    CanDebug (lldb::TargetSP target_sp, bool plugin_specified_by_name) override;
+  //------------------------------------------------------------------
+  // Check if a given Process
+  //------------------------------------------------------------------
+  bool CanDebug(lldb::TargetSP target_sp,
+                bool plugin_specified_by_name) override;
 
-    CommandObject *
-    GetPluginCommandObject() override;
+  CommandObject *GetPluginCommandObject() override;
 
-    //------------------------------------------------------------------
-    // Creating a new process, or attaching to an existing one
-    //------------------------------------------------------------------
-    Error
-    WillLaunch (Module* module) override;
+  //------------------------------------------------------------------
+  // Creating a new process, or attaching to an existing one
+  //------------------------------------------------------------------
+  Error WillLaunch(Module *module) override;
 
-    Error
-    DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info) override;
+  Error DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
 
-    void
-    DidLaunch () override;
+  void DidLaunch() override;
 
-    Error
-    WillAttachToProcessWithID (lldb::pid_t pid) override;
+  Error WillAttachToProcessWithID(lldb::pid_t pid) override;
 
-    Error
-    WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) override;
+  Error WillAttachToProcessWithName(const char *process_name,
+                                    bool wait_for_launch) override;
 
-    Error
-    DoConnectRemote (Stream *strm, const char *remote_url) override;
-    
-    Error
-    WillLaunchOrAttach ();
-    
-    Error
-    DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) override;
-    
-    Error
-    DoAttachToProcessWithName (const char *process_name,
-                               const ProcessAttachInfo &attach_info) override;
+  Error DoConnectRemote(Stream *strm, const char *remote_url) override;
 
-    void
-    DidAttach (ArchSpec &process_arch) override;
+  Error WillLaunchOrAttach();
 
-    //------------------------------------------------------------------
-    // PluginInterface protocol
-    //------------------------------------------------------------------
-    ConstString
-    GetPluginName() override;
+  Error DoAttachToProcessWithID(lldb::pid_t pid,
+                                const ProcessAttachInfo &attach_info) override;
 
-    uint32_t
-    GetPluginVersion() override;
+  Error
+  DoAttachToProcessWithName(const char *process_name,
+                            const ProcessAttachInfo &attach_info) override;
 
-    //------------------------------------------------------------------
-    // Process Control
-    //------------------------------------------------------------------
-    Error
-    WillResume () override;
+  void DidAttach(ArchSpec &process_arch) override;
 
-    Error
-    DoResume () override;
+  //------------------------------------------------------------------
+  // PluginInterface protocol
+  //------------------------------------------------------------------
+  ConstString GetPluginName() override;
 
-    Error
-    DoHalt (bool &caused_stop) override;
+  uint32_t GetPluginVersion() override;
 
-    Error
-    DoDetach (bool keep_stopped) override;
-    
-    bool
-    DetachRequiresHalt() override { return true; }
+  //------------------------------------------------------------------
+  // Process Control
+  //------------------------------------------------------------------
+  Error WillResume() override;
 
-    Error
-    DoSignal (int signal) override;
+  Error DoResume() override;
 
-    Error
-    DoDestroy () override;
+  Error DoHalt(bool &caused_stop) override;
 
-    void
-    RefreshStateAfterStop() override;
+  Error DoDetach(bool keep_stopped) override;
 
-    void
-    SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
+  bool DetachRequiresHalt() override { return true; }
 
-    //------------------------------------------------------------------
-    // Process Queries
-    //------------------------------------------------------------------
-    bool
-    IsAlive () override;
+  Error DoSignal(int signal) override;
 
-    lldb::addr_t
-    GetImageInfoAddress() override;
+  Error DoDestroy() override;
 
-    void
-    WillPublicStop () override;
+  void RefreshStateAfterStop() override;
 
-    //------------------------------------------------------------------
-    // Process Memory
-    //------------------------------------------------------------------
-    size_t
-    DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error) override;
+  void SetUnixSignals(const lldb::UnixSignalsSP &signals_sp);
 
-    size_t
-    DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, Error &error) override;
+  //------------------------------------------------------------------
+  // Process Queries
+  //------------------------------------------------------------------
+  bool IsAlive() override;
 
-    lldb::addr_t
-    DoAllocateMemory (size_t size, uint32_t permissions, Error &error) override;
+  lldb::addr_t GetImageInfoAddress() override;
 
-    Error
-    GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &region_info) override;
-    
-    Error
-    DoDeallocateMemory (lldb::addr_t ptr) override;
+  void WillPublicStop() override;
 
-    //------------------------------------------------------------------
-    // Process STDIO
-    //------------------------------------------------------------------
-    size_t
-    PutSTDIN (const char *buf, size_t buf_size, Error &error) override;
+  //------------------------------------------------------------------
+  // Process Memory
+  //------------------------------------------------------------------
+  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+                      Error &error) override;
 
-    //----------------------------------------------------------------------
-    // Process Breakpoints
-    //----------------------------------------------------------------------
-    Error
-    EnableBreakpointSite (BreakpointSite *bp_site) override;
+  size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
+                       Error &error) override;
 
-    Error
-    DisableBreakpointSite (BreakpointSite *bp_site) override;
+  lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
+                                Error &error) override;
 
-    //----------------------------------------------------------------------
-    // Process Watchpoints
-    //----------------------------------------------------------------------
-    Error
-    EnableWatchpoint (Watchpoint *wp, bool notify = true) override;
+  Error GetMemoryRegionInfo(lldb::addr_t load_addr,
+                            MemoryRegionInfo &region_info) override;
 
-    Error
-    DisableWatchpoint (Watchpoint *wp, bool notify = true) override;
+  Error DoDeallocateMemory(lldb::addr_t ptr) override;
 
-    Error
-    GetWatchpointSupportInfo (uint32_t &num) override;
-    
-    Error
-    GetWatchpointSupportInfo (uint32_t &num, bool& after) override;
-    
-    bool
-    StartNoticingNewThreads() override;
+  //------------------------------------------------------------------
+  // Process STDIO
+  //------------------------------------------------------------------
+  size_t PutSTDIN(const char *buf, size_t buf_size, Error &error) override;
 
-    bool
-    StopNoticingNewThreads() override;
+  //----------------------------------------------------------------------
+  // Process Breakpoints
+  //----------------------------------------------------------------------
+  Error EnableBreakpointSite(BreakpointSite *bp_site) override;
 
-    GDBRemoteCommunicationClient &
-    GetGDBRemote()
-    {
-        return m_gdb_comm;
-    }
-    
-    Error
-    SendEventData(const char *data) override;
+  Error DisableBreakpointSite(BreakpointSite *bp_site) override;
 
-    //----------------------------------------------------------------------
-    // Override DidExit so we can disconnect from the remote GDB server
-    //----------------------------------------------------------------------
-    void
-    DidExit () override;
+  //----------------------------------------------------------------------
+  // Process Watchpoints
+  //----------------------------------------------------------------------
+  Error EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
 
-    void
-    SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);
+  Error DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
 
-    bool
-    GetModuleSpec(const FileSpec& module_file_spec,
-                  const ArchSpec& arch,
-                  ModuleSpec &module_spec) override;
+  Error GetWatchpointSupportInfo(uint32_t &num) override;
 
-    bool
-    GetHostOSVersion(uint32_t &major,
-                     uint32_t &minor,
-                     uint32_t &update) override;
+  Error GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
 
-    size_t
-    LoadModules(LoadedModuleInfoList &module_list) override;
+  bool StartNoticingNewThreads() override;
 
-    size_t
-    LoadModules() override;
+  bool StopNoticingNewThreads() override;
 
-    Error
-    GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr) override;
+  GDBRemoteCommunicationClient &GetGDBRemote() { return m_gdb_comm; }
 
-    void
-    ModulesDidLoad (ModuleList &module_list) override;
+  Error SendEventData(const char *data) override;
 
-    StructuredData::ObjectSP
-    GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override;
+  //----------------------------------------------------------------------
+  // Override DidExit so we can disconnect from the remote GDB server
+  //----------------------------------------------------------------------
+  void DidExit() override;
 
-    Error
-    ConfigureStructuredData(const ConstString &type_name,
-                            const StructuredData::ObjectSP &config_sp) override;
+  void SetUserSpecifiedMaxMemoryTransferSize(uint64_t user_specified_max);
 
-    StructuredData::ObjectSP
-    GetLoadedDynamicLibrariesInfos () override;
+  bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
+                     ModuleSpec &module_spec) override;
 
-    StructuredData::ObjectSP
-    GetLoadedDynamicLibrariesInfos (const std::vector<lldb::addr_t> &load_addresses) override;
+  bool GetHostOSVersion(uint32_t &major, uint32_t &minor,
+                        uint32_t &update) override;
 
-    StructuredData::ObjectSP
-    GetLoadedDynamicLibrariesInfos_sender (StructuredData::ObjectSP args);
+  size_t LoadModules(LoadedModuleInfoList &module_list) override;
 
-    StructuredData::ObjectSP
-    GetSharedCacheInfo () override;
+  size_t LoadModules() override;
 
-    std::string
-    HarmonizeThreadIdsForProfileData(StringExtractorGDBRemote &inputStringExtractor);
+  Error GetFileLoadAddress(const FileSpec &file, bool &is_loaded,
+                           lldb::addr_t &load_addr) override;
+
+  void ModulesDidLoad(ModuleList &module_list) override;
+
+  StructuredData::ObjectSP
+  GetLoadedDynamicLibrariesInfos(lldb::addr_t image_list_address,
+                                 lldb::addr_t image_count) override;
+
+  Error
+  ConfigureStructuredData(const ConstString &type_name,
+                          const StructuredData::ObjectSP &config_sp) override;
+
+  StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override;
+
+  StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos(
+      const std::vector<lldb::addr_t> &load_addresses) override;
+
+  StructuredData::ObjectSP
+  GetLoadedDynamicLibrariesInfos_sender(StructuredData::ObjectSP args);
+
+  StructuredData::ObjectSP GetSharedCacheInfo() override;
+
+  std::string HarmonizeThreadIdsForProfileData(
+      StringExtractorGDBRemote &inputStringExtractor);
 
 protected:
-    friend class ThreadGDBRemote;
-    friend class GDBRemoteCommunicationClient;
-    friend class GDBRemoteRegisterContext;
+  friend class ThreadGDBRemote;
+  friend class GDBRemoteCommunicationClient;
+  friend class GDBRemoteRegisterContext;
 
-    //------------------------------------------------------------------
-    /// Broadcaster event bits definitions.
-    //------------------------------------------------------------------
-    enum
-    {
-        eBroadcastBitAsyncContinue                  = (1 << 0),
-        eBroadcastBitAsyncThreadShouldExit          = (1 << 1),
-        eBroadcastBitAsyncThreadDidExit             = (1 << 2)
-    };
-    
-    Flags m_flags;            // Process specific flags (see eFlags enums)
-    GDBRemoteCommunicationClient m_gdb_comm;
-    std::atomic<lldb::pid_t> m_debugserver_pid;
-    std::vector<StringExtractorGDBRemote> m_stop_packet_stack;  // The stop packet stack replaces the last stop packet variable
-    std::recursive_mutex m_last_stop_packet_mutex;
-    GDBRemoteDynamicRegisterInfo m_register_info;
-    Broadcaster m_async_broadcaster;
-    lldb::ListenerSP m_async_listener_sp;
-    HostThread m_async_thread;
-    std::recursive_mutex m_async_thread_state_mutex;
-    typedef std::vector<lldb::tid_t> tid_collection;
-    typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
-    typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
-    typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
-    tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping
-    std::vector<lldb::addr_t> m_thread_pcs; // PC values for all the threads.
-    StructuredData::ObjectSP m_jstopinfo_sp; // Stop info only for any threads that have valid stop infos
-    StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited registers and memory for all threads if "jThreadsInfo" packet is supported
-    tid_collection m_continue_c_tids;                  // 'c' for continue
-    tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
-    tid_collection m_continue_s_tids;                  // 's' for step
-    tid_sig_collection m_continue_S_tids; // 'S' for step with signal
-    uint64_t m_max_memory_size;       // The maximum number of bytes to read/write when reading and writing memory
-    uint64_t m_remote_stub_max_memory_size;    // The maximum memory size the remote gdb stub can handle
-    MMapMap m_addr_to_mmap_size;
-    lldb::BreakpointSP m_thread_create_bp_sp;
-    bool m_waiting_for_attach;
-    bool m_destroy_tried_resuming;
-    lldb::CommandObjectSP m_command_sp;
-    int64_t m_breakpoint_pc_offset;
-    lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
+  //------------------------------------------------------------------
+  /// Broadcaster event bits definitions.
+  //------------------------------------------------------------------
+  enum {
+    eBroadcastBitAsyncContinue = (1 << 0),
+    eBroadcastBitAsyncThreadShouldExit = (1 << 1),
+    eBroadcastBitAsyncThreadDidExit = (1 << 2)
+  };
 
-    //----------------------------------------------------------------------
-    // Accessors
-    //----------------------------------------------------------------------
-    bool
-    IsRunning ( lldb::StateType state )
-    {
-        return state == lldb::eStateRunning || IsStepping(state);
-    }
+  Flags m_flags; // Process specific flags (see eFlags enums)
+  GDBRemoteCommunicationClient m_gdb_comm;
+  std::atomic<lldb::pid_t> m_debugserver_pid;
+  std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet
+                                                             // stack replaces
+                                                             // the last stop
+                                                             // packet variable
+  std::recursive_mutex m_last_stop_packet_mutex;
+  GDBRemoteDynamicRegisterInfo m_register_info;
+  Broadcaster m_async_broadcaster;
+  lldb::ListenerSP m_async_listener_sp;
+  HostThread m_async_thread;
+  std::recursive_mutex m_async_thread_state_mutex;
+  typedef std::vector<lldb::tid_t> tid_collection;
+  typedef std::vector<std::pair<lldb::tid_t, int>> tid_sig_collection;
+  typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+  typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
+  tid_collection m_thread_ids; // Thread IDs for all threads. This list gets
+                               // updated after stopping
+  std::vector<lldb::addr_t> m_thread_pcs;     // PC values for all the threads.
+  StructuredData::ObjectSP m_jstopinfo_sp;    // Stop info only for any threads
+                                              // that have valid stop infos
+  StructuredData::ObjectSP m_jthreadsinfo_sp; // Full stop info, expedited
+                                              // registers and memory for all
+                                              // threads if "jThreadsInfo"
+                                              // packet is supported
+  tid_collection m_continue_c_tids;           // 'c' for continue
+  tid_sig_collection m_continue_C_tids;       // 'C' for continue with signal
+  tid_collection m_continue_s_tids;           // 's' for step
+  tid_sig_collection m_continue_S_tids;       // 'S' for step with signal
+  uint64_t m_max_memory_size; // The maximum number of bytes to read/write when
+                              // reading and writing memory
+  uint64_t m_remote_stub_max_memory_size; // The maximum memory size the remote
+                                          // gdb stub can handle
+  MMapMap m_addr_to_mmap_size;
+  lldb::BreakpointSP m_thread_create_bp_sp;
+  bool m_waiting_for_attach;
+  bool m_destroy_tried_resuming;
+  lldb::CommandObjectSP m_command_sp;
+  int64_t m_breakpoint_pc_offset;
+  lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach
 
-    bool
-    IsStepping ( lldb::StateType state)
-    {
-        return state == lldb::eStateStepping;
-    }
+  //----------------------------------------------------------------------
+  // Accessors
+  //----------------------------------------------------------------------
+  bool IsRunning(lldb::StateType state) {
+    return state == lldb::eStateRunning || IsStepping(state);
+  }
 
-    bool
-    CanResume ( lldb::StateType state)
-    {
-        return state == lldb::eStateStopped;
-    }
+  bool IsStepping(lldb::StateType state) {
+    return state == lldb::eStateStepping;
+  }
 
-    bool
-    HasExited (lldb::StateType state)
-    {
-        return state == lldb::eStateExited;
-    }
+  bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
 
-    bool
-    ProcessIDIsValid ( ) const;
+  bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
 
-    void
-    Clear ( );
+  bool ProcessIDIsValid() const;
 
-    Flags &
-    GetFlags ()
-    {
-        return m_flags;
-    }
+  void Clear();
 
-    const Flags &
-    GetFlags () const
-    {
-        return m_flags;
-    }
+  Flags &GetFlags() { return m_flags; }
 
-    bool
-    UpdateThreadList (ThreadList &old_thread_list, 
-                      ThreadList &new_thread_list) override;
+  const Flags &GetFlags() const { return m_flags; }
 
-    Error
-    EstablishConnectionIfNeeded (const ProcessInfo &process_info);
+  bool UpdateThreadList(ThreadList &old_thread_list,
+                        ThreadList &new_thread_list) override;
 
-    Error
-    LaunchAndConnectToDebugserver (const ProcessInfo &process_info);
+  Error EstablishConnectionIfNeeded(const ProcessInfo &process_info);
 
-    void
-    KillDebugserverProcess ();
+  Error LaunchAndConnectToDebugserver(const ProcessInfo &process_info);
 
-    void
-    BuildDynamicRegisterInfo (bool force);
+  void KillDebugserverProcess();
 
-    void
-    SetLastStopPacket (const StringExtractorGDBRemote &response);
+  void BuildDynamicRegisterInfo(bool force);
 
-    bool
-    ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
+  void SetLastStopPacket(const StringExtractorGDBRemote &response);
 
-    const lldb::DataBufferSP
-    GetAuxvData() override;
+  bool ParsePythonTargetDefinition(const FileSpec &target_definition_fspec);
 
-    StructuredData::ObjectSP
-    GetExtendedInfoForThread (lldb::tid_t tid);
+  const lldb::DataBufferSP GetAuxvData() override;
 
-    void
-    GetMaxMemorySize();
+  StructuredData::ObjectSP GetExtendedInfoForThread(lldb::tid_t tid);
 
-    bool
-    CalculateThreadStopInfo (ThreadGDBRemote *thread);
+  void GetMaxMemorySize();
 
-    size_t
-    UpdateThreadPCsFromStopReplyThreadsValue (std::string &value);
+  bool CalculateThreadStopInfo(ThreadGDBRemote *thread);
 
-    size_t
-    UpdateThreadIDsFromStopReplyThreadsValue (std::string &value);
+  size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value);
 
-    bool
-    HandleNotifyPacket(StringExtractorGDBRemote &packet);
+  size_t UpdateThreadIDsFromStopReplyThreadsValue(std::string &value);
 
-    bool
-    StartAsyncThread ();
+  bool HandleNotifyPacket(StringExtractorGDBRemote &packet);
 
-    void
-    StopAsyncThread ();
+  bool StartAsyncThread();
 
-    static lldb::thread_result_t
-    AsyncThread (void *arg);
+  void StopAsyncThread();
 
-    static bool
-    MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp, lldb::pid_t pid, bool exited, int signo,
-                              int exit_status);
+  static lldb::thread_result_t AsyncThread(void *arg);
 
-    lldb::StateType
-    SetThreadStopInfo (StringExtractor& stop_packet);
+  static bool
+  MonitorDebugserverProcess(std::weak_ptr<ProcessGDBRemote> process_wp,
+                            lldb::pid_t pid, bool exited, int signo,
+                            int exit_status);
 
-    bool
-    GetThreadStopInfoFromJSON (ThreadGDBRemote *thread, const StructuredData::ObjectSP &thread_infos_sp);
+  lldb::StateType SetThreadStopInfo(StringExtractor &stop_packet);
 
-    lldb::ThreadSP
-    SetThreadStopInfo (StructuredData::Dictionary *thread_dict);
+  bool
+  GetThreadStopInfoFromJSON(ThreadGDBRemote *thread,
+                            const StructuredData::ObjectSP &thread_infos_sp);
 
-    lldb::ThreadSP
-    SetThreadStopInfo (lldb::tid_t tid,
-                       ExpeditedRegisterMap &expedited_register_map,
-                       uint8_t signo,
-                       const std::string &thread_name,
-                       const std::string &reason,
-                       const std::string &description,
-                       uint32_t exc_type,
-                       const std::vector<lldb::addr_t> &exc_data,
-                       lldb::addr_t thread_dispatch_qaddr,
-                       bool queue_vars_valid,
-                       lldb_private::LazyBool associated_with_libdispatch_queue,
-                       lldb::addr_t dispatch_queue_t,
-                       std::string &queue_name,
-                       lldb::QueueKind queue_kind,
-                       uint64_t queue_serial);
+  lldb::ThreadSP SetThreadStopInfo(StructuredData::Dictionary *thread_dict);
 
-    void
-    HandleStopReplySequence ();
+  lldb::ThreadSP
+  SetThreadStopInfo(lldb::tid_t tid,
+                    ExpeditedRegisterMap &expedited_register_map, uint8_t signo,
+                    const std::string &thread_name, const std::string &reason,
+                    const std::string &description, uint32_t exc_type,
+                    const std::vector<lldb::addr_t> &exc_data,
+                    lldb::addr_t thread_dispatch_qaddr, bool queue_vars_valid,
+                    lldb_private::LazyBool associated_with_libdispatch_queue,
+                    lldb::addr_t dispatch_queue_t, std::string &queue_name,
+                    lldb::QueueKind queue_kind, uint64_t queue_serial);
 
-    void
-    ClearThreadIDList ();
+  void HandleStopReplySequence();
 
-    bool
-    UpdateThreadIDList ();
+  void ClearThreadIDList();
 
-    void
-    DidLaunchOrAttach (ArchSpec& process_arch);
+  bool UpdateThreadIDList();
 
-    Error
-    ConnectToDebugserver (const char *host_port);
+  void DidLaunchOrAttach(ArchSpec &process_arch);
 
-    const char *
-    GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
-                                   std::string &dispatch_queue_name);
+  Error ConnectToDebugserver(const char *host_port);
 
-    DynamicLoader *
-    GetDynamicLoader () override;
+  const char *GetDispatchQueueNameForThread(lldb::addr_t thread_dispatch_qaddr,
+                                            std::string &dispatch_queue_name);
 
-    // Query remote GDBServer for register information
-    bool
-    GetGDBServerRegisterInfo (ArchSpec &arch);
+  DynamicLoader *GetDynamicLoader() override;
 
-    // Query remote GDBServer for a detailed loaded library list
-    Error
-    GetLoadedModuleList (LoadedModuleInfoList &);
+  // Query remote GDBServer for register information
+  bool GetGDBServerRegisterInfo(ArchSpec &arch);
 
-    lldb::ModuleSP
-    LoadModuleAtAddress (const FileSpec &file, lldb::addr_t link_map, lldb::addr_t base_addr,
-                         bool value_is_offset);
+  // Query remote GDBServer for a detailed loaded library list
+  Error GetLoadedModuleList(LoadedModuleInfoList &);
+
+  lldb::ModuleSP LoadModuleAtAddress(const FileSpec &file,
+                                     lldb::addr_t link_map,
+                                     lldb::addr_t base_addr,
+                                     bool value_is_offset);
 
 private:
-    //------------------------------------------------------------------
-    // For ProcessGDBRemote only
-    //------------------------------------------------------------------
-    std::string m_partial_profile_data;
-    std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
+  //------------------------------------------------------------------
+  // For ProcessGDBRemote only
+  //------------------------------------------------------------------
+  std::string m_partial_profile_data;
+  std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
 
-    static bool
-    NewThreadNotifyBreakpointHit (void *baton,
-                         StoppointCallbackContext *context,
-                         lldb::user_id_t break_id,
-                         lldb::user_id_t break_loc_id);
+  static bool NewThreadNotifyBreakpointHit(void *baton,
+                                           StoppointCallbackContext *context,
+                                           lldb::user_id_t break_id,
+                                           lldb::user_id_t break_loc_id);
 
-    //------------------------------------------------------------------
-    // ContinueDelegate interface
-    //------------------------------------------------------------------
-    void
-    HandleAsyncStdout(llvm::StringRef out) override;
-    void
-    HandleAsyncMisc(llvm::StringRef data) override;
-    void
-    HandleStopReply() override;
-    bool
-    HandleAsyncStructuredData(const StructuredData::ObjectSP
-                              &object_sp) override;
+  //------------------------------------------------------------------
+  // ContinueDelegate interface
+  //------------------------------------------------------------------
+  void HandleAsyncStdout(llvm::StringRef out) override;
+  void HandleAsyncMisc(llvm::StringRef data) override;
+  void HandleStopReply() override;
+  bool
+  HandleAsyncStructuredData(const StructuredData::ObjectSP &object_sp) override;
 
-    DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote);
+  DISALLOW_COPY_AND_ASSIGN(ProcessGDBRemote);
 };
 
 } // namespace process_gdb_remote
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index d4726ad..80139ce 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -11,8 +11,8 @@
 
 #include <mutex>
 
-#include "lldb/Interpreter/Args.h"
 #include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
 
 #include "ProcessGDBRemote.h"
 
@@ -20,196 +20,198 @@
 using namespace lldb_private;
 using namespace lldb_private::process_gdb_remote;
 
-
 // We want to avoid global constructors where code needs to be run so here we
 // control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_lob_sp the first time this function is 
+// that will construct the static g_lob_sp the first time this function is
 // called.
 static bool g_log_enabled = false;
-static Log * g_log = NULL;
-static Log *
-GetLog ()
-{
-    if (!g_log_enabled)
-        return NULL;
-    return g_log;
-}
-
-void
-ProcessGDBRemoteLog::Initialize()
-{
-    static ConstString g_name("gdb-remote");
-    static std::once_flag g_once_flag;
-
-    std::call_once(g_once_flag, [](){
-        Log::Callbacks log_callbacks = {
-            DisableLog,
-            EnableLog,
-            ListLogCategories
-        };
-
-        Log::RegisterLogChannel (g_name, log_callbacks);
-    });
-}
-
-Log *
-ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
-{
-    Log *log(GetLog ());
-    if (log && mask)
-    {
-        uint32_t log_mask = log->GetMask().Get();
-        if ((log_mask & mask) != mask)
-            return NULL;
-    }
-    return log;
-}
-
-Log *
-ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
-{
-    Log *log(GetLog ());
-    if (log && log->GetMask().Get() & mask)
-        return log;
+static Log *g_log = NULL;
+static Log *GetLog() {
+  if (!g_log_enabled)
     return NULL;
+  return g_log;
 }
 
-void
-ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
-{
-    Log *log (GetLog ());
-    if (log)
-    {
-        uint32_t flag_bits = 0;
-        
-        if (categories[0] != NULL)
-        {
-            flag_bits = log->GetMask().Get();
-            for (size_t i = 0; categories[i] != NULL; ++i)
-            {
-                const char *arg = categories[i];
-                
+void ProcessGDBRemoteLog::Initialize() {
+  static ConstString g_name("gdb-remote");
+  static std::once_flag g_once_flag;
 
-                if      (::strcasecmp (arg, "all")        == 0 ) flag_bits &= ~GDBR_LOG_ALL;
-                else if (::strcasecmp (arg, "async")      == 0 ) flag_bits &= ~GDBR_LOG_ASYNC;
-                else if (::strncasecmp (arg, "break", 5)  == 0 ) flag_bits &= ~GDBR_LOG_BREAKPOINTS;
-                else if (::strncasecmp (arg, "comm", 4)   == 0 ) flag_bits &= ~GDBR_LOG_COMM;
-                else if (::strcasecmp (arg, "default")    == 0 ) flag_bits &= ~GDBR_LOG_DEFAULT;
-                else if (::strcasecmp (arg, "packets")    == 0 ) flag_bits &= ~GDBR_LOG_PACKETS;
-                else if (::strcasecmp (arg, "memory")     == 0 ) flag_bits &= ~GDBR_LOG_MEMORY;
-                else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
-                else if (::strcasecmp (arg, "data-long")  == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
-                else if (::strcasecmp (arg, "process")    == 0 ) flag_bits &= ~GDBR_LOG_PROCESS;
-                else if (::strcasecmp (arg, "step")       == 0 ) flag_bits &= ~GDBR_LOG_STEP;
-                else if (::strcasecmp (arg, "thread")     == 0 ) flag_bits &= ~GDBR_LOG_THREAD;
-                else if (::strcasecmp (arg, "verbose")    == 0 ) flag_bits &= ~GDBR_LOG_VERBOSE;
-                else if (::strncasecmp (arg, "watch", 5)  == 0 ) flag_bits &= ~GDBR_LOG_WATCHPOINTS;
-                else
-                {
-                    feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
-                    ListLogCategories (feedback_strm);
-                }
-                
-            }
-        }
-        
-        if (flag_bits == 0)
-            g_log_enabled = false;
-        else
-            log->GetMask().Reset (flag_bits);
-    }
-    
-    return;
+  std::call_once(g_once_flag, []() {
+    Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
+
+    Log::RegisterLogChannel(g_name, log_callbacks);
+  });
 }
 
-Log *
-ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
-{
-    // Try see if there already is a log - that way we can reuse its settings.
-    // We could reuse the log in toto, but we don't know that the stream is the same.
+Log *ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(uint32_t mask) {
+  Log *log(GetLog());
+  if (log && mask) {
+    uint32_t log_mask = log->GetMask().Get();
+    if ((log_mask & mask) != mask)
+      return NULL;
+  }
+  return log;
+}
+
+Log *ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(uint32_t mask) {
+  Log *log(GetLog());
+  if (log && log->GetMask().Get() & mask)
+    return log;
+  return NULL;
+}
+
+void ProcessGDBRemoteLog::DisableLog(const char **categories,
+                                     Stream *feedback_strm) {
+  Log *log(GetLog());
+  if (log) {
     uint32_t flag_bits = 0;
-    if (g_log)
-        flag_bits = g_log->GetMask().Get();
 
-    // Now make a new log with this stream if one was provided
-    if (log_stream_sp)
-    {
-        if (g_log)
-            g_log->SetStream(log_stream_sp);
-        else
-            g_log = new Log(log_stream_sp);
-    }
+    if (categories[0] != NULL) {
+      flag_bits = log->GetMask().Get();
+      for (size_t i = 0; categories[i] != NULL; ++i) {
+        const char *arg = categories[i];
 
-    if (g_log)
-    {
-        bool got_unknown_category = false;
-        for (size_t i=0; categories[i] != NULL; ++i)
-        {
-            const char *arg = categories[i];
-
-            if      (::strcasecmp (arg, "all")        == 0 ) flag_bits |= GDBR_LOG_ALL;
-            else if (::strcasecmp (arg, "async")      == 0 ) flag_bits |= GDBR_LOG_ASYNC;
-            else if (::strncasecmp (arg, "break", 5)  == 0 ) flag_bits |= GDBR_LOG_BREAKPOINTS;
-            else if (::strncasecmp (arg, "comm", 4)   == 0 ) flag_bits |= GDBR_LOG_COMM;
-            else if (::strcasecmp (arg, "default")    == 0 ) flag_bits |= GDBR_LOG_DEFAULT;
-            else if (::strcasecmp (arg, "packets")    == 0 ) flag_bits |= GDBR_LOG_PACKETS;
-            else if (::strcasecmp (arg, "memory")     == 0 ) flag_bits |= GDBR_LOG_MEMORY;
-            else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
-            else if (::strcasecmp (arg, "data-long")  == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
-            else if (::strcasecmp (arg, "process")    == 0 ) flag_bits |= GDBR_LOG_PROCESS;
-            else if (::strcasecmp (arg, "step")       == 0 ) flag_bits |= GDBR_LOG_STEP;
-            else if (::strcasecmp (arg, "thread")     == 0 ) flag_bits |= GDBR_LOG_THREAD;
-            else if (::strcasecmp (arg, "verbose")    == 0 ) flag_bits |= GDBR_LOG_VERBOSE;
-            else if (::strncasecmp (arg, "watch", 5)  == 0 ) flag_bits |= GDBR_LOG_WATCHPOINTS;
-            else
-            {
-                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
-                if (got_unknown_category == false)
-                {
-                    got_unknown_category = true;
-                    ListLogCategories (feedback_strm);
-                }
-            }
+        if (::strcasecmp(arg, "all") == 0)
+          flag_bits &= ~GDBR_LOG_ALL;
+        else if (::strcasecmp(arg, "async") == 0)
+          flag_bits &= ~GDBR_LOG_ASYNC;
+        else if (::strncasecmp(arg, "break", 5) == 0)
+          flag_bits &= ~GDBR_LOG_BREAKPOINTS;
+        else if (::strncasecmp(arg, "comm", 4) == 0)
+          flag_bits &= ~GDBR_LOG_COMM;
+        else if (::strcasecmp(arg, "default") == 0)
+          flag_bits &= ~GDBR_LOG_DEFAULT;
+        else if (::strcasecmp(arg, "packets") == 0)
+          flag_bits &= ~GDBR_LOG_PACKETS;
+        else if (::strcasecmp(arg, "memory") == 0)
+          flag_bits &= ~GDBR_LOG_MEMORY;
+        else if (::strcasecmp(arg, "data-short") == 0)
+          flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
+        else if (::strcasecmp(arg, "data-long") == 0)
+          flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
+        else if (::strcasecmp(arg, "process") == 0)
+          flag_bits &= ~GDBR_LOG_PROCESS;
+        else if (::strcasecmp(arg, "step") == 0)
+          flag_bits &= ~GDBR_LOG_STEP;
+        else if (::strcasecmp(arg, "thread") == 0)
+          flag_bits &= ~GDBR_LOG_THREAD;
+        else if (::strcasecmp(arg, "verbose") == 0)
+          flag_bits &= ~GDBR_LOG_VERBOSE;
+        else if (::strncasecmp(arg, "watch", 5) == 0)
+          flag_bits &= ~GDBR_LOG_WATCHPOINTS;
+        else {
+          feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+          ListLogCategories(feedback_strm);
         }
-        if (flag_bits == 0)
-            flag_bits = GDBR_LOG_DEFAULT;
-        g_log->GetMask().Reset(flag_bits);
-        g_log->GetOptions().Reset(log_options);
+      }
     }
-    g_log_enabled = true;
-    return g_log;
+
+    if (flag_bits == 0)
+      g_log_enabled = false;
+    else
+      log->GetMask().Reset(flag_bits);
+  }
+
+  return;
 }
 
-void
-ProcessGDBRemoteLog::ListLogCategories (Stream *strm)
-{
-    strm->Printf ("Logging categories for '%s':\n"
-                  "  all - turn on all available logging categories\n"
-                  "  async - log asynchronous activity\n"
-                  "  break - log breakpoints\n"
-                  "  communication - log communication activity\n"
-                  "  default - enable the default set of logging categories for liblldb\n"
-                  "  packets - log gdb remote packets\n"
-                  "  memory - log memory reads and writes\n"
-                  "  data-short - log memory bytes for memory reads and writes for short transactions only\n"
-                  "  data-long - log memory bytes for memory reads and writes for all transactions\n"
-                  "  process - log process events and activities\n"
-                  "  thread - log thread events and activities\n"
-                  "  step - log step related activities\n"
-                  "  verbose - enable verbose logging\n"
-                  "  watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic().GetCString());
+Log *ProcessGDBRemoteLog::EnableLog(StreamSP &log_stream_sp,
+                                    uint32_t log_options,
+                                    const char **categories,
+                                    Stream *feedback_strm) {
+  // Try see if there already is a log - that way we can reuse its settings.
+  // We could reuse the log in toto, but we don't know that the stream is the
+  // same.
+  uint32_t flag_bits = 0;
+  if (g_log)
+    flag_bits = g_log->GetMask().Get();
+
+  // Now make a new log with this stream if one was provided
+  if (log_stream_sp) {
+    if (g_log)
+      g_log->SetStream(log_stream_sp);
+    else
+      g_log = new Log(log_stream_sp);
+  }
+
+  if (g_log) {
+    bool got_unknown_category = false;
+    for (size_t i = 0; categories[i] != NULL; ++i) {
+      const char *arg = categories[i];
+
+      if (::strcasecmp(arg, "all") == 0)
+        flag_bits |= GDBR_LOG_ALL;
+      else if (::strcasecmp(arg, "async") == 0)
+        flag_bits |= GDBR_LOG_ASYNC;
+      else if (::strncasecmp(arg, "break", 5) == 0)
+        flag_bits |= GDBR_LOG_BREAKPOINTS;
+      else if (::strncasecmp(arg, "comm", 4) == 0)
+        flag_bits |= GDBR_LOG_COMM;
+      else if (::strcasecmp(arg, "default") == 0)
+        flag_bits |= GDBR_LOG_DEFAULT;
+      else if (::strcasecmp(arg, "packets") == 0)
+        flag_bits |= GDBR_LOG_PACKETS;
+      else if (::strcasecmp(arg, "memory") == 0)
+        flag_bits |= GDBR_LOG_MEMORY;
+      else if (::strcasecmp(arg, "data-short") == 0)
+        flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT;
+      else if (::strcasecmp(arg, "data-long") == 0)
+        flag_bits |= GDBR_LOG_MEMORY_DATA_LONG;
+      else if (::strcasecmp(arg, "process") == 0)
+        flag_bits |= GDBR_LOG_PROCESS;
+      else if (::strcasecmp(arg, "step") == 0)
+        flag_bits |= GDBR_LOG_STEP;
+      else if (::strcasecmp(arg, "thread") == 0)
+        flag_bits |= GDBR_LOG_THREAD;
+      else if (::strcasecmp(arg, "verbose") == 0)
+        flag_bits |= GDBR_LOG_VERBOSE;
+      else if (::strncasecmp(arg, "watch", 5) == 0)
+        flag_bits |= GDBR_LOG_WATCHPOINTS;
+      else {
+        feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+        if (got_unknown_category == false) {
+          got_unknown_category = true;
+          ListLogCategories(feedback_strm);
+        }
+      }
+    }
+    if (flag_bits == 0)
+      flag_bits = GDBR_LOG_DEFAULT;
+    g_log->GetMask().Reset(flag_bits);
+    g_log->GetOptions().Reset(log_options);
+  }
+  g_log_enabled = true;
+  return g_log;
 }
 
+void ProcessGDBRemoteLog::ListLogCategories(Stream *strm) {
+  strm->Printf(
+      "Logging categories for '%s':\n"
+      "  all - turn on all available logging categories\n"
+      "  async - log asynchronous activity\n"
+      "  break - log breakpoints\n"
+      "  communication - log communication activity\n"
+      "  default - enable the default set of logging categories for liblldb\n"
+      "  packets - log gdb remote packets\n"
+      "  memory - log memory reads and writes\n"
+      "  data-short - log memory bytes for memory reads and writes for short "
+      "transactions only\n"
+      "  data-long - log memory bytes for memory reads and writes for all "
+      "transactions\n"
+      "  process - log process events and activities\n"
+      "  thread - log thread events and activities\n"
+      "  step - log step related activities\n"
+      "  verbose - enable verbose logging\n"
+      "  watch - log watchpoint related activities\n",
+      ProcessGDBRemote::GetPluginNameStatic().GetCString());
+}
 
-void
-ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
-{
-    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
-    if (log)
-    {
-        va_list args;
-        va_start (args, format);
-        log->VAPrintf (format, args);
-        va_end (args);
-    }
+void ProcessGDBRemoteLog::LogIf(uint32_t mask, const char *format, ...) {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(mask));
+  if (log) {
+    va_list args;
+    va_start(args, format);
+    log->VAPrintf(format, args);
+    va_end(args);
+  }
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index 3cd974d..f5e92b4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -17,50 +17,44 @@
 // Project includes
 #include "lldb/Core/Log.h"
 
-#define GDBR_LOG_VERBOSE                  (1u << 0)
-#define GDBR_LOG_PROCESS                  (1u << 1)
-#define GDBR_LOG_THREAD                   (1u << 2)
-#define GDBR_LOG_PACKETS                  (1u << 3)
-#define GDBR_LOG_MEMORY                   (1u << 4)    // Log memory reads/writes calls
-#define GDBR_LOG_MEMORY_DATA_SHORT        (1u << 5)    // Log short memory reads/writes bytes
-#define GDBR_LOG_MEMORY_DATA_LONG         (1u << 6)    // Log all memory reads/writes bytes
-#define GDBR_LOG_BREAKPOINTS              (1u << 7)
-#define GDBR_LOG_WATCHPOINTS              (1u << 8)
-#define GDBR_LOG_STEP                     (1u << 9)
-#define GDBR_LOG_COMM                     (1u << 10)
-#define GDBR_LOG_ASYNC                    (1u << 11)
-#define GDBR_LOG_ALL                      (UINT32_MAX)
-#define GDBR_LOG_DEFAULT                  GDBR_LOG_PACKETS
+#define GDBR_LOG_VERBOSE (1u << 0)
+#define GDBR_LOG_PROCESS (1u << 1)
+#define GDBR_LOG_THREAD (1u << 2)
+#define GDBR_LOG_PACKETS (1u << 3)
+#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
+#define GDBR_LOG_MEMORY_DATA_SHORT                                             \
+  (1u << 5) // Log short memory reads/writes bytes
+#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
+#define GDBR_LOG_BREAKPOINTS (1u << 7)
+#define GDBR_LOG_WATCHPOINTS (1u << 8)
+#define GDBR_LOG_STEP (1u << 9)
+#define GDBR_LOG_COMM (1u << 10)
+#define GDBR_LOG_ASYNC (1u << 11)
+#define GDBR_LOG_ALL (UINT32_MAX)
+#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS
 
 namespace lldb_private {
 namespace process_gdb_remote {
 
-class ProcessGDBRemoteLog
-{
+class ProcessGDBRemoteLog {
 public:
-    static void
-    Initialize();
+  static void Initialize();
 
-    static Log *
-    GetLogIfAllCategoriesSet(uint32_t mask = 0);
-    
-    static Log *
-    GetLogIfAnyCategoryIsSet (uint32_t mask);
+  static Log *GetLogIfAllCategoriesSet(uint32_t mask = 0);
 
-    static void
-    DisableLog (const char **categories, Stream *feedback_strm);
+  static Log *GetLogIfAnyCategoryIsSet(uint32_t mask);
 
-    static Log *
-    EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm);
+  static void DisableLog(const char **categories, Stream *feedback_strm);
 
-    static void
-    ListLogCategories (Stream *strm);
+  static Log *EnableLog(lldb::StreamSP &log_stream_sp, uint32_t log_options,
+                        const char **categories, Stream *feedback_strm);
 
-    static void
-    LogIf (uint32_t mask, const char *format, ...);
+  static void ListLogCategories(Stream *strm);
+
+  static void LogIf(uint32_t mask, const char *format, ...);
 };
 
 } // namespace process_gdb_remote
 } // namespace lldb_private
 
-#endif  // liblldb_ProcessGDBRemoteLog_h_
+#endif // liblldb_ProcessGDBRemoteLog_h_
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 02a617b..ab55214 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -7,7 +7,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "ThreadGDBRemote.h"
 
 #include "lldb/Breakpoint/Watchpoint.h"
@@ -36,372 +35,318 @@
 // Thread Registers
 //----------------------------------------------------------------------
 
-ThreadGDBRemote::ThreadGDBRemote (Process &process, lldb::tid_t tid) :
-    Thread(process, tid),
-    m_thread_name (),
-    m_dispatch_queue_name (),
-    m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
-    m_dispatch_queue_t (LLDB_INVALID_ADDRESS),
-    m_queue_kind (eQueueKindUnknown),
-    m_queue_serial_number (LLDB_INVALID_QUEUE_ID),
-    m_associated_with_libdispatch_queue (eLazyBoolCalculate)
-{
-    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
-                               this, 
-                               process.GetID(),
-                               GetID());
+ThreadGDBRemote::ThreadGDBRemote(Process &process, lldb::tid_t tid)
+    : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
+      m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS),
+      m_dispatch_queue_t(LLDB_INVALID_ADDRESS), m_queue_kind(eQueueKindUnknown),
+      m_queue_serial_number(LLDB_INVALID_QUEUE_ID),
+      m_associated_with_libdispatch_queue(eLazyBoolCalculate) {
+  ProcessGDBRemoteLog::LogIf(
+      GDBR_LOG_THREAD,
+      "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this,
+      process.GetID(), GetID());
 }
 
-ThreadGDBRemote::~ThreadGDBRemote ()
-{
-    ProcessSP process_sp(GetProcess());
-    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", 
-                               this, 
-                               process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, 
-                               GetID());
-    DestroyThread();
+ThreadGDBRemote::~ThreadGDBRemote() {
+  ProcessSP process_sp(GetProcess());
+  ProcessGDBRemoteLog::LogIf(
+      GDBR_LOG_THREAD,
+      "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this,
+      process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, GetID());
+  DestroyThread();
 }
 
-const char *
-ThreadGDBRemote::GetName ()
-{
-    if (m_thread_name.empty())
-        return NULL;
-    return m_thread_name.c_str();
-}
-
-void
-ThreadGDBRemote::ClearQueueInfo ()
-{
-    m_dispatch_queue_name.clear();
-    m_queue_kind = eQueueKindUnknown;
-    m_queue_serial_number = 0;
-    m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
-    m_associated_with_libdispatch_queue = eLazyBoolCalculate;
-}
-
-void
-ThreadGDBRemote::SetQueueInfo (std::string &&queue_name, QueueKind queue_kind, uint64_t queue_serial, addr_t dispatch_queue_t, LazyBool associated_with_libdispatch_queue)
-{
-    m_dispatch_queue_name = queue_name;
-    m_queue_kind = queue_kind;
-    m_queue_serial_number = queue_serial;
-    m_dispatch_queue_t = dispatch_queue_t;
-    m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
-}
-
-
-const char *
-ThreadGDBRemote::GetQueueName ()
-{
-    // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
-    // with valid information that was gleaned from the stop reply packet. In this case we trust
-    // that the info is valid in m_dispatch_queue_name without refetching it
-    if (CachedQueueInfoIsValid())
-    {
-        if (m_dispatch_queue_name.empty())
-            return nullptr;
-        else
-            return m_dispatch_queue_name.c_str();
-    }
-    // Always re-fetch the dispatch queue name since it can change
-
-    if (m_associated_with_libdispatch_queue == eLazyBoolNo)
-        return nullptr;
-
-    if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
-    {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp)
-        {
-            SystemRuntime *runtime = process_sp->GetSystemRuntime ();
-            if (runtime)
-                m_dispatch_queue_name = runtime->GetQueueNameFromThreadQAddress (m_thread_dispatch_qaddr);
-            else
-                m_dispatch_queue_name.clear();
-
-            if (!m_dispatch_queue_name.empty())
-                return m_dispatch_queue_name.c_str();
-        }
-    }
+const char *ThreadGDBRemote::GetName() {
+  if (m_thread_name.empty())
     return NULL;
+  return m_thread_name.c_str();
 }
 
-QueueKind
-ThreadGDBRemote::GetQueueKind ()
-{
-    // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
-    // with valid information that was gleaned from the stop reply packet. In this case we trust
-    // that the info is valid in m_dispatch_queue_name without refetching it
-    if (CachedQueueInfoIsValid())
-    {
-        return m_queue_kind;
-    }
-
-    if (m_associated_with_libdispatch_queue == eLazyBoolNo)
-        return eQueueKindUnknown;
-
-    if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
-    {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp)
-        {
-            SystemRuntime *runtime = process_sp->GetSystemRuntime ();
-            if (runtime)
-                m_queue_kind = runtime->GetQueueKind (m_thread_dispatch_qaddr);
-            return m_queue_kind;
-        }
-    }
-    return eQueueKindUnknown;
+void ThreadGDBRemote::ClearQueueInfo() {
+  m_dispatch_queue_name.clear();
+  m_queue_kind = eQueueKindUnknown;
+  m_queue_serial_number = 0;
+  m_dispatch_queue_t = LLDB_INVALID_ADDRESS;
+  m_associated_with_libdispatch_queue = eLazyBoolCalculate;
 }
 
-
-queue_id_t
-ThreadGDBRemote::GetQueueID ()
-{
-    // If our cached queue info is valid, then someone called ThreadGDBRemote::SetQueueInfo(...)
-    // with valid information that was gleaned from the stop reply packet. In this case we trust
-    // that the info is valid in m_dispatch_queue_name without refetching it
-    if (CachedQueueInfoIsValid())
-        return m_queue_serial_number;
-
-    if (m_associated_with_libdispatch_queue == eLazyBoolNo)
-        return LLDB_INVALID_QUEUE_ID;
-
-    if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
-    {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp)
-        {
-            SystemRuntime *runtime = process_sp->GetSystemRuntime ();
-            if (runtime)
-            {
-                return runtime->GetQueueIDFromThreadQAddress (m_thread_dispatch_qaddr);
-            }
-        }
-    }
-    return LLDB_INVALID_QUEUE_ID;
+void ThreadGDBRemote::SetQueueInfo(std::string &&queue_name,
+                                   QueueKind queue_kind, uint64_t queue_serial,
+                                   addr_t dispatch_queue_t,
+                                   LazyBool associated_with_libdispatch_queue) {
+  m_dispatch_queue_name = queue_name;
+  m_queue_kind = queue_kind;
+  m_queue_serial_number = queue_serial;
+  m_dispatch_queue_t = dispatch_queue_t;
+  m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
 }
 
-QueueSP
-ThreadGDBRemote::GetQueue ()
-{
-    queue_id_t queue_id = GetQueueID();
-    QueueSP queue;
-    if (queue_id != LLDB_INVALID_QUEUE_ID)
-    {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp)
-        {
-            queue = process_sp->GetQueueList().FindQueueByID (queue_id);
-        }
-    }
-    return queue;
-}
-
-addr_t
-ThreadGDBRemote::GetQueueLibdispatchQueueAddress ()
-{
-    if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS)
-    {
-        if (m_thread_dispatch_qaddr != 0 && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS)
-        {
-            ProcessSP process_sp (GetProcess());
-            if (process_sp)
-            {
-                SystemRuntime *runtime = process_sp->GetSystemRuntime ();
-                if (runtime)
-                {
-                    m_dispatch_queue_t = runtime->GetLibdispatchQueueAddressFromThreadQAddress (m_thread_dispatch_qaddr);
-                }
-            }
-        }
-    }
-    return m_dispatch_queue_t;
-}
-
-void
-ThreadGDBRemote::SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t)
-{
-    m_dispatch_queue_t = dispatch_queue_t;
-}
-
-bool
-ThreadGDBRemote::ThreadHasQueueInformation () const
-{
-    if (m_thread_dispatch_qaddr != 0 
-        && m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS
-        && m_dispatch_queue_t != LLDB_INVALID_ADDRESS
-        && m_queue_kind != eQueueKindUnknown
-        && m_queue_serial_number != 0)
-    {
-        return true;
-    }
-    return false;
-}
-
-LazyBool
-ThreadGDBRemote::GetAssociatedWithLibdispatchQueue ()
-{
-    return m_associated_with_libdispatch_queue;
-}
-
-void
-ThreadGDBRemote::SetAssociatedWithLibdispatchQueue (LazyBool associated_with_libdispatch_queue)
-{
-    m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
-}
-
-StructuredData::ObjectSP
-ThreadGDBRemote::FetchThreadExtendedInfo ()
-{
-    StructuredData::ObjectSP object_sp;
-    const lldb::user_id_t tid = GetProtocolID();
-    Log *log(GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
-    if (log)
-        log->Printf ("Fetching extended information for thread %4.4" PRIx64, tid);
-    ProcessSP process_sp (GetProcess());
-    if (process_sp)
-    {
-        ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
-        object_sp = gdb_process->GetExtendedInfoForThread (tid);
-    }
-    return object_sp;
-}
-
-void
-ThreadGDBRemote::WillResume (StateType resume_state)
-{
-    int signo = GetResumeSignal();
-    const lldb::user_id_t tid = GetProtocolID();
-    Log *log(GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
-    if (log)
-        log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", tid, StateAsCString(resume_state));
-
-    ProcessSP process_sp (GetProcess());
-    if (process_sp)
-    {
-        ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
-        switch (resume_state)
-        {
-        case eStateSuspended:
-        case eStateStopped:
-            // Don't append anything for threads that should stay stopped.
-            break;
-
-        case eStateRunning:
-            if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
-                gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
-            else
-                gdb_process->m_continue_c_tids.push_back(tid);
-            break;
-
-        case eStateStepping:
-            if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
-                gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
-            else
-                gdb_process->m_continue_s_tids.push_back(tid);
-            break;
-
-        default:
-            break;
-        }
-    }
-}
-
-void
-ThreadGDBRemote::RefreshStateAfterStop()
-{
-    // Invalidate all registers in our register context. We don't set "force" to
-    // true because the stop reply packet might have had some register values
-    // that were expedited and these will already be copied into the register
-    // context by the time this function gets called. The GDBRemoteRegisterContext
-    // class has been made smart enough to detect when it needs to invalidate
-    // which registers are valid by putting hooks in the register read and 
-    // register supply functions where they check the process stop ID and do
-    // the right thing.
-    const bool force = false;
-    GetRegisterContext()->InvalidateIfNeeded (force);
-}
-
-bool
-ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread)
-{
-    return thread != 0;
-}
-
-void
-ThreadGDBRemote::Dump(Log *log, uint32_t index)
-{
-}
-
-
-bool
-ThreadGDBRemote::ShouldStop (bool &step_more)
-{
-    return true;
-}
-lldb::RegisterContextSP
-ThreadGDBRemote::GetRegisterContext ()
-{
-    if (m_reg_context_sp.get() == NULL)
-        m_reg_context_sp = CreateRegisterContextForFrame (NULL);
-    return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame)
-{
-    lldb::RegisterContextSP reg_ctx_sp;
-    uint32_t concrete_frame_idx = 0;
-    
-    if (frame)
-        concrete_frame_idx = frame->GetConcreteFrameIndex ();
-
-    
-    if (concrete_frame_idx == 0)
-    {
-        ProcessSP process_sp (GetProcess());
-        if (process_sp)
-        {
-            ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
-            // read_all_registers_at_once will be true if 'p' packet is not supported.
-            bool read_all_registers_at_once = !gdb_process->GetGDBRemote().GetpPacketSupported (GetID());
-            reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
-        }
-    }
+const char *ThreadGDBRemote::GetQueueName() {
+  // If our cached queue info is valid, then someone called
+  // ThreadGDBRemote::SetQueueInfo(...)
+  // with valid information that was gleaned from the stop reply packet. In this
+  // case we trust
+  // that the info is valid in m_dispatch_queue_name without refetching it
+  if (CachedQueueInfoIsValid()) {
+    if (m_dispatch_queue_name.empty())
+      return nullptr;
     else
-    {
-        Unwind *unwinder = GetUnwinder ();
-        if (unwinder)
-            reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+      return m_dispatch_queue_name.c_str();
+  }
+  // Always re-fetch the dispatch queue name since it can change
+
+  if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+    return nullptr;
+
+  if (m_thread_dispatch_qaddr != 0 &&
+      m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+    ProcessSP process_sp(GetProcess());
+    if (process_sp) {
+      SystemRuntime *runtime = process_sp->GetSystemRuntime();
+      if (runtime)
+        m_dispatch_queue_name =
+            runtime->GetQueueNameFromThreadQAddress(m_thread_dispatch_qaddr);
+      else
+        m_dispatch_queue_name.clear();
+
+      if (!m_dispatch_queue_name.empty())
+        return m_dispatch_queue_name.c_str();
     }
-    return reg_ctx_sp;
+  }
+  return NULL;
 }
 
-bool
-ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data)
-{
-    GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
-    assert (gdb_reg_ctx);
-    return gdb_reg_ctx->PrivateSetRegisterValue(reg, data);
+QueueKind ThreadGDBRemote::GetQueueKind() {
+  // If our cached queue info is valid, then someone called
+  // ThreadGDBRemote::SetQueueInfo(...)
+  // with valid information that was gleaned from the stop reply packet. In this
+  // case we trust
+  // that the info is valid in m_dispatch_queue_name without refetching it
+  if (CachedQueueInfoIsValid()) {
+    return m_queue_kind;
+  }
+
+  if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+    return eQueueKindUnknown;
+
+  if (m_thread_dispatch_qaddr != 0 &&
+      m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+    ProcessSP process_sp(GetProcess());
+    if (process_sp) {
+      SystemRuntime *runtime = process_sp->GetSystemRuntime();
+      if (runtime)
+        m_queue_kind = runtime->GetQueueKind(m_thread_dispatch_qaddr);
+      return m_queue_kind;
+    }
+  }
+  return eQueueKindUnknown;
 }
 
-bool
-ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, uint64_t regval)
-{
-    GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
-    assert (gdb_reg_ctx);
-    return gdb_reg_ctx->PrivateSetRegisterValue (reg, regval);
+queue_id_t ThreadGDBRemote::GetQueueID() {
+  // If our cached queue info is valid, then someone called
+  // ThreadGDBRemote::SetQueueInfo(...)
+  // with valid information that was gleaned from the stop reply packet. In this
+  // case we trust
+  // that the info is valid in m_dispatch_queue_name without refetching it
+  if (CachedQueueInfoIsValid())
+    return m_queue_serial_number;
+
+  if (m_associated_with_libdispatch_queue == eLazyBoolNo)
+    return LLDB_INVALID_QUEUE_ID;
+
+  if (m_thread_dispatch_qaddr != 0 &&
+      m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+    ProcessSP process_sp(GetProcess());
+    if (process_sp) {
+      SystemRuntime *runtime = process_sp->GetSystemRuntime();
+      if (runtime) {
+        return runtime->GetQueueIDFromThreadQAddress(m_thread_dispatch_qaddr);
+      }
+    }
+  }
+  return LLDB_INVALID_QUEUE_ID;
 }
 
-bool
-ThreadGDBRemote::CalculateStopInfo ()
-{
-    ProcessSP process_sp (GetProcess());
-    if (process_sp)
-        return static_cast<ProcessGDBRemote *>(process_sp.get())->CalculateThreadStopInfo(this);
-    return false;
+QueueSP ThreadGDBRemote::GetQueue() {
+  queue_id_t queue_id = GetQueueID();
+  QueueSP queue;
+  if (queue_id != LLDB_INVALID_QUEUE_ID) {
+    ProcessSP process_sp(GetProcess());
+    if (process_sp) {
+      queue = process_sp->GetQueueList().FindQueueByID(queue_id);
+    }
+  }
+  return queue;
 }
 
+addr_t ThreadGDBRemote::GetQueueLibdispatchQueueAddress() {
+  if (m_dispatch_queue_t == LLDB_INVALID_ADDRESS) {
+    if (m_thread_dispatch_qaddr != 0 &&
+        m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) {
+      ProcessSP process_sp(GetProcess());
+      if (process_sp) {
+        SystemRuntime *runtime = process_sp->GetSystemRuntime();
+        if (runtime) {
+          m_dispatch_queue_t =
+              runtime->GetLibdispatchQueueAddressFromThreadQAddress(
+                  m_thread_dispatch_qaddr);
+        }
+      }
+    }
+  }
+  return m_dispatch_queue_t;
+}
 
+void ThreadGDBRemote::SetQueueLibdispatchQueueAddress(
+    lldb::addr_t dispatch_queue_t) {
+  m_dispatch_queue_t = dispatch_queue_t;
+}
+
+bool ThreadGDBRemote::ThreadHasQueueInformation() const {
+  if (m_thread_dispatch_qaddr != 0 &&
+      m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS &&
+      m_dispatch_queue_t != LLDB_INVALID_ADDRESS &&
+      m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0) {
+    return true;
+  }
+  return false;
+}
+
+LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() {
+  return m_associated_with_libdispatch_queue;
+}
+
+void ThreadGDBRemote::SetAssociatedWithLibdispatchQueue(
+    LazyBool associated_with_libdispatch_queue) {
+  m_associated_with_libdispatch_queue = associated_with_libdispatch_queue;
+}
+
+StructuredData::ObjectSP ThreadGDBRemote::FetchThreadExtendedInfo() {
+  StructuredData::ObjectSP object_sp;
+  const lldb::user_id_t tid = GetProtocolID();
+  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+  if (log)
+    log->Printf("Fetching extended information for thread %4.4" PRIx64, tid);
+  ProcessSP process_sp(GetProcess());
+  if (process_sp) {
+    ProcessGDBRemote *gdb_process =
+        static_cast<ProcessGDBRemote *>(process_sp.get());
+    object_sp = gdb_process->GetExtendedInfoForThread(tid);
+  }
+  return object_sp;
+}
+
+void ThreadGDBRemote::WillResume(StateType resume_state) {
+  int signo = GetResumeSignal();
+  const lldb::user_id_t tid = GetProtocolID();
+  Log *log(GetLogIfAnyCategoriesSet(GDBR_LOG_THREAD));
+  if (log)
+    log->Printf("Resuming thread: %4.4" PRIx64 " with state: %s.", tid,
+                StateAsCString(resume_state));
+
+  ProcessSP process_sp(GetProcess());
+  if (process_sp) {
+    ProcessGDBRemote *gdb_process =
+        static_cast<ProcessGDBRemote *>(process_sp.get());
+    switch (resume_state) {
+    case eStateSuspended:
+    case eStateStopped:
+      // Don't append anything for threads that should stay stopped.
+      break;
+
+    case eStateRunning:
+      if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
+        gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
+      else
+        gdb_process->m_continue_c_tids.push_back(tid);
+      break;
+
+    case eStateStepping:
+      if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
+        gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
+      else
+        gdb_process->m_continue_s_tids.push_back(tid);
+      break;
+
+    default:
+      break;
+    }
+  }
+}
+
+void ThreadGDBRemote::RefreshStateAfterStop() {
+  // Invalidate all registers in our register context. We don't set "force" to
+  // true because the stop reply packet might have had some register values
+  // that were expedited and these will already be copied into the register
+  // context by the time this function gets called. The GDBRemoteRegisterContext
+  // class has been made smart enough to detect when it needs to invalidate
+  // which registers are valid by putting hooks in the register read and
+  // register supply functions where they check the process stop ID and do
+  // the right thing.
+  const bool force = false;
+  GetRegisterContext()->InvalidateIfNeeded(force);
+}
+
+bool ThreadGDBRemote::ThreadIDIsValid(lldb::tid_t thread) {
+  return thread != 0;
+}
+
+void ThreadGDBRemote::Dump(Log *log, uint32_t index) {}
+
+bool ThreadGDBRemote::ShouldStop(bool &step_more) { return true; }
+lldb::RegisterContextSP ThreadGDBRemote::GetRegisterContext() {
+  if (m_reg_context_sp.get() == NULL)
+    m_reg_context_sp = CreateRegisterContextForFrame(NULL);
+  return m_reg_context_sp;
+}
+
+lldb::RegisterContextSP
+ThreadGDBRemote::CreateRegisterContextForFrame(StackFrame *frame) {
+  lldb::RegisterContextSP reg_ctx_sp;
+  uint32_t concrete_frame_idx = 0;
+
+  if (frame)
+    concrete_frame_idx = frame->GetConcreteFrameIndex();
+
+  if (concrete_frame_idx == 0) {
+    ProcessSP process_sp(GetProcess());
+    if (process_sp) {
+      ProcessGDBRemote *gdb_process =
+          static_cast<ProcessGDBRemote *>(process_sp.get());
+      // read_all_registers_at_once will be true if 'p' packet is not supported.
+      bool read_all_registers_at_once =
+          !gdb_process->GetGDBRemote().GetpPacketSupported(GetID());
+      reg_ctx_sp.reset(new GDBRemoteRegisterContext(
+          *this, concrete_frame_idx, gdb_process->m_register_info,
+          read_all_registers_at_once));
+    }
+  } else {
+    Unwind *unwinder = GetUnwinder();
+    if (unwinder)
+      reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
+  }
+  return reg_ctx_sp;
+}
+
+bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg,
+                                              llvm::ArrayRef<uint8_t> data) {
+  GDBRemoteRegisterContext *gdb_reg_ctx =
+      static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
+  assert(gdb_reg_ctx);
+  return gdb_reg_ctx->PrivateSetRegisterValue(reg, data);
+}
+
+bool ThreadGDBRemote::PrivateSetRegisterValue(uint32_t reg, uint64_t regval) {
+  GDBRemoteRegisterContext *gdb_reg_ctx =
+      static_cast<GDBRemoteRegisterContext *>(GetRegisterContext().get());
+  assert(gdb_reg_ctx);
+  return gdb_reg_ctx->PrivateSetRegisterValue(reg, regval);
+}
+
+bool ThreadGDBRemote::CalculateStopInfo() {
+  ProcessSP process_sp(GetProcess());
+  if (process_sp)
+    return static_cast<ProcessGDBRemote *>(process_sp.get())
+        ->CalculateThreadStopInfo(this);
+  return false;
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index d452042..27caf42 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -27,125 +27,94 @@
 
 class ProcessGDBRemote;
 
-class ThreadGDBRemote : public Thread
-{
+class ThreadGDBRemote : public Thread {
 public:
-    ThreadGDBRemote (Process &process, lldb::tid_t tid);
+  ThreadGDBRemote(Process &process, lldb::tid_t tid);
 
-    ~ThreadGDBRemote() override;
+  ~ThreadGDBRemote() override;
 
-    void
-    WillResume (lldb::StateType resume_state) override;
+  void WillResume(lldb::StateType resume_state) override;
 
-    void
-    RefreshStateAfterStop() override;
+  void RefreshStateAfterStop() override;
 
-    const char *
-    GetName () override;
+  const char *GetName() override;
 
-    const char *
-    GetQueueName () override;
+  const char *GetQueueName() override;
 
-    lldb::QueueKind
-    GetQueueKind () override;
+  lldb::QueueKind GetQueueKind() override;
 
-    lldb::queue_id_t
-    GetQueueID () override;
+  lldb::queue_id_t GetQueueID() override;
 
-    lldb::QueueSP
-    GetQueue () override;
+  lldb::QueueSP GetQueue() override;
 
-    lldb::addr_t
-    GetQueueLibdispatchQueueAddress () override;
+  lldb::addr_t GetQueueLibdispatchQueueAddress() override;
 
-    void
-    SetQueueLibdispatchQueueAddress (lldb::addr_t dispatch_queue_t) override;
+  void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override;
 
-    bool
-    ThreadHasQueueInformation () const override;
+  bool ThreadHasQueueInformation() const override;
 
-    lldb::RegisterContextSP
-    GetRegisterContext () override;
+  lldb::RegisterContextSP GetRegisterContext() override;
 
-    lldb::RegisterContextSP
-    CreateRegisterContextForFrame (StackFrame *frame) override;
+  lldb::RegisterContextSP
+  CreateRegisterContextForFrame(StackFrame *frame) override;
 
-    void
-    Dump (Log *log, uint32_t index);
+  void Dump(Log *log, uint32_t index);
 
-    static bool
-    ThreadIDIsValid (lldb::tid_t thread);
+  static bool ThreadIDIsValid(lldb::tid_t thread);
 
-    bool
-    ShouldStop (bool &step_more);
+  bool ShouldStop(bool &step_more);
 
-    const char *
-    GetBasicInfoAsString ();
+  const char *GetBasicInfoAsString();
 
-    void
-    SetName (const char *name) override
-    {
-        if (name && name[0])
-            m_thread_name.assign (name);
-        else
-            m_thread_name.clear();
-    }
+  void SetName(const char *name) override {
+    if (name && name[0])
+      m_thread_name.assign(name);
+    else
+      m_thread_name.clear();
+  }
 
-    lldb::addr_t
-    GetThreadDispatchQAddr ()
-    {
-        return m_thread_dispatch_qaddr;
-    }
+  lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
 
-    void
-    SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
-    {
-        m_thread_dispatch_qaddr = thread_dispatch_qaddr;
-    }
+  void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
+    m_thread_dispatch_qaddr = thread_dispatch_qaddr;
+  }
 
-    void
-    ClearQueueInfo ();
-    
-    void
-    SetQueueInfo (std::string &&queue_name, lldb::QueueKind queue_kind, uint64_t queue_serial, lldb::addr_t dispatch_queue_t, lldb_private::LazyBool associated_with_libdispatch_queue);
+  void ClearQueueInfo();
 
-    lldb_private::LazyBool
-    GetAssociatedWithLibdispatchQueue () override;
+  void SetQueueInfo(std::string &&queue_name, lldb::QueueKind queue_kind,
+                    uint64_t queue_serial, lldb::addr_t dispatch_queue_t,
+                    lldb_private::LazyBool associated_with_libdispatch_queue);
 
-    void
-    SetAssociatedWithLibdispatchQueue (lldb_private::LazyBool associated_with_libdispatch_queue) override;
+  lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() override;
 
-    StructuredData::ObjectSP
-    FetchThreadExtendedInfo () override;
+  void SetAssociatedWithLibdispatchQueue(
+      lldb_private::LazyBool associated_with_libdispatch_queue) override;
+
+  StructuredData::ObjectSP FetchThreadExtendedInfo() override;
 
 protected:
-    friend class ProcessGDBRemote;
+  friend class ProcessGDBRemote;
 
-    std::string m_thread_name;
-    std::string m_dispatch_queue_name;
-    lldb::addr_t m_thread_dispatch_qaddr;
-    lldb::addr_t m_dispatch_queue_t;
-    lldb::QueueKind m_queue_kind;     // Queue info from stop reply/stop info for thread
-    uint64_t m_queue_serial_number;   // Queue info from stop reply/stop info for thread
-    lldb_private::LazyBool m_associated_with_libdispatch_queue;
+  std::string m_thread_name;
+  std::string m_dispatch_queue_name;
+  lldb::addr_t m_thread_dispatch_qaddr;
+  lldb::addr_t m_dispatch_queue_t;
+  lldb::QueueKind
+      m_queue_kind; // Queue info from stop reply/stop info for thread
+  uint64_t
+      m_queue_serial_number; // Queue info from stop reply/stop info for thread
+  lldb_private::LazyBool m_associated_with_libdispatch_queue;
 
-    bool
-    PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
+  bool PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data);
 
-    bool
-    PrivateSetRegisterValue (uint32_t reg, 
-                             uint64_t regval);
+  bool PrivateSetRegisterValue(uint32_t reg, uint64_t regval);
 
-    bool
-    CachedQueueInfoIsValid() const
-    {
-        return m_queue_kind != lldb::eQueueKindUnknown;
-    }
-    void
-    SetStopInfoFromPacket (StringExtractor &stop_packet, uint32_t stop_id);
+  bool CachedQueueInfoIsValid() const {
+    return m_queue_kind != lldb::eQueueKindUnknown;
+  }
+  void SetStopInfoFromPacket(StringExtractor &stop_packet, uint32_t stop_id);
 
-    bool
-    CalculateStopInfo () override;
+  bool CalculateStopInfo() override;
 };
 
 } // namespace process_gdb_remote
