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


#include "GDBRemoteCommunication.h"

// C Includes
#include <limits.h>
#include <string.h>
#include <sys/stat.h>

// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/Log.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Target/Process.h"
#include "llvm/ADT/SmallString.h"

// Project includes
#include "ProcessGDBRemoteLog.h"

#if defined(__APPLE__)
# define DEBUGSERVER_BASENAME    "debugserver"
#else
# define DEBUGSERVER_BASENAME    "lldb-server"
#endif

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

#if defined (HAVE_LIBZ)
#include <zlib.h>
#endif

using namespace lldb;
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 ()
{
}

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::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 (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) :
    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_sequence_mutex (Mutex::eMutexTypeRecursive),
    m_public_is_running (false),
    m_private_is_running (false),
    m_history (512),
    m_send_acks (true),
    m_compression_type (CompressionType::None),
    m_listen_url ()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
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();
}

char
GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length)
{
    int checksum = 0;

    for (size_t i = 0; i < payload_length; ++i)
        checksum += payload[i];

    return checksum & 255;
}

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::SendPacket (const char *payload, size_t payload_length)
{
    Mutex::Locker locker(m_sequence_mutex);
    return SendPacketNoLock (payload, payload_length);
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
{
    if (IsConnected())
    {
        StreamString packet(0, 4, eByteOrderBig);

        packet.PutChar('$');
        packet.Write (payload, payload_length);
        packet.PutChar('#');
        packet.PutHex8(CalculcateChecksum (payload, payload_length));

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

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

bool
GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
{
    if (IsRunning())
        return locker.TryLock (m_sequence_mutex, failure_message);

    locker.Lock (m_sequence_mutex);
    return true;
}


bool
GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
{
    return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
}

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


// 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)
{
    // Calculate absolute timeout value
    TimeValue timeout = TimeValue::Now();
    timeout.OffsetWithMicroSeconds(timeout_usec);

    do
    {
        // scope for the mutex
        {
            // lock down the packet queue
            Mutex::Locker locker(m_packet_queue_mutex);

            // Wait on condition variable.
            if (m_packet_queue.size() == 0)
                m_condition_queue_not_empty.Wait(m_packet_queue_mutex, &timeout);

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

                // we got a packet
                return PacketResult::Success;
            }
         }

         // Disconnected
         if (!IsConnected())
             return PacketResult::ErrorDisconnected;

      // Loop while not timed out
    } while (TimeValue::Now() < timeout);

    return PacketResult::ErrorReplyTimeout;
}


GDBRemoteCommunication::PacketResult
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));

    // 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,
                         __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;

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

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;
    if (m_bytes[pkt_size - 3] != '#')
        return true;
    if (!::isxdigit (m_bytes[pkt_size - 2]) || !::isxdigit (m_bytes[pkt_size - 1]))
        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 hash_mark_idx = pkt_size - 3;    // The '#' character marking the end of the packet
    size_t checksum_idx = pkt_size - 2;     // The first character of the two hex checksum characters

    // 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, pkt_size);
                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 (m_bytes.data() + 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, pkt_size);
            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, pkt_size);
            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, pkt_size);
        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 ((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 = new_packet;

    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
    Mutex::Locker locker(m_bytes_mutex);
    
    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);
    }

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

        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;

            case '%': // Async notify packet
                isNotifyPacket = true;
                // Intentional fall through

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

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

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

            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.c_str(), packet_str.size());
                        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;
            else
                return GDBRemoteCommunication::PacketType::Standard;
        }
    }
    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");
    }
    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;
}

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

Error
GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
                                                 uint16_t in_port,
                                                 ProcessLaunchInfo &launch_info,
                                                 uint16_t &out_port)
{
    Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
    if (log)
        log->Printf ("GDBRemoteCommunication::%s(hostname=%s, in_port=%" PRIu16 ", out_port=%" PRIu16, __FUNCTION__, hostname ? hostname : "<empty>", in_port, out_port);

    out_port = in_port;
    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() 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 ());

                g_debugserver_file_spec = debugserver_file_spec;
            }
            else
            {
                if (log)
                    log->Printf ("GDBRemoteCommunication::%s() could not find gdb-remote stub exe '%s'", __FUNCTION__, debugserver_file_spec.GetPath ().c_str ());

                g_debugserver_file_spec.Clear();
                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];

        // 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");
#endif

        // If a host and port is supplied then use it
        char host_and_port[128];
        if (hostname)
        {
            snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port);
            debugserver_args.AppendArgument(host_and_port);
        }
        else
        {
            host_and_port[0] = '\0';
        }

        // use native registers, not the GDB registers
        debugserver_args.AppendArgument("--native-regs");

        if (launch_info.GetLaunchInSeparateProcessGroup())
        {
            debugserver_args.AppendArgument("--setsid");
        }

        llvm::SmallString<PATH_MAX> named_pipe_path;
        Pipe port_pipe;

        if (host_and_port[0] && in_port == 0)
        {
            // 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"

            // Binding to port zero, we need to figure out what port it ends up
            // using using a named pipe...
            error = port_pipe.CreateWithUniqueName("debugserver-named-pipe", false, named_pipe_path);
            if (error.Success())
            {
                debugserver_args.AppendArgument("--named-pipe");
                debugserver_args.AppendArgument(named_pipe_path.c_str());
            }
            else
            {
                if (log)
                    log->Printf("GDBRemoteCommunication::%s() "
                            "named pipe creation failed: %s",
                            __FUNCTION__, error.AsCString());
                // let's try an unnamed pipe
                error = port_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 = port_pipe.GetWriteFileDescriptor();
                debugserver_args.AppendArgument("--pipe");
                debugserver_args.AppendArgument(std::to_string(write_fd).c_str());
                launch_info.AppendCloseFileAction(port_pipe.GetReadFileDescriptor());
            }
        }
        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
            out_port = connection->GetListeningPort(10);
            if (out_port > 0)
            {
                char port_cstr[32];
                snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", out_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);
            }
            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);
        }
#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);
        }
#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;

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

        // 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);
        
        error = Host::LaunchProcess(launch_info);
        
        if (error.Success() && launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
        {
            if (named_pipe_path.size() > 0)
            {
                error = port_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 (port_pipe.CanWrite())
                port_pipe.CloseWriteFileDescriptor();
            if (port_pipe.CanRead())
            {
                char port_cstr[256];
                port_cstr[0] = '\0';
                size_t num_bytes = sizeof(port_cstr);
                // Read port from pipe with 10 second timeout.
                error = port_pipe.ReadWithTimeout(port_cstr, num_bytes,
                        std::chrono::seconds{10}, num_bytes);
                if (error.Success())
                {
                    assert(num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
                    out_port = StringConvert::ToUInt32(port_cstr, 0);
                    if (log)
                        log->Printf("GDBRemoteCommunication::%s() "
                                "debugserver listens %u port",
                                __FUNCTION__, out_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());

                }
                port_pipe.Close();
            }

            if (named_pipe_path.size() > 0)
            {
                const auto err = port_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 );
    }

    if (error.Fail())
    {
        if (log)
            log->Printf ("GDBRemoteCommunication::%s() failed: %s", __FUNCTION__, error.AsCString());
    }

    return error;
}

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 ()
{
    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
// 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;

    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;

        // 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
                Mutex::Locker locker(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.Signal();

            }
        }

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