]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdwfl: Support automatic decompression of files in XZ format.
authorRoland McGrath <roland@redhat.com>
Wed, 26 Aug 2009 09:26:34 +0000 (02:26 -0700)
committerRoland McGrath <roland@redhat.com>
Wed, 26 Aug 2009 09:27:19 +0000 (02:27 -0700)
ChangeLog
NEWS
configure.ac
libdwfl/ChangeLog
libdwfl/Makefile.am
libdwfl/gzip.c
libdwfl/libdwflP.h
libdwfl/lzma.c [new file with mode: 0644]
libdwfl/open.c
m4/ChangeLog
m4/zip.m4

index 7b8c4438b396c9376759ab18a1b3685bd26e5574..8b535e09aa0cd9c9a82ce664459ed828ee7a95fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-08-26  Roland McGrath  <roland@redhat.com>
+
+       * configure.ac (zip_LIBS): Check for liblzma too.
+
 2009-04-19  Roland McGrath  <roland@redhat.com>
 
        * configure.ac (eu_version): Round down here, not in version.h macros.
diff --git a/NEWS b/NEWS
index e0ff9dcc866f02619572d5206004d36f0a03e874..0f964d76cefd8ff4e4e2e5fb2641e08db6e396f8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ libdw: Various convenience functions for individual attributes now use
        dwarf_attr_integrate to look up indirect inherited attributes.
 
 libdwfl: Support Linux bzip2 kernel images for automatic decompression.
+        Support automatic decompression of files in XZ format.
 
 Version 0.142:
 
index f5a3c527ccd62326d37be6cbdbeeb49ef41565f9..f1118c6b46c89f86df98fe9549f08d587db86f51 100644 (file)
@@ -203,8 +203,9 @@ dnl Test for zlib and bzlib, gives ZLIB/BZLIB .am
 dnl conditional and config.h USE_ZLIB/USE_BZLIB #define.
 save_LIBS="$LIBS"
 LIBS=
-eu_ZIPLIB(z,Z,z,gzdirect,gzip)
-eu_ZIPLIB(bz,BZ,bz2,BZ2_bzdopen,bzip2)
+eu_ZIPLIB(zlib,ZLIB,z,gzdirect,gzip)
+eu_ZIPLIB(bzlib,BZLIB,bz2,BZ2_bzdopen,bzip2)
+eu_ZIPLIB(lzma,LZMA,lzma,lzma_auto_decoder,[LZMA (xz)])
 zip_LIBS="$LIBS"
 LIBS="$save_LIBS"
 AC_SUBST([zip_LIBS])
index ddfd3259571d2d12888fcdbec5cd608e72a605fd..46c70b30598d4cb0c272b0580a3786466ec1ee20 100644 (file)
@@ -1,5 +1,12 @@
 2009-08-26  Roland McGrath  <roland@redhat.com>
 
+       * open.c [USE_LZMA]: Try __libdw_unlzma.
+       * libdwflP.h: Declare it.
+       (DWFL_ERRORS): Add DWFL_E_LZMA.
+       * gzip.c [LZMA]: Implement liblzma version for XZ file format.
+       * lzma.c: New file.
+       * Makefile.am [LZMA] (libdwfl_a_SOURCES): Add it.
+
        * gzip.c (mapped_zImage): Limit scan to 32kb.
        Make this unconditional, support bzip2 kernel images too.
        (unzip): Use direct inflate method for non-mmap case too.
index adc8a2894d53dc1dcf72c6cbb735ee8706ebbf1b..af83a96e64635fa410d23fa8ae3ffac6b1b2d591 100644 (file)
@@ -82,6 +82,9 @@ endif
 if BZLIB
 libdwfl_a_SOURCES += bzip2.c
 endif
+if LZMA
+libdwfl_a_SOURCES += lzma.c
+endif
 
 if MUDFLAP
 libdwfl = libdwfl.a $(libdw) $(libebl) $(libelf) $(libeu)
index 9b87192089c390db0214f201f8ad6eb556229e38..67f203f8ea75c7a5fab5487e6eb50c17339fbc4a 100644 (file)
 
 #include <unistd.h>
 
