Don't write to inferior_ptid in infrun.c
[deliverable/binutils-gdb.git] / bfd / compress.c
index fe1b0fd3b33f995a51e76037145c3b58f547543d..728ba39dfbf748c688bb8c9f1a8d28c5a1ae9bd0 100644 (file)
@@ -1,6 +1,5 @@
 /* Compressed section support (intended for debug sections).
 /* Compressed section support (intended for debug sections).
-   Copyright 2008, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2008-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 
    This file is part of BFD, the Binary File Descriptor library.
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#include "config.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include <zlib.h>
 #include "bfd.h"
 #include "libbfd.h"
 #include "bfd.h"
 #include "libbfd.h"
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
+#include "safe-ctype.h"
+
+#define MAX_COMPRESSION_HEADER_SIZE 24
+
+static bfd_boolean
+decompress_contents (bfd_byte *compressed_buffer,
+                    bfd_size_type compressed_size,
+                    bfd_byte *uncompressed_buffer,
+                    bfd_size_type uncompressed_size)
+{
+  z_stream strm;
+  int rc;
+
+  /* It is possible the section consists of several compressed
+     buffers concatenated together, so we uncompress in a loop.  */
+  /* PR 18313: The state field in the z_stream structure is supposed
+     to be invisible to the user (ie us), but some compilers will
+     still complain about it being used without initialisation.  So
+     we first zero the entire z_stream structure and then set the fields
+     that we need.  */
+  memset (& strm, 0, sizeof strm);
+  strm.avail_in = compressed_size;
+  strm.next_in = (Bytef*) compressed_buffer;
+  strm.avail_out = uncompressed_size;
+
+  BFD_ASSERT (Z_OK == 0);
+  rc = inflateInit (&strm);
+  while (strm.avail_in > 0 && strm.avail_out > 0)
+    {
+      if (rc != Z_OK)
+       break;
+      strm.next_out = ((Bytef*) uncompressed_buffer
+                      + (uncompressed_size - strm.avail_out));
+      rc = inflate (&strm, Z_FINISH);
+      if (rc != Z_STREAM_END)
+       break;
+      rc = inflateReset (&strm);
+    }
+  rc |= inflateEnd (&strm);
+  return rc == Z_OK && strm.avail_out == 0;
+}
+
+/* Compress data of the size specified in @var{uncompressed_size}
+   and pointed to by @var{uncompressed_buffer} using zlib and store
+   as the contents field.  This function assumes the contents
+   field was allocated using bfd_malloc() or equivalent.
+
+   Return the uncompressed size if the full section contents is
+   compressed successfully.  Otherwise return 0.  */
+
+static bfd_size_type
+bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
+                              bfd_byte *uncompressed_buffer,
+                              bfd_size_type uncompressed_size)
+{
+  uLong compressed_size;
+  bfd_byte *buffer;
+  bfd_size_type buffer_size;
+  bfd_boolean decompress;
+  int zlib_size = 0;
+  int orig_compression_header_size;
+  bfd_size_type orig_uncompressed_size;
+  unsigned int orig_uncompressed_alignment_pow;
+  int header_size = bfd_get_compression_header_size (abfd, NULL);
+  bfd_boolean compressed
+    = bfd_is_section_compressed_with_header (abfd, sec,
+                                            &orig_compression_header_size,
+                                            &orig_uncompressed_size,
+                                            &orig_uncompressed_alignment_pow);
+
+  /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
+     overhead in .zdebug* section.  */
+  if (!header_size)
+     header_size = 12;
+
+  if (compressed)
+    {
+      /* We shouldn't decompress unsupported compressed section.  */
+      if (orig_compression_header_size < 0)
+       abort ();
+
+      /* Different compression schemes.  Just move the compressed section
+        contents to the right position. */
+      if (orig_compression_header_size == 0)
+       {
+         /* Convert it from .zdebug* section.  Get the uncompressed
+            size first.  We need to subtract the 12-byte overhead in
+            .zdebug* section.  Set orig_compression_header_size to
+            the 12-bye overhead.  */
+         orig_compression_header_size = 12;
+         zlib_size = uncompressed_size - 12;
+       }
+      else
+       {
+         /* Convert it to .zdebug* section.  */
+         zlib_size = uncompressed_size - orig_compression_header_size;
+       }
+
+      /* Add the header size.  */
+      compressed_size = zlib_size + header_size;
+    }
+  else
+    compressed_size = compressBound (uncompressed_size) + header_size;
+
+  /* Uncompress if it leads to smaller size.  */
+  if (compressed && compressed_size > orig_uncompressed_size)
+    {
+      decompress = TRUE;
+      buffer_size = orig_uncompressed_size;
+    }
+  else
+    {
+      decompress = FALSE;
+      buffer_size = compressed_size;
+    }
+  buffer = (bfd_byte *) bfd_alloc (abfd, buffer_size);
+  if (buffer == NULL)
+    return 0;
+
+  if (compressed)
+    {
+      sec->size = orig_uncompressed_size;
+      if (decompress)
+       {
+         if (!decompress_contents (uncompressed_buffer
+                                   + orig_compression_header_size,
+                                   zlib_size, buffer, buffer_size))
+           {
+             bfd_set_error (bfd_error_bad_value);
+             bfd_release (abfd, buffer);
+             return 0;
+           }
+         free (uncompressed_buffer);
+         bfd_set_section_alignment (sec, orig_uncompressed_alignment_pow);
+
+         sec->contents = buffer;
+         sec->compress_status = COMPRESS_SECTION_DONE;
+         return orig_uncompressed_size;
+       }
+      else
+       {
+         bfd_update_compression_header (abfd, buffer, sec);
+         memmove (buffer + header_size,
+                  uncompressed_buffer + orig_compression_header_size,
+                  zlib_size);
+       }
+    }
+  else
+    {
+      if (compress ((Bytef*) buffer + header_size,
+                   &compressed_size,
+                   (const Bytef*) uncompressed_buffer,
+                   uncompressed_size) != Z_OK)
+       {
+         bfd_release (abfd, buffer);
+         bfd_set_error (bfd_error_bad_value);
+         return 0;
+       }
+
+      compressed_size += header_size;
+      /* PR binutils/18087: If compression didn't make the section smaller,
+        just keep it uncompressed.  */
+      if (compressed_size < uncompressed_size)
+       bfd_update_compression_header (abfd, buffer, sec);
+      else
+       {
+         /* NOTE: There is a small memory leak here since
+            uncompressed_buffer is malloced and won't be freed.  */
+         bfd_release (abfd, buffer);
+         sec->contents = uncompressed_buffer;
+         sec->compress_status = COMPRESS_SECTION_NONE;
+         return uncompressed_size;
+       }
+    }
+
+  free (uncompressed_buffer);
+  sec->contents = buffer;
+  sec->size = compressed_size;
+  sec->compress_status = COMPRESS_SECTION_DONE;
+
+  return uncompressed_size;
+}
+
+/*
+FUNCTION
+       bfd_get_full_section_contents
+
+SYNOPSIS
+       bfd_boolean bfd_get_full_section_contents
+         (bfd *abfd, asection *section, bfd_byte **ptr);
+
+DESCRIPTION
+       Read all data from @var{section} in BFD @var{abfd}, decompress
+       if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
+       return @var{*ptr} with memory malloc'd by this function.
+
+       Return @code{TRUE} if the full section contents is retrieved
+       successfully.  If the section has no contents then this function
+       returns @code{TRUE} but @var{*ptr} is set to NULL.
+*/
+
+bfd_boolean
+bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
+{
+  bfd_size_type sz;
+  bfd_byte *p = *ptr;
+  bfd_boolean ret;
+  bfd_size_type save_size;
+  bfd_size_type save_rawsize;
+  bfd_byte *compressed_buffer;
+  unsigned int compression_header_size;
+
+  if (abfd->direction != write_direction && sec->rawsize != 0)
+    sz = sec->rawsize;
+  else
+    sz = sec->size;
+  if (sz == 0)
+    {
+      *ptr = NULL;
+      return TRUE;
+    }
+
+  switch (sec->compress_status)
+    {
+    case COMPRESS_SECTION_NONE:
+      if (p == NULL)
+       {
+         ufile_ptr filesize = bfd_get_file_size (abfd);
+         if (filesize > 0
+             && filesize < sz
+             /* PR 24753: Linker created sections can be larger than
+                the file size, eg if they are being used to hold stubs.  */
+             && (bfd_section_flags (sec) & SEC_LINKER_CREATED) == 0
+             /* PR 24753: Sections which have no content should also be
+                excluded as they contain no size on disk.  */
+             && (bfd_section_flags (sec) & SEC_HAS_CONTENTS) != 0
+             /* The MMO file format supports its own special compression
+                technique, but it uses COMPRESS_SECTION_NONE when loading
+                a section's contents.  */
+             && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
+           {
+             /* PR 24708: Avoid attempts to allocate a ridiculous amount
+                of memory.  */
+             bfd_set_error (bfd_error_no_memory);
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"),
+                abfd, sec, (uint64_t) sz, (uint64_t) filesize);
+             return FALSE;
+           }
+         p = (bfd_byte *) bfd_malloc (sz);
+         if (p == NULL)
+           {
+             /* PR 20801: Provide a more helpful error message.  */
+             if (bfd_get_error () == bfd_error_no_memory)
+               _bfd_error_handler
+                 /* xgettext:c-format */
+                 (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
+                 abfd, sec, (uint64_t) sz);
+             return FALSE;
+           }
+       }
+
+      if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
+       {
+         if (*ptr != p)
+           free (p);
+         return FALSE;
+       }
+      *ptr = p;
+      return TRUE;
+
+    case DECOMPRESS_SECTION_SIZED:
+      /* Read in the full compressed section contents.  */
+      compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
+      if (compressed_buffer == NULL)
+       return FALSE;
+      save_rawsize = sec->rawsize;
+      save_size = sec->size;
+      /* Clear rawsize, set size to compressed size and set compress_status
+        to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
+        the uncompressed size, bfd_get_section_contents will fail.  */
+      sec->rawsize = 0;
+      sec->size = sec->compressed_size;
+      sec->compress_status = COMPRESS_SECTION_NONE;
+      ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
+                                     0, sec->compressed_size);
+      /* Restore rawsize and size.  */
+      sec->rawsize = save_rawsize;
+      sec->size = save_size;
+      sec->compress_status = DECOMPRESS_SECTION_SIZED;
+      if (!ret)
+       goto fail_compressed;
+
+      if (p == NULL)
+       p = (bfd_byte *) bfd_malloc (sz);
+      if (p == NULL)
+       goto fail_compressed;
+
+      compression_header_size = bfd_get_compression_header_size (abfd, sec);
+      if (compression_header_size == 0)
+       /* Set header size to the zlib header size if it is a
+          SHF_COMPRESSED section.  */
+       compression_header_size = 12;
+      if (!decompress_contents (compressed_buffer + compression_header_size,
+                               sec->compressed_size - compression_header_size, p, sz))
+       {
+         bfd_set_error (bfd_error_bad_value);
+         if (p != *ptr)
+           free (p);
+       fail_compressed:
+         free (compressed_buffer);
+         return FALSE;
+       }
+
+      free (compressed_buffer);
+      *ptr = p;
+      return TRUE;
+
+    case COMPRESS_SECTION_DONE:
+      if (sec->contents == NULL)
+       return FALSE;
+      if (p == NULL)
+       {
+         p = (bfd_byte *) bfd_malloc (sz);
+         if (p == NULL)
+           return FALSE;
+         *ptr = p;
+       }
+      /* PR 17512; file: 5bc29788.  */
+      if (p != sec->contents)
+       memcpy (p, sec->contents, sz);
+      return TRUE;
+
+    default:
+      abort ();
+    }
+}
 
 /*
 FUNCTION
 
 /*
 FUNCTION
-       bfd_uncompress_section_contents
+       bfd_cache_section_contents
 
 SYNOPSIS
 
 SYNOPSIS
-       bfd_boolean bfd_uncompress_section_contents
-         (bfd_byte **buffer, bfd_size_type *size);
+       void bfd_cache_section_contents
+         (asection *sec, void *contents);
 
 DESCRIPTION
 
 DESCRIPTION
+       Stash @var(contents) so any following reads of @var(sec) do
+       not need to decompress again.
+*/
+
+void
+bfd_cache_section_contents (asection *sec, void *contents)
+{
+  if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
+    sec->compress_status = COMPRESS_SECTION_DONE;
+  sec->contents = contents;
+  sec->flags |= SEC_IN_MEMORY;
+}
+
+/*
+FUNCTION
+       bfd_is_section_compressed_with_header
+
+SYNOPSIS
+       bfd_boolean bfd_is_section_compressed_with_header
+         (bfd *abfd, asection *section,
+         int *compression_header_size_p,
+         bfd_size_type *uncompressed_size_p,
+         unsigned int *uncompressed_alignment_power_p);
 
 
-       Uncompresses a section that was compressed using zlib, in place.  At
-       the call to this function, *@var{buffer} and *@var{size} should point
-       to the section contents to be uncompressed.  At the end of the
-       function, *@var{buffer} and *@var{size} will point to the uncompressed
-       contents.  This function assumes *BUFFER was allocated using
-       bfd_malloc() or equivalent.  If the section is not a valid compressed
-       section, or zlib is not installed on this machine, the input is
-       unmodified.
-
-        Returns @code{FALSE} if unable to uncompress successfully; in that case
-        the input is unmodified.  Otherwise, returns @code{TRUE}.
+DESCRIPTION
+       Return @code{TRUE} if @var{section} is compressed.  Compression
+       header size is returned in @var{compression_header_size_p},
+       uncompressed size is returned in @var{uncompressed_size_p}
+       and the uncompressed data alignement power is returned in
+       @var{uncompressed_align_pow_p}.  If compression is
+       unsupported, compression header size is returned with -1
+       and uncompressed size is returned with 0.
 */
 
 bfd_boolean
 */
 
 bfd_boolean
