| @@ -0,0 +1,59 @@ | ||
| config XZ_DEC | ||
| tristate "XZ decompression support" | ||
| select CRC32 | ||
| help | ||
| LZMA2 compression algorithm and BCJ filters are supported using | ||
| the .xz file format as the container. For integrity checking, | ||
| CRC32 is supported. See Documentation/xz.txt for more information. | ||
|
|
||
| config XZ_DEC_X86 | ||
| bool "x86 BCJ filter decoder" if EMBEDDED | ||
| default y | ||
| depends on XZ_DEC | ||
| select XZ_DEC_BCJ | ||
|
|
||
| config XZ_DEC_POWERPC | ||
| bool "PowerPC BCJ filter decoder" if EMBEDDED | ||
| default y | ||
| depends on XZ_DEC | ||
| select XZ_DEC_BCJ | ||
|
|
||
| config XZ_DEC_IA64 | ||
| bool "IA-64 BCJ filter decoder" if EMBEDDED | ||
| default y | ||
| depends on XZ_DEC | ||
| select XZ_DEC_BCJ | ||
|
|
||
| config XZ_DEC_ARM | ||
| bool "ARM BCJ filter decoder" if EMBEDDED | ||
| default y | ||
| depends on XZ_DEC | ||
| select XZ_DEC_BCJ | ||
|
|
||
| config XZ_DEC_ARMTHUMB | ||
| bool "ARM-Thumb BCJ filter decoder" if EMBEDDED | ||
| default y | ||
| depends on XZ_DEC | ||
| select XZ_DEC_BCJ | ||
|
|
||
| config XZ_DEC_SPARC | ||
| bool "SPARC BCJ filter decoder" if EMBEDDED | ||
| default y | ||
| depends on XZ_DEC | ||
| select XZ_DEC_BCJ | ||
|
|
||
| config XZ_DEC_BCJ | ||
| bool | ||
| default n | ||
|
|
||
| config XZ_DEC_TEST | ||
| tristate "XZ decompressor tester" | ||
| default n | ||
| depends on XZ_DEC | ||
| help | ||
| This allows passing .xz files to the in-kernel XZ decoder via | ||
| a character special file. It calculates CRC32 of the decompressed | ||
| data and writes diagnostics to the system log. | ||
|
|
||
| Unless you are developing the XZ decoder, you don't need this | ||
| and should say N. |
| @@ -0,0 +1,5 @@ | ||
| obj-$(CONFIG_XZ_DEC) += xz_dec.o | ||
| xz_dec-y := xz_dec_syms.o xz_dec_stream.o xz_dec_lzma2.o | ||
| xz_dec-$(CONFIG_XZ_DEC_BCJ) += xz_dec_bcj.o | ||
|
|
||
| obj-$(CONFIG_XZ_DEC_TEST) += xz_dec_test.o |
| @@ -0,0 +1,59 @@ | ||
| /* | ||
| * CRC32 using the polynomial from IEEE-802.3 | ||
| * | ||
| * Authors: Lasse Collin <lasse.collin@tukaani.org> | ||
| * Igor Pavlov <http://7-zip.org/> | ||
| * | ||
| * This file has been put into the public domain. | ||
| * You can do whatever you want with this file. | ||
| */ | ||
|
|
||
| /* | ||
| * This is not the fastest implementation, but it is pretty compact. | ||
| * The fastest versions of xz_crc32() on modern CPUs without hardware | ||
| * accelerated CRC instruction are 3-5 times as fast as this version, | ||
| * but they are bigger and use more memory for the lookup table. | ||
| */ | ||
|
|
||
| #include "xz_private.h" | ||
|
|
||
| /* | ||
| * STATIC_RW_DATA is used in the pre-boot environment on some architectures. | ||
| * See <linux/decompress/mm.h> for details. | ||
| */ | ||
| #ifndef STATIC_RW_DATA | ||
| # define STATIC_RW_DATA static | ||
| #endif | ||
|
|
||
| STATIC_RW_DATA uint32_t xz_crc32_table[256]; | ||
|
|
||
| XZ_EXTERN void xz_crc32_init(void) | ||
| { | ||
| const uint32_t poly = 0xEDB88320; | ||
|
|
||
| uint32_t i; | ||
| uint32_t j; | ||
| uint32_t r; | ||
|
|
||
| for (i = 0; i < 256; ++i) { | ||
| r = i; | ||
| for (j = 0; j < 8; ++j) | ||
| r = (r >> 1) ^ (poly & ~((r & 1) - 1)); | ||
|
|
||
| xz_crc32_table[i] = r; | ||
| } | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | ||
| { | ||
| crc = ~crc; | ||
|
|
||
| while (size != 0) { | ||
| crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); | ||
| --size; | ||
| } | ||
|
|
||
| return ~crc; | ||
| } |
| @@ -0,0 +1,26 @@ | ||
| /* | ||
| * XZ decoder module information | ||
| * | ||
| * Author: Lasse Collin <lasse.collin@tukaani.org> | ||
| * | ||
| * This file has been put into the public domain. | ||
| * You can do whatever you want with this file. | ||
| */ | ||
|
|
||
| #include <linux/module.h> | ||
| #include <linux/xz.h> | ||
|
|
||
| EXPORT_SYMBOL(xz_dec_init); | ||
| EXPORT_SYMBOL(xz_dec_reset); | ||
| EXPORT_SYMBOL(xz_dec_run); | ||
| EXPORT_SYMBOL(xz_dec_end); | ||
|
|
||
| MODULE_DESCRIPTION("XZ decompressor"); | ||
| MODULE_VERSION("1.0"); | ||
| MODULE_AUTHOR("Lasse Collin <lasse.collin@tukaani.org> and Igor Pavlov"); | ||
|
|
||
| /* | ||
| * This code is in the public domain, but in Linux it's simplest to just | ||
| * say it's GPL and consider the authors as the copyright holders. | ||
| */ | ||
| MODULE_LICENSE("GPL"); |
| @@ -0,0 +1,220 @@ | ||
| /* | ||
| * XZ decoder tester | ||
| * | ||
| * Author: Lasse Collin <lasse.collin@tukaani.org> | ||
| * | ||
| * This file has been put into the public domain. | ||
| * You can do whatever you want with this file. | ||
| */ | ||
|
|
||
| #include <linux/kernel.h> | ||
| #include <linux/module.h> | ||
| #include <linux/fs.h> | ||
| #include <linux/uaccess.h> | ||
| #include <linux/crc32.h> | ||
| #include <linux/xz.h> | ||
|
|
||
| /* Maximum supported dictionary size */ | ||
| #define DICT_MAX (1 << 20) | ||
|
|
||
| /* Device name to pass to register_chrdev(). */ | ||
| #define DEVICE_NAME "xz_dec_test" | ||
|
|
||
| /* Dynamically allocated device major number */ | ||
| static int device_major; | ||
|
|
||
| /* | ||
| * We reuse the same decoder state, and thus can decode only one | ||
| * file at a time. | ||
| */ | ||
| static bool device_is_open; | ||
|
|
||
| /* XZ decoder state */ | ||
| static struct xz_dec *state; | ||
|
|
||
| /* | ||
| * Return value of xz_dec_run(). We need to avoid calling xz_dec_run() after | ||
| * it has returned XZ_STREAM_END, so we make this static. | ||
| */ | ||
| static enum xz_ret ret; | ||
|
|
||
| /* | ||
| * Input and output buffers. The input buffer is used as a temporary safe | ||
| * place for the data coming from the userspace. | ||
| */ | ||
| static uint8_t buffer_in[1024]; | ||
| static uint8_t buffer_out[1024]; | ||
|
|
||
| /* | ||
| * Structure to pass the input and output buffers to the XZ decoder. | ||
| * A few of the fields are never modified so we initialize them here. | ||
| */ | ||
| static struct xz_buf buffers = { | ||
| .in = buffer_in, | ||
| .out = buffer_out, | ||
| .out_size = sizeof(buffer_out) | ||
| }; | ||
|
|
||
| /* | ||
| * CRC32 of uncompressed data. This is used to give the user a simple way | ||
| * to check that the decoder produces correct output. | ||
| */ | ||
| static uint32_t crc; | ||
|
|
||
| static int xz_dec_test_open(struct inode *i, struct file *f) | ||
| { | ||
| if (device_is_open) | ||
| return -EBUSY; | ||
|
|
||
| device_is_open = true; | ||
|
|
||
| xz_dec_reset(state); | ||
| ret = XZ_OK; | ||
| crc = 0xFFFFFFFF; | ||
|
|
||
| buffers.in_pos = 0; | ||
| buffers.in_size = 0; | ||
| buffers.out_pos = 0; | ||
|
|
||
| printk(KERN_INFO DEVICE_NAME ": opened\n"); | ||
| return 0; | ||
| } | ||
|
|
||
| static int xz_dec_test_release(struct inode *i, struct file *f) | ||
| { | ||
| device_is_open = false; | ||
|
|
||
| if (ret == XZ_OK) | ||
| printk(KERN_INFO DEVICE_NAME ": input was truncated\n"); | ||
|
|
||
| printk(KERN_INFO DEVICE_NAME ": closed\n"); | ||
| return 0; | ||
| } | ||
|
|
||
| /* | ||
| * Decode the data given to us from the userspace. CRC32 of the uncompressed | ||
| * data is calculated and is printed at the end of successful decoding. The | ||
| * uncompressed data isn't stored anywhere for further use. | ||
| * | ||
| * The .xz file must have exactly one Stream and no Stream Padding. The data | ||
| * after the first Stream is considered to be garbage. | ||
| */ | ||
| static ssize_t xz_dec_test_write(struct file *file, const char __user *buf, | ||
| size_t size, loff_t *pos) | ||
| { | ||
| size_t remaining; | ||
|
|
||
| if (ret != XZ_OK) { | ||
| if (size > 0) | ||
| printk(KERN_INFO DEVICE_NAME ": %zu bytes of " | ||
| "garbage at the end of the file\n", | ||
| size); | ||
|
|
||
| return -ENOSPC; | ||
| } | ||
|
|
||
| printk(KERN_INFO DEVICE_NAME ": decoding %zu bytes of input\n", | ||
| size); | ||
|
|
||
| remaining = size; | ||
| while ((remaining > 0 || buffers.out_pos == buffers.out_size) | ||
| && ret == XZ_OK) { | ||
| if (buffers.in_pos == buffers.in_size) { | ||
| buffers.in_pos = 0; | ||
| buffers.in_size = min(remaining, sizeof(buffer_in)); | ||
| if (copy_from_user(buffer_in, buf, buffers.in_size)) | ||
| return -EFAULT; | ||
|
|
||
| buf += buffers.in_size; | ||
| remaining -= buffers.in_size; | ||
| } | ||
|
|
||
| buffers.out_pos = 0; | ||
| ret = xz_dec_run(state, &buffers); | ||
| crc = crc32(crc, buffer_out, buffers.out_pos); | ||
| } | ||
|
|
||
| switch (ret) { | ||
| case XZ_OK: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_OK\n"); | ||
| return size; | ||
|
|
||
| case XZ_STREAM_END: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_STREAM_END, " | ||
| "CRC32 = 0x%08X\n", ~crc); | ||
| return size - remaining - (buffers.in_size - buffers.in_pos); | ||
|
|
||
| case XZ_MEMLIMIT_ERROR: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_MEMLIMIT_ERROR\n"); | ||
| break; | ||
|
|
||
| case XZ_FORMAT_ERROR: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_FORMAT_ERROR\n"); | ||
| break; | ||
|
|
||
| case XZ_OPTIONS_ERROR: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_OPTIONS_ERROR\n"); | ||
| break; | ||
|
|
||
| case XZ_DATA_ERROR: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_DATA_ERROR\n"); | ||
| break; | ||
|
|
||
| case XZ_BUF_ERROR: | ||
| printk(KERN_INFO DEVICE_NAME ": XZ_BUF_ERROR\n"); | ||
| break; | ||
|
|
||
| default: | ||
| printk(KERN_INFO DEVICE_NAME ": Bug detected!\n"); | ||
| break; | ||
| } | ||
|
|
||
| return -EIO; | ||
| } | ||
|
|
||
| /* Allocate the XZ decoder state and register the character device. */ | ||
| static int __init xz_dec_test_init(void) | ||
| { | ||
| static const struct file_operations fileops = { | ||
| .owner = THIS_MODULE, | ||
| .open = &xz_dec_test_open, | ||
| .release = &xz_dec_test_release, | ||
| .write = &xz_dec_test_write | ||
| }; | ||
|
|
||
| state = xz_dec_init(XZ_PREALLOC, DICT_MAX); | ||
| if (state == NULL) | ||
| return -ENOMEM; | ||
|
|
||
| device_major = register_chrdev(0, DEVICE_NAME, &fileops); | ||
| if (device_major < 0) { | ||
| xz_dec_end(state); | ||
| return device_major; | ||
| } | ||
|
|
||
| printk(KERN_INFO DEVICE_NAME ": module loaded\n"); | ||
| printk(KERN_INFO DEVICE_NAME ": Create a device node with " | ||
| "'mknod " DEVICE_NAME " c %d 0' and write .xz files " | ||
| "to it.\n", device_major); | ||
| return 0; | ||
| } | ||
|
|
||
| static void __exit xz_dec_test_exit(void) | ||
| { | ||
| unregister_chrdev(device_major, DEVICE_NAME); | ||
| xz_dec_end(state); | ||
| printk(KERN_INFO DEVICE_NAME ": module unloaded\n"); | ||
| } | ||
|
|
||
| module_init(xz_dec_test_init); | ||
| module_exit(xz_dec_test_exit); | ||
|
|
||
| MODULE_DESCRIPTION("XZ decompressor tester"); | ||
| MODULE_VERSION("1.0"); | ||
| MODULE_AUTHOR("Lasse Collin <lasse.collin@tukaani.org>"); | ||
|
|
||
| /* | ||
| * This code is in the public domain, but in Linux it's simplest to just | ||
| * say it's GPL and consider the authors as the copyright holders. | ||
| */ | ||
| MODULE_LICENSE("GPL"); |
| @@ -0,0 +1,204 @@ | ||
| /* | ||
| * LZMA2 definitions | ||
| * | ||
| * Authors: Lasse Collin <lasse.collin@tukaani.org> | ||
| * Igor Pavlov <http://7-zip.org/> | ||
| * | ||
| * This file has been put into the public domain. | ||
| * You can do whatever you want with this file. | ||
| */ | ||
|
|
||
| #ifndef XZ_LZMA2_H | ||
| #define XZ_LZMA2_H | ||
|
|
||
| /* Range coder constants */ | ||
| #define RC_SHIFT_BITS 8 | ||
| #define RC_TOP_BITS 24 | ||
| #define RC_TOP_VALUE (1 << RC_TOP_BITS) | ||
| #define RC_BIT_MODEL_TOTAL_BITS 11 | ||
| #define RC_BIT_MODEL_TOTAL (1 << RC_BIT_MODEL_TOTAL_BITS) | ||
| #define RC_MOVE_BITS 5 | ||
|
|
||
| /* | ||
| * Maximum number of position states. A position state is the lowest pb | ||
| * number of bits of the current uncompressed offset. In some places there | ||
| * are different sets of probabilities for different position states. | ||
| */ | ||
| #define POS_STATES_MAX (1 << 4) | ||
|
|
||
| /* | ||
| * This enum is used to track which LZMA symbols have occurred most recently | ||
| * and in which order. This information is used to predict the next symbol. | ||
| * | ||
| * Symbols: | ||
| * - Literal: One 8-bit byte | ||
| * - Match: Repeat a chunk of data at some distance | ||
| * - Long repeat: Multi-byte match at a recently seen distance | ||
| * - Short repeat: One-byte repeat at a recently seen distance | ||
| * | ||
| * The symbol names are in from STATE_oldest_older_previous. REP means | ||
| * either short or long repeated match, and NONLIT means any non-literal. | ||
| */ | ||
| enum lzma_state { | ||
| STATE_LIT_LIT, | ||
| STATE_MATCH_LIT_LIT, | ||
| STATE_REP_LIT_LIT, | ||
| STATE_SHORTREP_LIT_LIT, | ||
| STATE_MATCH_LIT, | ||
| STATE_REP_LIT, | ||
| STATE_SHORTREP_LIT, | ||
| STATE_LIT_MATCH, | ||
| STATE_LIT_LONGREP, | ||
| STATE_LIT_SHORTREP, | ||
| STATE_NONLIT_MATCH, | ||
| STATE_NONLIT_REP | ||
| }; | ||
|
|
||
| /* Total number of states */ | ||
| #define STATES 12 | ||
|
|
||
| /* The lowest 7 states indicate that the previous state was a literal. */ | ||
| #define LIT_STATES 7 | ||
|
|
||
| /* Indicate that the latest symbol was a literal. */ | ||
| static inline void lzma_state_literal(enum lzma_state *state) | ||
| { | ||
| if (*state <= STATE_SHORTREP_LIT_LIT) | ||
| *state = STATE_LIT_LIT; | ||
| else if (*state <= STATE_LIT_SHORTREP) | ||
| *state -= 3; | ||
| else | ||
| *state -= 6; | ||
| } | ||
|
|
||
| /* Indicate that the latest symbol was a match. */ | ||
| static inline void lzma_state_match(enum lzma_state *state) | ||
| { | ||
| *state = *state < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH; | ||
| } | ||
|
|
||
| /* Indicate that the latest state was a long repeated match. */ | ||
| static inline void lzma_state_long_rep(enum lzma_state *state) | ||
| { | ||
| *state = *state < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP; | ||
| } | ||
|
|
||
| /* Indicate that the latest symbol was a short match. */ | ||
| static inline void lzma_state_short_rep(enum lzma_state *state) | ||
| { | ||
| *state = *state < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP; | ||
| } | ||
|
|
||
| /* Test if the previous symbol was a literal. */ | ||
| static inline bool lzma_state_is_literal(enum lzma_state state) | ||
| { | ||
| return state < LIT_STATES; | ||
| } | ||
|
|
||
| /* Each literal coder is divided in three sections: | ||
| * - 0x001-0x0FF: Without match byte | ||
| * - 0x101-0x1FF: With match byte; match bit is 0 | ||
| * - 0x201-0x2FF: With match byte; match bit is 1 | ||
| * | ||
| * Match byte is used when the previous LZMA symbol was something else than | ||
| * a literal (that is, it was some kind of match). | ||
| */ | ||
| #define LITERAL_CODER_SIZE 0x300 | ||
|
|
||
| /* Maximum number of literal coders */ | ||
| #define LITERAL_CODERS_MAX (1 << 4) | ||
|
|
||
| /* Minimum length of a match is two bytes. */ | ||
| #define MATCH_LEN_MIN 2 | ||
|
|
||
| /* Match length is encoded with 4, 5, or 10 bits. | ||
| * | ||
| * Length Bits | ||
| * 2-9 4 = Choice=0 + 3 bits | ||
| * 10-17 5 = Choice=1 + Choice2=0 + 3 bits | ||
| * 18-273 10 = Choice=1 + Choice2=1 + 8 bits | ||
| */ | ||
| #define LEN_LOW_BITS 3 | ||
| #define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS) | ||
| #define LEN_MID_BITS 3 | ||
| #define LEN_MID_SYMBOLS (1 << LEN_MID_BITS) | ||
| #define LEN_HIGH_BITS 8 | ||
| #define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS) | ||
| #define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS) | ||
|
|
||
| /* | ||
| * Maximum length of a match is 273 which is a result of the encoding | ||
| * described above. | ||
| */ | ||
| #define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1) | ||
|
|
||
| /* | ||
| * Different sets of probabilities are used for match distances that have | ||
| * very short match length: Lengths of 2, 3, and 4 bytes have a separate | ||
| * set of probabilities for each length. The matches with longer length | ||
| * use a shared set of probabilities. | ||
| */ | ||
| #define DIST_STATES 4 | ||
|
|
||
| /* | ||
| * Get the index of the appropriate probability array for decoding | ||
| * the distance slot. | ||
| */ | ||
| static inline uint32_t lzma_get_dist_state(uint32_t len) | ||
| { | ||
| return len < DIST_STATES + MATCH_LEN_MIN | ||
| ? len - MATCH_LEN_MIN : DIST_STATES - 1; | ||
| } | ||
|
|
||
| /* | ||
| * The highest two bits of a 32-bit match distance are encoded using six bits. | ||
| * This six-bit value is called a distance slot. This way encoding a 32-bit | ||
| * value takes 6-36 bits, larger values taking more bits. | ||
| */ | ||
| #define DIST_SLOT_BITS 6 | ||
| #define DIST_SLOTS (1 << DIST_SLOT_BITS) | ||
|
|
||
| /* Match distances up to 127 are fully encoded using probabilities. Since | ||
| * the highest two bits (distance slot) are always encoded using six bits, | ||
| * the distances 0-3 don't need any additional bits to encode, since the | ||
| * distance slot itself is the same as the actual distance. DIST_MODEL_START | ||
| * indicates the first distance slot where at least one additional bit is | ||
| * needed. | ||
| */ | ||
| #define DIST_MODEL_START 4 | ||
|
|
||
| /* | ||
| * Match distances greater than 127 are encoded in three pieces: | ||
| * - distance slot: the highest two bits | ||
| * - direct bits: 2-26 bits below the highest two bits | ||
| * - alignment bits: four lowest bits | ||
| * | ||
| * Direct bits don't use any probabilities. | ||
| * | ||
| * The distance slot value of 14 is for distances 128-191. | ||
| */ | ||
| #define DIST_MODEL_END 14 | ||
|
|
||
| /* Distance slots that indicate a distance <= 127. */ | ||
| #define FULL_DISTANCES_BITS (DIST_MODEL_END / 2) | ||
| #define FULL_DISTANCES (1 << FULL_DISTANCES_BITS) | ||
|
|
||
| /* | ||
| * For match distances greater than 127, only the highest two bits and the | ||
| * lowest four bits (alignment) is encoded using probabilities. | ||
| */ | ||
| #define ALIGN_BITS 4 | ||
| #define ALIGN_SIZE (1 << ALIGN_BITS) | ||
| #define ALIGN_MASK (ALIGN_SIZE - 1) | ||
|
|
||
| /* Total number of all probability variables */ | ||
| #define PROBS_TOTAL (1846 + LITERAL_CODERS_MAX * LITERAL_CODER_SIZE) | ||
|
|
||
| /* | ||
| * LZMA remembers the four most recent match distances. Reusing these | ||
| * distances tends to take less space than re-encoding the actual | ||
| * distance value. | ||
| */ | ||
| #define REPS 4 | ||
|
|
||
| #endif |
| @@ -0,0 +1,156 @@ | ||
| /* | ||
| * Private includes and definitions | ||
| * | ||
| * Author: Lasse Collin <lasse.collin@tukaani.org> | ||
| * | ||
| * This file has been put into the public domain. | ||
| * You can do whatever you want with this file. | ||
| */ | ||
|
|
||
| #ifndef XZ_PRIVATE_H | ||
| #define XZ_PRIVATE_H | ||
|
|
||
| #ifdef __KERNEL__ | ||
| # include <linux/xz.h> | ||
| # include <asm/byteorder.h> | ||
| # include <asm/unaligned.h> | ||
| /* XZ_PREBOOT may be defined only via decompress_unxz.c. */ | ||
| # ifndef XZ_PREBOOT | ||
| # include <linux/slab.h> | ||
| # include <linux/vmalloc.h> | ||
| # include <linux/string.h> | ||
| # ifdef CONFIG_XZ_DEC_X86 | ||
| # define XZ_DEC_X86 | ||
| # endif | ||
| # ifdef CONFIG_XZ_DEC_POWERPC | ||
| # define XZ_DEC_POWERPC | ||
| # endif | ||
| # ifdef CONFIG_XZ_DEC_IA64 | ||
| # define XZ_DEC_IA64 | ||
| # endif | ||
| # ifdef CONFIG_XZ_DEC_ARM | ||
| # define XZ_DEC_ARM | ||
| # endif | ||
| # ifdef CONFIG_XZ_DEC_ARMTHUMB | ||
| # define XZ_DEC_ARMTHUMB | ||
| # endif | ||
| # ifdef CONFIG_XZ_DEC_SPARC | ||
| # define XZ_DEC_SPARC | ||
| # endif | ||
| # define memeq(a, b, size) (memcmp(a, b, size) == 0) | ||
| # define memzero(buf, size) memset(buf, 0, size) | ||
| # endif | ||
| # define get_le32(p) le32_to_cpup((const uint32_t *)(p)) | ||
| #else | ||
| /* | ||
| * For userspace builds, use a separate header to define the required | ||
| * macros and functions. This makes it easier to adapt the code into | ||
| * different environments and avoids clutter in the Linux kernel tree. | ||
| */ | ||
| # include "xz_config.h" | ||
| #endif | ||
|
|
||
| /* If no specific decoding mode is requested, enable support for all modes. */ | ||
| #if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) \ | ||
| && !defined(XZ_DEC_DYNALLOC) | ||
| # define XZ_DEC_SINGLE | ||
| # define XZ_DEC_PREALLOC | ||
| # define XZ_DEC_DYNALLOC | ||
| #endif | ||
|
|
||
| /* | ||
| * The DEC_IS_foo(mode) macros are used in "if" statements. If only some | ||
| * of the supported modes are enabled, these macros will evaluate to true or | ||
| * false at compile time and thus allow the compiler to omit unneeded code. | ||
| */ | ||
| #ifdef XZ_DEC_SINGLE | ||
| # define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE) | ||
| #else | ||
| # define DEC_IS_SINGLE(mode) (false) | ||
| #endif | ||
|
|
||
| #ifdef XZ_DEC_PREALLOC | ||
| # define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC) | ||
| #else | ||
| # define DEC_IS_PREALLOC(mode) (false) | ||
| #endif | ||
|
|
||
| #ifdef XZ_DEC_DYNALLOC | ||
| # define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC) | ||
| #else | ||
| # define DEC_IS_DYNALLOC(mode) (false) | ||
| #endif | ||
|
|
||
| #if !defined(XZ_DEC_SINGLE) | ||
| # define DEC_IS_MULTI(mode) (true) | ||
| #elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC) | ||
| # define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE) | ||
| #else | ||
| # define DEC_IS_MULTI(mode) (false) | ||
| #endif | ||
|
|
||
| /* | ||
| * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ. | ||
| * XZ_DEC_BCJ is used to enable generic support for BCJ decoders. | ||
| */ | ||
| #ifndef XZ_DEC_BCJ | ||
| # if defined(XZ_DEC_X86) || defined(XZ_DEC_POWERPC) \ | ||
| || defined(XZ_DEC_IA64) || defined(XZ_DEC_ARM) \ | ||
| || defined(XZ_DEC_ARM) || defined(XZ_DEC_ARMTHUMB) \ | ||
| || defined(XZ_DEC_SPARC) | ||
| # define XZ_DEC_BCJ | ||
| # endif | ||
| #endif | ||
|
|
||
| /* | ||
| * Allocate memory for LZMA2 decoder. xz_dec_lzma2_reset() must be used | ||
| * before calling xz_dec_lzma2_run(). | ||
| */ | ||
| XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode, | ||
| uint32_t dict_max); | ||
|
|
||
| /* | ||
| * Decode the LZMA2 properties (one byte) and reset the decoder. Return | ||
| * XZ_OK on success, XZ_MEMLIMIT_ERROR if the preallocated dictionary is not | ||
| * big enough, and XZ_OPTIONS_ERROR if props indicates something that this | ||
| * decoder doesn't support. | ||
| */ | ||
| XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, | ||
| uint8_t props); | ||
|
|
||
| /* Decode raw LZMA2 stream from b->in to b->out. */ | ||
| XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, | ||
| struct xz_buf *b); | ||
|
|
||
| /* Free the memory allocated for the LZMA2 decoder. */ | ||
| XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s); | ||
|
|
||
| #ifdef XZ_DEC_BCJ | ||
| /* | ||
| * Allocate memory for BCJ decoders. xz_dec_bcj_reset() must be used before | ||
| * calling xz_dec_bcj_run(). | ||
| */ | ||
| XZ_EXTERN struct xz_dec_bcj *xz_dec_bcj_create(bool single_call); | ||
|
|
||
| /* | ||
| * Decode the Filter ID of a BCJ filter. This implementation doesn't | ||
| * support custom start offsets, so no decoding of Filter Properties | ||
| * is needed. Returns XZ_OK if the given Filter ID is supported. | ||
| * Otherwise XZ_OPTIONS_ERROR is returned. | ||
| */ | ||
| XZ_EXTERN enum xz_ret xz_dec_bcj_reset(struct xz_dec_bcj *s, uint8_t id); | ||
|
|
||
| /* | ||
| * Decode raw BCJ + LZMA2 stream. This must be used only if there actually is | ||
| * a BCJ filter in the chain. If the chain has only LZMA2, xz_dec_lzma2_run() | ||
| * must be called directly. | ||
| */ | ||
| XZ_EXTERN enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, | ||
| struct xz_dec_lzma2 *lzma2, | ||
| struct xz_buf *b); | ||
|
|
||
| /* Free the memory allocated for the BCJ filters. */ | ||
| #define xz_dec_bcj_end(s) kfree(s) | ||
| #endif | ||
|
|
||
| #endif |
| @@ -0,0 +1,62 @@ | ||
| /* | ||
| * Definitions for handling the .xz file format | ||
| * | ||
| * Author: Lasse Collin <lasse.collin@tukaani.org> | ||
| * | ||
| * This file has been put into the public domain. | ||
| * You can do whatever you want with this file. | ||
| */ | ||
|
|
||
| #ifndef XZ_STREAM_H | ||
| #define XZ_STREAM_H | ||
|
|
||
| #if defined(__KERNEL__) && !XZ_INTERNAL_CRC32 | ||
| # include <linux/crc32.h> | ||
| # undef crc32 | ||
| # define xz_crc32(buf, size, crc) \ | ||
| (~crc32_le(~(uint32_t)(crc), buf, size)) | ||
| #endif | ||
|
|
||
| /* | ||
| * See the .xz file format specification at | ||
| * http://tukaani.org/xz/xz-file-format.txt | ||
| * to understand the container format. | ||
| */ | ||
|
|
||
| #define STREAM_HEADER_SIZE 12 | ||
|
|
||
| #define HEADER_MAGIC "\3757zXZ" | ||
| #define HEADER_MAGIC_SIZE 6 | ||
|
|
||
| #define FOOTER_MAGIC "YZ" | ||
| #define FOOTER_MAGIC_SIZE 2 | ||
|
|
||
| /* | ||
| * Variable-length integer can hold a 63-bit unsigned integer or a special | ||
| * value indicating that the value is unknown. | ||
| * | ||
| * Experimental: vli_type can be defined to uint32_t to save a few bytes | ||
| * in code size (no effect on speed). Doing so limits the uncompressed and | ||
| * compressed size of the file to less than 256 MiB and may also weaken | ||
| * error detection slightly. | ||
| */ | ||
| typedef uint64_t vli_type; | ||
|
|
||
| #define VLI_MAX ((vli_type)-1 / 2) | ||
| #define VLI_UNKNOWN ((vli_type)-1) | ||
|
|
||
| /* Maximum encoded size of a VLI */ | ||
| #define VLI_BYTES_MAX (sizeof(vli_type) * 8 / 7) | ||
|
|
||
| /* Integrity Check types */ | ||
| enum xz_check { | ||
| XZ_CHECK_NONE = 0, | ||
| XZ_CHECK_CRC32 = 1, | ||
| XZ_CHECK_CRC64 = 4, | ||
| XZ_CHECK_SHA256 = 10 | ||
| }; | ||
|
|
||
| /* Maximum possible Check ID */ | ||
| #define XZ_CHECK_MAX 15 | ||
|
|
||
| #endif |
| @@ -0,0 +1,23 @@ | ||
| #!/bin/sh | ||
| # | ||
| # This is a wrapper for xz to compress the kernel image using appropriate | ||
| # compression options depending on the architecture. | ||
| # | ||
| # Author: Lasse Collin <lasse.collin@tukaani.org> | ||
| # | ||
| # This file has been put into the public domain. | ||
| # You can do whatever you want with this file. | ||
| # | ||
|
|
||
| BCJ= | ||
| LZMA2OPTS= | ||
|
|
||
| case $ARCH in | ||
| x86|x86_64) BCJ=--x86 ;; | ||
| powerpc) BCJ=--powerpc ;; | ||
| ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; | ||
| arm) BCJ=--arm ;; | ||
| sparc) BCJ=--sparc ;; | ||
| esac | ||
|
|
||
| exec xz --check=crc32 $BCJ --lzma2=$LZMA2OPTS,dict=32MiB |