Force libcompression calls to be enabled when building on Darwin
systems.  It has been available in the OS over over three years
now.  If lldb doesn't link against -lcompression, it should be an
error.

Allocate a scratch buffer for libcompression to use when decoding
packets, instead of it having to allocate & free one on every call.

Fix a typeo with the size of the buffer that compression_decode_buffer()
is expanding into.

<rdar://problem/41601084> 

llvm-svn: 349563
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index 4605bd2e..e63b51e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -42,7 +42,8 @@
 #define DEBUGSERVER_BASENAME "lldb-server"
 #endif
 
-#if defined(HAVE_LIBCOMPRESSION)
+#if defined(__APPLE__)
+#define HAVE_LIBCOMPRESSION
 #include <compression.h>
 #endif
 
@@ -67,7 +68,9 @@
 #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_listen_url(), m_decompression_scratch_type(CompressionType::None),
+      m_decompression_scratch(nullptr)
+{ 
 }
 
 //----------------------------------------------------------------------
@@ -532,7 +535,7 @@
   size_t decompressed_bytes = 0;
 
   if (decompressed_bufsize != ULONG_MAX) {
-    decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1);
+    decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize);
     if (decompressed_buffer == nullptr) {
       m_bytes.erase(0, size_of_first_packet);
       return false;
@@ -540,11 +543,10 @@
   }
 
 #if defined(HAVE_LIBCOMPRESSION)
-  // libcompression is weak linked so check that compression_decode_buffer() is
-  // available
   if (m_compression_type == CompressionType::ZlibDeflate ||
       m_compression_type == CompressionType::LZFSE ||
-      m_compression_type == CompressionType::LZ4) {
+      m_compression_type == CompressionType::LZ4 || 
+      m_compression_type == CompressionType::LZMA) {
     compression_algorithm compression_type;
     if (m_compression_type == CompressionType::LZFSE)
       compression_type = COMPRESSION_LZFSE;
@@ -555,16 +557,33 @@
     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 (m_decompression_scratch_type != m_compression_type) {
+      if (m_decompression_scratch) {
+        free (m_decompression_scratch);
+        m_decompression_scratch = nullptr;
+      }
+      size_t scratchbuf_size = 0;
+      if (m_compression_type == CompressionType::LZFSE)
+        scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE);
+      else if (m_compression_type == CompressionType::LZ4)
+        scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZ4_RAW);
+      else if (m_compression_type == CompressionType::ZlibDeflate)
+        scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_ZLIB);
+      else if (m_compression_type == CompressionType::LZMA)
+        scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZMA);
+      else if (m_compression_type == CompressionType::LZFSE)
+        scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE);
+      if (scratchbuf_size > 0) {
+        m_decompression_scratch = (void*) malloc (scratchbuf_size);
+        m_decompression_scratch_type = m_compression_type;
+      }
+    }
 
     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);
+          decompressed_buffer, decompressed_bufsize,
+          (uint8_t *)unescaped_content.data(), unescaped_content.size(), 
+          m_decompression_scratch, compression_type);
     }
   }
 #endif
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index d2e21f4b..369eb25 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -218,6 +218,9 @@
   HostThread m_listen_thread;
   std::string m_listen_url;
 
+  CompressionType m_decompression_scratch_type;
+  void *m_decompression_scratch;
+
   DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication);
 };
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 92bde03..1e12ea6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -37,7 +37,8 @@
 
 #include "llvm/ADT/StringSwitch.h"
 
-#if defined(HAVE_LIBCOMPRESSION)
+#if defined(__APPLE__)
+#define HAVE_LIBCOMPRESSION
 #include <compression.h>
 #endif