From: Roland McGrath Date: Wed, 26 Aug 2009 09:26:34 +0000 (-0700) Subject: libdwfl: Support automatic decompression of files in XZ format. X-Git-Tag: elfutils-0.143~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=241696467caa087278576291cb3b89693668df0b;p=thirdparty%2Felfutils.git libdwfl: Support automatic decompression of files in XZ format. --- diff --git a/ChangeLog b/ChangeLog index 7b8c4438b..8b535e09a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-08-26 Roland McGrath + + * configure.ac (zip_LIBS): Check for liblzma too. + 2009-04-19 Roland McGrath * configure.ac (eu_version): Round down here, not in version.h macros. diff --git a/NEWS b/NEWS index e0ff9dcc8..0f964d76c 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 f5a3c527c..f1118c6b4 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 ddfd32595..46c70b305 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,5 +1,12 @@ 2009-08-26 Roland McGrath + * 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 adc8a2894..af83a96e6 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 9b8719208..67f203f8e 100644 --- a/libdwfl/gzip.c +++ b/libdwfl/gzip.c @@ -52,7 +52,19 @@ #include -#ifdef BZLIB +#ifdef LZMA +# define USE_INFLATE 1 +# include +# 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 # 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 03f39f810..0c52d2592 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 000000000..3edfdc228 --- /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 0ab2a9d24..e78eb21f1 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 256756348..d116ccdc8 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2009-08-26 Roland McGrath + + * zip.m4 (eu_ZIPLIB): Don't apply lib/LIB suffix to args. + 2009-02-01 Roland McGrath * zip.m4: Fix --with/--without argument handling. diff --git a/m4/zip.m4 b/m4/zip.m4 index 19fa49262..8e4d545c0 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.])])