[PATCH 1/3] simplify decompression code

Tom Tromey tromey@redhat.com
Tue Oct 16 20:45:00 GMT 2012


While working on PR 14704, I realized that BFD has its own code to
decompress section data.  This code is enabled under the same
conditions that the zlib code in gdb is enabled.

This patch simplifies gdb by having it use the BFD code in this
situation.

Built and regtested on x86-64 F16.

	* gdb_bfd.c (zlib_decompress_section): Remove.
	(gdb_bfd_map_section): Only check for compressed section
	in mmap case.  Use bfd_get_full_section_contents.
---
 gdb/gdb_bfd.c |  126 ++++++++-------------------------------------------------
 1 files changed, 17 insertions(+), 109 deletions(-)

diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
index a346cfb..f334e27 100644
--- a/gdb/gdb_bfd.c
+++ b/gdb/gdb_bfd.c
@@ -337,98 +337,6 @@ get_section_descriptor (asection *section)
   return result;
 }
 
-/* Decompress a section that was compressed using zlib.  Store the
-   decompressed buffer, and its size, in DESCRIPTOR.  */
-
-static void
-zlib_decompress_section (asection *sectp,
-			 struct gdb_bfd_section_data *descriptor)
-{
-  bfd *abfd = sectp->owner;
-#ifndef HAVE_ZLIB_H
-  error (_("Support for zlib-compressed data (from '%s', section '%s') "
-           "is disabled in this copy of GDB"),
-         bfd_get_filename (abfd),
-	 bfd_get_section_name (abfd, sectp));
-#else
-  bfd_size_type compressed_size = bfd_get_section_size (sectp);
-  gdb_byte *compressed_buffer = xmalloc (compressed_size);
-  struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
-  struct cleanup *inner_cleanup;
-  bfd_size_type uncompressed_size;
-  gdb_byte *uncompressed_buffer;
-  z_stream strm;
-  int rc;
-  int header_size = 12;
-
-  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
-      || bfd_bread (compressed_buffer,
-		    compressed_size, abfd) != compressed_size)
-    error (_("can't read data from '%s', section '%s'"),
-           bfd_get_filename (abfd),
-	   bfd_get_section_name (abfd, sectp));
-
-  /* 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
-      || strncmp (compressed_buffer, "ZLIB", 4) != 0)
-    error (_("corrupt ZLIB header from '%s', section '%s'"),
-           bfd_get_filename (abfd),
-	   bfd_get_section_name (abfd, sectp));
-  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];
-
-  /* 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;
-  uncompressed_buffer = xmalloc (uncompressed_size);
-  inner_cleanup = make_cleanup (xfree, uncompressed_buffer);
-  rc = inflateInit (&strm);
-  while (strm.avail_in > 0)
-    {
-      if (rc != Z_OK)
-        error (_("setting up uncompression in '%s', section '%s': %d"),
-               bfd_get_filename (abfd),
-	       bfd_get_section_name (abfd, sectp),
-	       rc);
-      strm.next_out = ((Bytef*) uncompressed_buffer
-                       + (uncompressed_size - strm.avail_out));
-      rc = inflate (&strm, Z_FINISH);
-      if (rc != Z_STREAM_END)
-        error (_("zlib error uncompressing from '%s', section '%s': %d"),
-               bfd_get_filename (abfd),
-	       bfd_get_section_name (abfd, sectp),
-	       rc);
-      rc = inflateReset (&strm);
-    }
-  rc = inflateEnd (&strm);
-  if (rc != Z_OK
-      || strm.avail_out != 0)
-    error (_("concluding uncompression in '%s', section '%s': %d"),
-           bfd_get_filename (abfd),
-	   bfd_get_section_name (abfd, sectp),
-	   rc);
-
-  discard_cleanups (inner_cleanup);
-  do_cleanups (cleanup);
-
-  /* Attach the data to the BFD section.  */
-  descriptor->data = uncompressed_buffer;
-  descriptor->size = uncompressed_size;
-#endif
-}
-
 /* See gdb_bfd.h.  */
 
 const gdb_byte *
@@ -437,6 +345,7 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
   bfd *abfd;
   unsigned char header[4];
   struct gdb_bfd_section_data *descriptor;
+  bfd_byte *data;
 
   gdb_assert ((sectp->flags & SEC_RELOC) == 0);
   gdb_assert (size != NULL);
@@ -449,20 +358,19 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
   if (descriptor->data != NULL)
     goto done;
 
-  /* Check if the file has a 4-byte header indicating compression.  */
+#ifdef HAVE_MMAP
+  /* Check if the file has a 4-byte header indicating compression.
+     Note that we can't use bfd_is_section_compressed here, because
+     that does not work if the BFD_DECOMPRESS flag is set.  */
   if (bfd_get_section_size (sectp) > sizeof (header)
       && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
       && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
     {
       /* Upon decompression, update the buffer and its size.  */
       if (strncmp (header, "ZLIB", sizeof (header)) == 0)
-        {
-          zlib_decompress_section (sectp, descriptor);
-	  goto done;
-        }
+	goto no_mmap;
     }
 
-#ifdef HAVE_MMAP
   {
     /* The page size, used when mmapping.  */
     static int pagesize;
@@ -496,20 +404,20 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
   }
 #endif /* HAVE_MMAP */
 
-  /* If we get here, we are a normal, not-compressed section.  */
+ no_mmap:
+
+  /* Handle compressed sections, or ordinary uncompressed sections in
+     the no-mmap case.  */
 
   descriptor->size = bfd_get_section_size (sectp);
-  descriptor->data = xmalloc (descriptor->size);
+  descriptor->data = NULL;
 
-  if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
-      || bfd_bread (descriptor->data, bfd_get_section_size (sectp),
-		    abfd) != bfd_get_section_size (sectp))
-    {
-      xfree (descriptor->data);
-      descriptor->data = NULL;
-      error (_("Can't read data for section '%s'"),
-	     bfd_get_filename (abfd));
-    }
+  data = NULL;
+  if (!bfd_get_full_section_contents (abfd, sectp, &data))
+    error (_("Can't read data for section '%s' in file '%s'"),
+	   bfd_get_section_name (abfd, sectp),
+	   bfd_get_filename (abfd));
+  descriptor->data = data;
 
  done:
   gdb_assert (descriptor->data != NULL);
-- 
1.7.7.6



More information about the Gdb-patches mailing list