From: Roland McGrath Date: Wed, 26 Aug 2009 10:05:50 +0000 (-0700) Subject: libdwfl: Support LZMA kernel images. X-Git-Tag: elfutils-0.143~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5a1a8123c4ad0e0df8a66e0d737aafb5ed9d693;p=thirdparty%2Felfutils.git libdwfl: Support LZMA kernel images. --- diff --git a/NEWS b/NEWS index 0f964d76c..992ffd28f 100644 --- a/NEWS +++ b/NEWS @@ -3,8 +3,8 @@ Version 0.143: 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. +libdwfl: Support automatic decompression of files in XZ format, + and of Linux kernel images made with bzip2 or LZMA (as well as gzip). Version 0.142: diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index 46c70b305..9d2bf8c7c 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,5 +1,10 @@ 2009-08-26 Roland McGrath + * gzip.c (find_zImage_payload): New function, broken out of ... + (mapped_zImage): ... here. Call it. + (find_zImage_payload) [LZMA]: Match LZMA-compressed kernels with + stupid method of just trying the decoder. + * open.c [USE_LZMA]: Try __libdw_unlzma. * libdwflP.h: Declare it. (DWFL_ERRORS): Add DWFL_E_LZMA. diff --git a/libdwfl/gzip.c b/libdwfl/gzip.c index 67f203f8e..daf250bb3 100644 --- a/libdwfl/gzip.c +++ b/libdwfl/gzip.c @@ -93,6 +93,34 @@ #define LINUX_MAGIC "HdrS" #define LINUX_MAX_SCAN 32768 +static void * +find_zImage_payload (void *buffer, size_t size) +{ + void *p = memmem (buffer, size, MAGIC, sizeof MAGIC - 1); +#ifdef LZMA + /* The raw LZMA format doesn't have any helpful header magic bytes to + match. So instead we just consider any byte that could possibly be + the start of an LZMA header, and try feeding the input to the decoder + to see if it likes the data. */ + if (p == NULL) + for (; size > 0; ++buffer, --size) + if (*(uint8_t *) buffer < (9 * 5 * 5)) + { + uint8_t dummy[512]; + lzma_stream z = { .next_in = buffer, .avail_in = size, + .next_out = dummy, .avail_out = sizeof dummy }; + int result = lzma_alone_decoder (&z, 1 << 30); + if (result != LZMA_OK) + break; + result = lzma_code (&z, LZMA_RUN); + lzma_end (&z); + if (result == LZMA_OK) + return buffer; + } +#endif + return p; +} + static bool mapped_zImage (off64_t *start_offset, void **mapped, size_t *mapped_size) { @@ -104,7 +132,7 @@ mapped_zImage (off64_t *start_offset, void **mapped, size_t *mapped_size) size_t scan = *mapped_size - pos; if (scan > LINUX_MAX_SCAN) scan = LINUX_MAX_SCAN; - void *p = memmem (*mapped + pos, scan, MAGIC, sizeof MAGIC - 1); + void *p = find_zImage_payload (*mapped + pos, scan); if (p != NULL) { *start_offset += p - *mapped;