summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland McGrath <[email protected]>2009-08-26 02:26:34 -0700
committerRoland McGrath <[email protected]>2009-08-26 02:27:19 -0700
commit241696467caa087278576291cb3b89693668df0b (patch)
tree23132315a7fcbc856ded416ae2883abd3637b52b
parentae1d7dc16530898192929ea2a8faea803282a3b3 (diff)
libdwfl: Support automatic decompression of files in XZ format.
-rw-r--r--ChangeLog4
-rw-r--r--NEWS1
-rw-r--r--configure.ac5
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/Makefile.am3
-rw-r--r--libdwfl/gzip.c35
-rw-r--r--libdwfl/libdwflP.h11
-rw-r--r--libdwfl/lzma.c4
-rw-r--r--libdwfl/open.c8
-rw-r--r--m4/ChangeLog4
-rw-r--r--m4/zip.m426
11 files changed, 78 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b8c4438..8b535e09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-08-26 Roland McGrath <[email protected]>
+
+ * configure.ac (zip_LIBS): Check for liblzma too.
+
2009-04-19 Roland McGrath <[email protected]>
* configure.ac (eu_version): Round down here, not in version.h macros.
diff --git a/NEWS b/NEWS
index e0ff9dcc..0f964d76 100644
--- 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:
diff --git a/configure.ac b/configure.ac
index f5a3c527..f1118c6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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])
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index ddfd3259..46c70b30 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,12 @@
2009-08-26 Roland McGrath <[email protected]>
+ * 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.
diff --git a/libdwfl/Makefile.am b/libdwfl/Makefile.am
index adc8a289..af83a96e 100644
--- a/libdwfl/Makefile.am
+++ b/libdwfl/Makefile.am
@@ -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)
diff --git a/libdwfl/gzip.c b/libdwfl/gzip.c
index 9b871920..67f203f8 100644
--- a/libdwfl/gzip.c
+++ b/libdwfl/gzip.c
@@ -52,7 +52,19 @@
#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
@@ -62,13 +74,8 @@
# 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)
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 03f39f81..0c52d259 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -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
index 00000000..3edfdc22
--- /dev/null
+++ b/libdwfl/lzma.c
@@ -0,0 +1,4 @@
+/* liblzma is pretty close to zlib and bzlib. */
+
+#define LZMA
+#include "gzip.c"
diff --git a/libdwfl/open.c b/libdwfl/open.c
index 0ab2a9d2..e78eb21f 100644
--- a/libdwfl/open.c
+++ b/libdwfl/open.c
@@ -61,6 +61,10 @@
# 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);
diff --git a/m4/ChangeLog b/m4/ChangeLog
index 25675634..d116ccdc 100644
--- a/m4/ChangeLog
+++ b/m4/ChangeLog
@@ -1,3 +1,7 @@
+2009-08-26 Roland McGrath <[email protected]>
+
+ * zip.m4 (eu_ZIPLIB): Don't apply lib/LIB suffix to args.
+
2009-02-01 Roland McGrath <[email protected]>
* zip.m4: Fix --with/--without argument handling.
diff --git a/m4/zip.m4 b/m4/zip.m4
index 19fa4926..8e4d545c 100644
--- 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.])])