-bfd_uncompress_section_contents (bfd_byte **buffer ATTRIBUTE_UNUSED,
-                                bfd_size_type *size ATTRIBUTE_UNUSED)
+bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
+                                      int *compression_header_size_p,
+                                      bfd_size_type *uncompressed_size_p,
+                                      unsigned int *uncompressed_align_pow_p)
+{
+  bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
+  int compression_header_size;
+  int header_size;
+  unsigned int saved = sec->compress_status;
+  bfd_boolean compressed;
+
+  *uncompressed_align_pow_p = 0;
+
+  compression_header_size = bfd_get_compression_header_size (abfd, sec);
+  if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
+    abort ();
+  header_size = compression_header_size ? compression_header_size : 12;
+
+  /* Don't decompress the section.  */
+  sec->compress_status = COMPRESS_SECTION_NONE;
+
+  /* Read the header.  */
+  if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
+    {
+      if (compression_header_size == 0)
+       /* In this case, it should be "ZLIB" followed by the uncompressed
+          section size, 8 bytes in big-endian order.  */
+       compressed = CONST_STRNEQ ((char*) header , "ZLIB");
+      else
+       compressed = TRUE;
+    }
+  else
+    compressed = FALSE;
+
+  *uncompressed_size_p = sec->size;
+  if (compressed)
+    {
+      if (compression_header_size != 0)
+       {
+         if (!bfd_check_compression_header (abfd, header, sec,
+                                            uncompressed_size_p,
+                                            uncompressed_align_pow_p))
+           compression_header_size = -1;
+       }
+      /* Check for the pathalogical case of a debug string section that
+        contains the string ZLIB.... as the first entry.  We assume that
+        no uncompressed .debug_str section would ever be big enough to
+        have the first byte of its (big-endian) size be non-zero.  */
+      else if (strcmp (sec->name, ".debug_str") == 0
+              && ISPRINT (header[4]))
+       compressed = FALSE;
+      else
+       *uncompressed_size_p = bfd_getb64 (header + 4);
+    }
+
+  /* Restore compress_status.  */
+  sec->compress_status = saved;
+  *compression_header_size_p = compression_header_size;
+  return compressed;
+}
+
+/*
+FUNCTION
+       bfd_is_section_compressed
+
+SYNOPSIS
+       bfd_boolean bfd_is_section_compressed
+         (bfd *abfd, asection *section);
+
+DESCRIPTION
+       Return @code{TRUE} if @var{section} is compressed.
+*/
+
+bfd_boolean
+bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
+{
+  int compression_header_size;
+  bfd_size_type uncompressed_size;
+  unsigned int uncompressed_align_power;
+  return (bfd_is_section_compressed_with_header (abfd, sec,
+                                                &compression_header_size,
+                                                &uncompressed_size,
+                                                &uncompressed_align_power)
+         && compression_header_size >= 0
+         && uncompressed_size > 0);
+}
+
+/*
+FUNCTION
+       bfd_init_section_decompress_status
+
+SYNOPSIS
+       bfd_boolean bfd_init_section_decompress_status
+         (bfd *abfd, asection *section);
+
+DESCRIPTION
+       Record compressed section size, update section size with
+       decompressed size and set compress_status to
+       DECOMPRESS_SECTION_SIZED.
+
+       Return @code{FALSE} if the section is not a valid compressed
+       section.  Otherwise, return @code{TRUE}.
+*/
+
+bfd_boolean
+bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
+{
+  bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
+  int compression_header_size;
+  int header_size;
+  bfd_size_type uncompressed_size;
+  unsigned int uncompressed_alignment_power = 0;
+
+  compression_header_size = bfd_get_compression_header_size (abfd, sec);
+  if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
+    abort ();
+  header_size = compression_header_size ? compression_header_size : 12;
+
+  /* Read the header.  */
+  if (sec->rawsize != 0
+      || sec->contents != NULL
+      || sec->compress_status != COMPRESS_SECTION_NONE
+      || !bfd_get_section_contents (abfd, sec, header, 0, header_size))
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
+
+  if (compression_header_size == 0)
+    {
+      /* In this case, it should be "ZLIB" followed by the uncompressed
+        section size, 8 bytes in big-endian order.  */
+      if (! CONST_STRNEQ ((char*) header, "ZLIB"))
+       {
+         bfd_set_error (bfd_error_wrong_format);
+         return FALSE;
+       }
+      uncompressed_size = bfd_getb64 (header + 4);
+    }
+  else if (!bfd_check_compression_header (abfd, header, sec,
+                                         &uncompressed_size,
+                                         &uncompressed_alignment_power))
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return FALSE;
+    }
+
+  sec->compressed_size = sec->size;
+  sec->size = uncompressed_size;
+  bfd_set_section_alignment (sec, uncompressed_alignment_power);
+  sec->compress_status = DECOMPRESS_SECTION_SIZED;
+
+  return TRUE;
+}
+
+/*
+FUNCTION
+       bfd_init_section_compress_status
+
+SYNOPSIS
+       bfd_boolean bfd_init_section_compress_status
+         (bfd *abfd, asection *section);
+
+DESCRIPTION
+       If open for read, compress section, update section size with
+       compressed size and set compress_status to COMPRESS_SECTION_DONE.
+
+       Return @code{FALSE} if the section is not a valid compressed
+       section.  Otherwise, return @code{TRUE}.
+*/
+
+bfd_boolean
+bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
 {
 {
-#ifndef HAVE_ZLIB_H
-  return FALSE;
-#else
-  bfd_size_type compressed_size = *size;
-  bfd_byte *compressed_buffer = *buffer;
   bfd_size_type uncompressed_size;
   bfd_byte *uncompressed_buffer;
   bfd_size_type uncompressed_size;
   bfd_byte *uncompressed_buffer;
-  z_stream strm;
-  int rc;
-  bfd_size_type header_size = 12;
 
 
-  /* Read the zlib header.  In this case, it should be "ZLIB" followed
-     by the uncompressed section size, 8 bytes in big-endian order.  */
-  if (compressed_size < header_size
-      || ! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
-    return FALSE;
-  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
-  uncompressed_size += compressed_buffer[11];
+  /* Error if not opened for read.  */
+  if (abfd->direction != read_direction
+      || sec->size == 0
+      || sec->rawsize != 0
+      || sec->contents != NULL
+      || sec->compress_status != COMPRESS_SECTION_NONE)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
 
 
-  /* It is possible the section consists of several compressed
-     buffers concatenated together, so we uncompress in a loop.  */
-  strm.zalloc = NULL;
-  strm.zfree = NULL;
-  strm.opaque = NULL;
-  strm.avail_in = compressed_size - header_size;
-  strm.next_in = (Bytef*) compressed_buffer + header_size;
-  strm.avail_out = uncompressed_size;
+  /* Read in the full section contents and compress it.  */
+  uncompressed_size = sec->size;
   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
-  if (! uncompressed_buffer)
+  /* PR 21431 */
+  if (uncompressed_buffer == NULL)
     return FALSE;
 
     return FALSE;
 
-  rc = inflateInit (&strm);
-  while (strm.avail_in > 0)
+  if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
+                                0, uncompressed_size))
+    return FALSE;
+
+  uncompressed_size = bfd_compress_section_contents (abfd, sec,
+                                                    uncompressed_buffer,
+                                                    uncompressed_size);
+  return uncompressed_size != 0;
+}
+
+/*
+FUNCTION
+       bfd_compress_section
+
+SYNOPSIS
+       bfd_boolean bfd_compress_section
+         (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
+DESCRIPTION
+       If open for write, compress section, update section size with
+       compressed size and set compress_status to COMPRESS_SECTION_DONE.
+
+       Return @code{FALSE} if compression fail.  Otherwise, return
+       @code{TRUE}.
+*/
+
+bfd_boolean
+bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
+{
+  bfd_size_type uncompressed_size = sec->size;
+
+  /* Error if not opened for write.  */
+  if (abfd->direction != write_direction
+      || uncompressed_size == 0
+      || uncompressed_buffer == NULL
+      || sec->contents != NULL
+      || sec->compressed_size != 0
+      || sec->compress_status != COMPRESS_SECTION_NONE)
     {
     {
-      if (rc != Z_OK)
-        goto fail;
-      strm.next_out = ((Bytef*) uncompressed_buffer
-                       + (uncompressed_size - strm.avail_out));
-      rc = inflate (&strm, Z_FINISH);
-      if (rc != Z_STREAM_END)
-        goto fail;
-      rc = inflateReset (&strm);
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
     }
     }
-  rc = inflateEnd (&strm);
-  if (rc != Z_OK
-      || strm.avail_out != 0)
-    goto fail;
-
-  free (compressed_buffer);
-  *buffer = uncompressed_buffer;
-  *size = uncompressed_size;
-  return TRUE;
 
 
- fail:
-  free (uncompressed_buffer);
-  return FALSE;
-#endif  /* HAVE_ZLIB_H */
+  /* Compress it.  */
+  return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
+                                       uncompressed_size) != 0;
 }
 }
This page took 0.030274 seconds and 4 git commands to generate.