Fix decompression logic.
diff --git a/libdwfl/gzip.c b/libdwfl/gzip.c
index effde5f..ed602a6 100644
--- a/libdwfl/gzip.c
+++ b/libdwfl/gzip.c
@@ -52,6 +52,7 @@
 #include <unistd.h>
 
 #ifdef BZLIB
+# define inflate_groks_header	true
 # include <bzlib.h>
 # define unzip		__libdw_bunzip2
 # define DWFL_E_ZLIB	DWFL_E_BZLIB
@@ -66,6 +67,7 @@
 # define gzread		BZ2_bzread
 # define gzclose	BZ2_bzclose
 #else
+# define inflate_groks_header	false
 # include <zlib.h>
 # define unzip		__libdw_gunzip
 # define MAGIC		"\037\213"
@@ -115,19 +117,25 @@
     return failure;
   }
 
-  if (mapped != NULL)
+  /* If the file is already mapped in, look at the header.  */
+  if (mapped != NULL
+      && (mapped_size <= sizeof MAGIC
+	  || memcmp (mapped, MAGIC, sizeof MAGIC - 1)))
+    /* Not a compressed file.  */
+    return DWFL_E_BADELF;
+
+  if (mapped != NULL && inflate_groks_header)
     {
-      /* The file is already mapped in.  Look at the header.  */
-      if (mapped_size <= sizeof MAGIC || memcmp (mapped, MAGIC, sizeof MAGIC))
-	/* Not a compressed file.  */
-	return DWFL_E_CB;
+      /* This style actually only works with bzlib.
+	 The stupid zlib interface has nothing to grok the
+	 gzip file headers except the slow gzFile interface.  */
 
       z_stream z = { .next_in = mapped, .avail_in = mapped_size };
       int result = inflateInit (&z);
       if (result != Z (OK))
 	return zlib_fail (result);
 
-      while ((result = inflate (&z, Z_SYNC_FLUSH)) == Z (OK))
+      do
 	{
 	  ptrdiff_t pos = (void *) z.next_out - buffer;
 	  if (!bigger_buffer (z.avail_in))
@@ -138,6 +146,7 @@
 	  z.next_out = buffer + pos;
 	  z.avail_out = size - pos;
 	}
+      while ((result = inflate (&z, Z_SYNC_FLUSH)) == Z (OK));
 
 #ifdef BZLIB
       uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32)
@@ -154,16 +163,18 @@
     }
   else
     {
+      /* Let the decompression library read the file directly.  */
+
       int d = dup (fd);
       if (unlikely (d < 0))
-	return DWFL_E_CB;
+	return DWFL_E_BADELF;
       if (start_offset != 0)
 	{
 	  off64_t off = lseek (d, start_offset, SEEK_SET);
 	  if (off != start_offset)
 	    {
 	      close (d);
-	      return DWFL_E_CB;
+	      return DWFL_E_BADELF;
 	    }
 	}
       gzFile zf = gzdopen (d, "r");
@@ -179,7 +190,7 @@
       if (gzdirect (zf))
 	{
 	  gzclose (zf);
-	  return DWFL_E_CB;
+	  return DWFL_E_BADELF;
 	}
 #endif
 
@@ -201,7 +212,7 @@
 		{
 		  gzclose (zf);
 		  free (buffer);
-		  return DWFL_E_CB;
+		  return DWFL_E_BADELF;
 		}
 #endif
 	      gzclose (zf);
@@ -219,5 +230,5 @@
   *whole = buffer;
   *whole_size = size;
 
-return DWFL_E_NOERROR;
+  return DWFL_E_NOERROR;
 }