-#ifdef BZLIB
+#ifdef LZMA
+# define USE_INFLATE   1
+# include <lzma.h>
+# define unzip         __libdw_unlzma
+# define DWFL_E_ZLIB   DWFL_E_LZMA
+# define MAGIC         "\xFD" "7zXZ\0"
+# define Z(what)       LZMA_##what
+# define LZMA_ERRNO    LZMA_PROG_ERROR
+# define z_stream      lzma_stream
+# define inflateInit(z)        lzma_auto_decoder (z, 1 << 30, 0)
+# define do_inflate(z) lzma_code (z, LZMA_RUN)
+# define inflateEnd(z) lzma_end (z)
+#elif defined BZLIB
 # define USE_INFLATE   1
 # include <bzlib.h>
 # define unzip         __libdw_bunzip2
 # define BZ_ERRNO      BZ_IO_ERROR
 # define z_stream      bz_stream
 # define inflateInit(z)        BZ2_bzDecompressInit (z, 0, 0)
-# define inflate(z, f) BZ2_bzDecompress (z)
+# define do_inflate(z) BZ2_bzDecompress (z)
 # define inflateEnd(z) BZ2_bzDecompressEnd (z)
-# define gzFile                BZFILE *
-# define gzdopen       BZ2_bzdopen
-# define gzread                BZ2_bzread
-# define gzclose       BZ2_bzclose
-# define gzerror       BZ2_bzerror
 #else
 # define USE_INFLATE   0
 # define crc32         loser_crc32
@@ -136,7 +143,7 @@ unzip (int fd, off64_t start_offset,
   }
   inline void smaller_buffer (size_t end)
   {
-    buffer = realloc (buffer, end) ?: buffer;
+    buffer = realloc (buffer, end) ?: end == 0 ? NULL : buffer;
     size = end;
   }
 
@@ -192,7 +199,10 @@ unzip (int fd, off64_t start_offset,
   z_stream z = { .next_in = mapped, .avail_in = mapped_size };
   int result = inflateInit (&z);
   if (result != Z (OK))
-    return zlib_fail (result);
+    {
+      inflateEnd (&z);
+      return zlib_fail (result);
+    }
 
   do
     {
@@ -200,7 +210,10 @@ unzip (int fd, off64_t start_offset,
        {
          ssize_t n = pread_retry (fd, input_buffer, READ_SIZE, input_pos);
          if (unlikely (n < 0))
-           return zlib_fail (Z (IO_ERROR));
+           {
+             inflateEnd (&z);
+             return zlib_fail (Z (ERRNO));
+           }
          z.next_in = input_buffer;
          z.avail_in = n;
          input_pos += n;
@@ -217,7 +230,7 @@ unzip (int fd, off64_t start_offset,
          z.avail_out = size - pos;
        }
     }
-  while ((result = inflate (&z, Z_SYNC_FLUSH)) == Z (OK));
+  while ((result = do_inflate (&z)) == Z (OK));
 
 #ifdef BZLIB
   uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32)
index 03f39f810f6856e227e572f6a99ea48a3e06904b..0c52d2592869fe90a89ef8ad5a3734fb26601bce 100644 (file)
@@ -76,6 +76,7 @@
   DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)"))                     \
   DWFL_ERROR (ZLIB, N_("gzip decompression failed"))                         \
   DWFL_ERROR (BZLIB, N_("bzip2 decompression failed"))                       \
+  DWFL_ERROR (LZMA, N_("LZMA decompression failed"))                         \
   DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine"))    \
   DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file"))                \
   DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type"))                 \
@@ -334,9 +335,13 @@ extern Dwfl_Error __libdw_gunzip  (int fd, off64_t start_offset,
                                   void *mapped, size_t mapped_size,
                                   void **whole, size_t *whole_size)
   internal_function;
-extern Dwfl_Error __libdw_bunzip2  (int fd, off64_t start_offset,
-                                   void *mapped, size_t mapped_size,
-                                   void **whole, size_t *whole_size)
+extern Dwfl_Error __libdw_bunzip2 (int fd, off64_t start_offset,
+                                  void *mapped, size_t mapped_size,
+                                  void **whole, size_t *whole_size)
+  internal_function;
+extern Dwfl_Error __libdw_unlzma (int fd, off64_t start_offset,
+                                 void *mapped, size_t mapped_size,
+                                 void **whole, size_t *whole_size)
   internal_function;
 
 /* Open Elf handle on *FDP.  This handles decompression and checks
diff --git a/libdwfl/lzma.c b/libdwfl/lzma.c
new file mode 100644 (file)
index 0000000..3edfdc2
--- /dev/null
@@ -0,0 +1,4 @@
+/* liblzma is pretty close to zlib and bzlib.  */
+
+#define LZMA
+#include "gzip.c"
index 0ab2a9d241ed185be9dec3d63579eb1e600d3bef..e78eb21f1d26265f458b0ac93d024dbd2dd94c8c 100644 (file)
 # define __libdw_bunzip2(...)  false
 #endif
 
+#if !USE_LZMA
+# define __libdw_unlzma(...)   false
+#endif
+
 /* Always consumes *ELF, never consumes FD.
    Replaces *ELF on success.  */
 static Dwfl_Error
@@ -70,7 +74,7 @@ decompress (int fd __attribute__ ((unused)), Elf **elf)
   void *buffer = NULL;
   size_t size = 0;
 
-#if USE_ZLIB || USE_BZLIB
+#if USE_ZLIB || USE_BZLIB || USE_LZMA
   const off64_t offset = (*elf)->start_offset;
   void *const mapped = ((*elf)->map_address == NULL ? NULL
                        : (*elf)->map_address + (*elf)->start_offset);
@@ -81,6 +85,8 @@ decompress (int fd __attribute__ ((unused)), Elf **elf)
   error = __libdw_gunzip (fd, offset, mapped, mapped_size, &buffer, &size);
   if (error == DWFL_E_BADELF)
     error = __libdw_bunzip2 (fd, offset, mapped, mapped_size, &buffer, &size);
+  if (error == DWFL_E_BADELF)
+    error = __libdw_unlzma (fd, offset, mapped, mapped_size, &buffer, &size);
 #endif
 
   elf_end (*elf);
index 25675634816bdc5ff2eee7cb240dfa300a9c21c2..d116ccdc89e794e190ca1d5c7b6a16dca7a196e4 100644 (file)
@@ -1,3 +1,7 @@
+2009-08-26  Roland McGrath  <roland@redhat.com>
+
+       * zip.m4 (eu_ZIPLIB): Don't apply lib/LIB suffix to args.
+
 2009-02-01  Roland McGrath  <roland@redhat.com>
 
        * zip.m4: Fix --with/--without argument handling.
index 19fa492622b1a10a463446ed7a71c93d1b956af8..8e4d545c0c9f1a77fe7b4e9905748e4994c7e8f3 100644 (file)
--- a/m4/zip.m4
+++ b/m4/zip.m4
@@ -1,18 +1,18 @@
 dnl -*- Autoconf -*- test for either zlib or bzlib.
-dnl Defines --with-$1lib argument, $2LIB automake conditional,
-dnl and sets AC_DEFINE(USE_$2LIB) and LIBS.
+dnl Defines --with-$1 argument, $2 automake conditional,
+dnl and sets AC_DEFINE(USE_$2) and LIBS.
 
 AC_DEFUN([eu_ZIPLIB], [dnl
-AC_ARG_WITH([[$1]lib],
-AC_HELP_STRING([--with-[$1]lib], [support g[$1]ip compression in libdwfl]),,
-           [with_[$1]lib=default])
-if test $with_[$1]lib != no; then
-  AC_SEARCH_LIBS([$4], [$3], [with_[$1]lib=yes],
-                [test $with_[$1]lib = default ||
-                 AC_MSG_ERROR([missing -l[$3] for --with-[$1]lib])])
+AC_ARG_WITH([[$1]],
+AC_HELP_STRING([--with-[$1]], [support [$1] compression in libdwfl]),,
+           [with_[$1]=default])
+if test $with_[$1] != no; then
+  AC_SEARCH_LIBS([$4], [$3], [with_[$1]=yes],
+                [test $with_[$1] = default ||
+                 AC_MSG_ERROR([missing -l[$3] for --with-[$1]])])
 fi
-AM_CONDITIONAL([$2]LIB, test $with_[$1]lib = yes)
-if test $with_[$1]lib = yes; then
-  AC_DEFINE(USE_[$2]LIB)
+AM_CONDITIONAL([$2], test $with_[$1] = yes)
+if test $with_[$1] = yes; then
+  AC_DEFINE(USE_[$2])
 fi
-AH_TEMPLATE(USE_[$2]LIB, [Support $5 decompression via -l$3.])])
+AH_TEMPLATE(USE_[$2], [Support $5 decompression via -l$3.])])