packages: xen/xen.spec, xen/xen-xz.patch (NEW) - xz compression support fro...
arekm
arekm at pld-linux.org
Sun Nov 27 12:32:23 CET 2011
Author: arekm Date: Sun Nov 27 11:32:23 2011 GMT
Module: packages Tag: HEAD
---- Log message:
- xz compression support from upstream prepared by archlinux
---- Files affected:
packages/xen:
xen.spec (1.90 -> 1.91) , xen-xz.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: packages/xen/xen.spec
diff -u packages/xen/xen.spec:1.90 packages/xen/xen.spec:1.91
--- packages/xen/xen.spec:1.90 Sun Nov 27 11:30:35 2011
+++ packages/xen/xen.spec Sun Nov 27 12:32:18 2011
@@ -12,7 +12,7 @@
Summary(pl.UTF-8): Xen - monitor maszyny wirtualnej
Name: xen
Version: 4.1.2
-Release: 0.2
+Release: 0.3
License: GPL
Group: Applications/System
Source0: http://bits.xensource.com/oss-xen/release/%{version}/%{name}-%{version}.tar.gz
@@ -36,6 +36,7 @@
Patch1: %{name}-symbols.patch
Patch2: %{name}-curses.patch
Patch3: %{name}-gcc.patch
+Patch4: %{name}-xz.patch
URL: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/index.html
BuildRequires: SDL-devel
%{?with_hvm:BuildRequires: bcc}
@@ -190,6 +191,7 @@
%patch1 -p1
%patch2 -p1
#%%patch3 -p1
+%patch4 -p1
%{__rm} -v tools/check/*.orig
@@ -367,6 +369,9 @@
All persons listed below can be reached at <cvs_login>@pld-linux.org
$Log$
+Revision 1.91 2011/11/27 11:32:18 arekm
+- xz compression support from upstream prepared by archlinux
+
Revision 1.90 2011/11/27 10:30:35 glen
- download stubdown sources to distfiles
================================================================
Index: packages/xen/xen-xz.patch
diff -u /dev/null packages/xen/xen-xz.patch:1.1
--- /dev/null Sun Nov 27 12:32:23 2011
+++ packages/xen/xen-xz.patch Sun Nov 27 12:32:18 2011
@@ -0,0 +1,3528 @@
+diff --git a/xen/common/Makefile b/xen/common/Makefile
+--- a/xen/common/Makefile
++++ b/xen/common/Makefile
+@@ -43,7 +43,7 @@
+ obj-y += rbtree.o
+ obj-y += lzo.o
+
+-obj-$(CONFIG_X86) += decompress.o bunzip2.o unlzma.o unlzo.o
++obj-$(CONFIG_X86) += decompress.o bunzip2.o unxz.o unlzma.o unlzo.o
+
+ obj-$(perfc) += perfc.o
+ obj-$(crash_debug) += gdbstub.o
+diff --git a/xen/common/decompress.c b/xen/common/decompress.c
+--- a/xen/common/decompress.c
++++ b/xen/common/decompress.c
+@@ -20,6 +20,9 @@
+ if ( len >= 3 && !memcmp(inbuf, "\x42\x5a\x68", 3) )
+ return bunzip2(inbuf, len, NULL, NULL, outbuf, NULL, error);
+
++ if ( len >= 6 && !memcmp(inbuf, "\3757zXZ", 6) )
++ return unxz(inbuf, len, NULL, NULL, outbuf, NULL, error);
++
+ if ( len >= 2 && !memcmp(inbuf, "\135\000", 2) )
+ return unlzma(inbuf, len, NULL, NULL, outbuf, NULL, error);
+
+diff --git a/xen/common/decompress.h b/xen/common/decompress.h
+--- a/xen/common/decompress.h
++++ b/xen/common/decompress.h
+@@ -8,6 +8,7 @@
+
+ #define STATIC
+ #define INIT __init
++#define INITDATA __initdata
+
+ static void(*__initdata error)(const char *);
+ #define set_error_fn(x) error = x;
+diff --git a/xen/common/unxz.c b/xen/common/unxz.c
+new file mode 100644
+--- /dev/null
++++ b/xen/common/unxz.c
+@@ -0,0 +1,306 @@
++/*
++ * Wrapper for decompressing XZ-compressed kernel, initramfs, and initrd
++ *
++ * Author: Lasse Collin <lasse.collin at tukaani.org>
++ *
++ * This file has been put into the public domain.
++ * You can do whatever you want with this file.
++ */
++
++/*
++ * Important notes about in-place decompression
++ *
++ * At least on x86, the kernel is decompressed in place: the compressed data
++ * is placed to the end of the output buffer, and the decompressor overwrites
++ * most of the compressed data. There must be enough safety margin to
++ * guarantee that the write position is always behind the read position.
++ *
++ * The safety margin for XZ with LZMA2 or BCJ+LZMA2 is calculated below.
++ * Note that the margin with XZ is bigger than with Deflate (gzip)!
++ *
++ * The worst case for in-place decompression is that the beginning of
++ * the file is compressed extremely well, and the rest of the file is
++ * uncompressible. Thus, we must look for worst-case expansion when the
++ * compressor is encoding uncompressible data.
++ *
++ * The structure of the .xz file in case of a compresed kernel is as follows.
++ * Sizes (as bytes) of the fields are in parenthesis.
++ *
++ * Stream Header (12)
++ * Block Header:
++ * Block Header (8-12)
++ * Compressed Data (N)
++ * Block Padding (0-3)
++ * CRC32 (4)
++ * Index (8-20)
++ * Stream Footer (12)
++ *
++ * Normally there is exactly one Block, but let's assume that there are
++ * 2-4 Blocks just in case. Because Stream Header and also Block Header
++ * of the first Block don't make the decompressor produce any uncompressed
++ * data, we can ignore them from our calculations. Block Headers of possible
++ * additional Blocks have to be taken into account still. With these
++ * assumptions, it is safe to assume that the total header overhead is
++ * less than 128 bytes.
++ *
++ * Compressed Data contains LZMA2 or BCJ+LZMA2 encoded data. Since BCJ
++ * doesn't change the size of the data, it is enough to calculate the
++ * safety margin for LZMA2.
++ *
++ * LZMA2 stores the data in chunks. Each chunk has a header whose size is
++ * a maximum of 6 bytes, but to get round 2^n numbers, let's assume that
++ * the maximum chunk header size is 8 bytes. After the chunk header, there
++ * may be up to 64 KiB of actual payload in the chunk. Often the payload is
++ * quite a bit smaller though; to be safe, let's assume that an average
++ * chunk has only 32 KiB of payload.
++ *
++ * The maximum uncompressed size of the payload is 2 MiB. The minimum
++ * uncompressed size of the payload is in practice never less than the
++ * payload size itself. The LZMA2 format would allow uncompressed size
++ * to be less than the payload size, but no sane compressor creates such
++ * files. LZMA2 supports storing uncompressible data in uncompressed form,
++ * so there's never a need to create payloads whose uncompressed size is
++ * smaller than the compressed size.
++ *
++ * The assumption, that the uncompressed size of the payload is never
++ * smaller than the payload itself, is valid only when talking about
++ * the payload as a whole. It is possible that the payload has parts where
++ * the decompressor consumes more input than it produces output. Calculating
++ * the worst case for this would be tricky. Instead of trying to do that,
++ * let's simply make sure that the decompressor never overwrites any bytes
++ * of the payload which it is currently reading.
++ *
++ * Now we have enough information to calculate the safety margin. We need
++ * - 128 bytes for the .xz file format headers;
++ * - 8 bytes per every 32 KiB of uncompressed size (one LZMA2 chunk header
++ * per chunk, each chunk having average payload size of 32 KiB); and
++ * - 64 KiB (biggest possible LZMA2 chunk payload size) to make sure that
++ * the decompressor never overwrites anything from the LZMA2 chunk
++ * payload it is currently reading.
++ *
++ * We get the following formula:
++ *
++ * safety_margin = 128 + uncompressed_size * 8 / 32768 + 65536
++ * = 128 + (uncompressed_size >> 12) + 65536
++ *
++ * For comparision, according to arch/x86/boot/compressed/misc.c, the
++ * equivalent formula for Deflate is this:
++ *
++ * safety_margin = 18 + (uncompressed_size >> 12) + 32768
++ *
++ * Thus, when updating Deflate-only in-place kernel decompressor to
++ * support XZ, the fixed overhead has to be increased from 18+32768 bytes
++ * to 128+65536 bytes.
++ */
++
++#include "decompress.h"
++
++#define XZ_EXTERN STATIC
++
++/*
++ * For boot time use, we enable only the BCJ filter of the current
++ * architecture or none if no BCJ filter is available for the architecture.
++ */
++#ifdef CONFIG_X86
++# define XZ_DEC_X86
++#endif
++#ifdef CONFIG_PPC
++# define XZ_DEC_POWERPC
++#endif
++#ifdef CONFIG_ARM
++# define XZ_DEC_ARM
++#endif
++#ifdef CONFIG_IA64
++# define XZ_DEC_IA64
++#endif
++#ifdef CONFIG_SPARC
++# define XZ_DEC_SPARC
++#endif
++
++/*
++ * This will get the basic headers so that memeq() and others
++ * can be defined.
++ */
++#include "xz/private.h"
++
++/*
++ * memeq and memzero are not used much and any remotely sane implementation
++ * is fast enough. memcpy/memmove speed matters in multi-call mode, but
++ * the kernel image is decompressed in single-call mode, in which only
++ * memcpy speed can matter and only if there is a lot of uncompressible data
++ * (LZMA2 stores uncompressible chunks in uncompressed form). Thus, the
++ * functions below should just be kept small; it's probably not worth
++ * optimizing for speed.
++ */
++
++#ifndef memeq
++#define memeq(p1, p2, sz) (memcmp(p1, p2, sz) == 0)
++#endif
++
++#ifndef memzero
++#define memzero(p, sz) memset(p, 0, sz)
++#endif
++
++#include "xz/crc32.c"
++#include "xz/dec_stream.c"
++#include "xz/dec_lzma2.c"
++#include "xz/dec_bcj.c"
++
++/* Size of the input and output buffers in multi-call mode */
++#define XZ_IOBUF_SIZE 4096
++
++/*
++ * This function implements the API defined in <linux/decompress/generic.h>.
++ *
++ * This wrapper will automatically choose single-call or multi-call mode
++ * of the native XZ decoder API. The single-call mode can be used only when
++ * both input and output buffers are available as a single chunk, i.e. when
++ * fill() and flush() won't be used.
++ */
++STATIC int INIT unxz(unsigned char *in, unsigned int in_size,
++ int (*fill)(void *dest, unsigned int size),
++ int (*flush)(void *src, unsigned int size),
++ unsigned char *out, unsigned int *in_used,
++ void (*error_fn)(const char *x))
++{
++ struct xz_buf b;
++ struct xz_dec *s;
++ enum xz_ret ret;
++ bool_t must_free_in = false;
++
++ set_error_fn(error_fn);
++
++ xz_crc32_init();
++
++ if (in_used != NULL)
++ *in_used = 0;
++
++ if (fill == NULL && flush == NULL)
++ s = xz_dec_init(XZ_SINGLE, 0);
++ else
++ s = xz_dec_init(XZ_DYNALLOC, (uint32_t)-1);
++
++ if (s == NULL)
++ goto error_alloc_state;
++
++ if (flush == NULL) {
++ b.out = out;
++ b.out_size = (size_t)-1;
++ } else {
++ b.out_size = XZ_IOBUF_SIZE;
++ b.out = malloc(XZ_IOBUF_SIZE);
++ if (b.out == NULL)
++ goto error_alloc_out;
++ }
++
++ if (in == NULL) {
++ must_free_in = true;
++ in = malloc(XZ_IOBUF_SIZE);
++ if (in == NULL)
++ goto error_alloc_in;
++ }
++
++ b.in = in;
++ b.in_pos = 0;
++ b.in_size = in_size;
++ b.out_pos = 0;
++
++ if (fill == NULL && flush == NULL) {
++ ret = xz_dec_run(s, &b);
++ } else {
++ do {
++ if (b.in_pos == b.in_size && fill != NULL) {
++ if (in_used != NULL)
++ *in_used += b.in_pos;
++
++ b.in_pos = 0;
++
++ in_size = fill(in, XZ_IOBUF_SIZE);
++ if (in_size < 0) {
++ /*
++ * This isn't an optimal error code
++ * but it probably isn't worth making
++ * a new one either.
++ */
++ ret = XZ_BUF_ERROR;
++ break;
++ }
++
++ b.in_size = in_size;
++ }
++
++ ret = xz_dec_run(s, &b);
++
++ if (flush != NULL && (b.out_pos == b.out_size
++ || (ret != XZ_OK && b.out_pos > 0))) {
++ /*
++ * Setting ret here may hide an error
++ * returned by xz_dec_run(), but probably
++ * it's not too bad.
++ */
++ if (flush(b.out, b.out_pos) != (int)b.out_pos)
++ ret = XZ_BUF_ERROR;
++
++ b.out_pos = 0;
++ }
++ } while (ret == XZ_OK);
++
++ if (must_free_in)
++ free(in);
++
++ if (flush != NULL)
++ free(b.out);
++ }
++
++ if (in_used != NULL)
++ *in_used += b.in_pos;
++
++ xz_dec_end(s);
++
++ switch (ret) {
++ case XZ_STREAM_END:
++ return 0;
++
++ case XZ_MEM_ERROR:
++ /* This can occur only in multi-call mode. */
++ error("XZ decompressor ran out of memory");
++ break;
++
++ case XZ_FORMAT_ERROR:
++ error("Input is not in the XZ format (wrong magic bytes)");
++ break;
++
++ case XZ_OPTIONS_ERROR:
++ error("Input was encoded with settings that are not "
++ "supported by this XZ decoder");
++ break;
++
++ case XZ_DATA_ERROR:
++ case XZ_BUF_ERROR:
++ error("XZ-compressed data is corrupt");
++ break;
++
++ default:
++ error("Bug in the XZ decompressor");
++ break;
++ }
++
++ return -1;
++
++error_alloc_in:
++ if (flush != NULL)
++ free(b.out);
++
++error_alloc_out:
++ xz_dec_end(s);
++
++error_alloc_state:
++ error("XZ decompressor ran out of memory");
++ return -1;
++}
++
++/*
++ * This macro is used by architecture-specific files to decompress
++ * the kernel image.
++ */
++#define decompress unxz
+diff --git a/xen/common/xz/crc32.c b/xen/common/xz/crc32.c
+new file mode 100644
+--- /dev/null
++++ b/xen/common/xz/crc32.c
+@@ -0,0 +1,51 @@
++/*
++ * CRC32 using the polynomial from IEEE-802.3
++ *
++ * Authors: Lasse Collin <lasse.collin at 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 "private.h"
++
++XZ_EXTERN uint32_t INITDATA xz_crc32_table[256];
++
++XZ_EXTERN void INIT 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 INIT 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;
++}
+diff --git a/xen/common/xz/dec_bcj.c b/xen/common/xz/dec_bcj.c
+new file mode 100644
+--- /dev/null
++++ b/xen/common/xz/dec_bcj.c
+@@ -0,0 +1,562 @@
++/*
++ * Branch/Call/Jump (BCJ) filter decoders
++ *
++ * Authors: Lasse Collin <lasse.collin at 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.
++ */
++
++#include "private.h"
++
++/*
++ * The rest of the file is inside this ifdef. It makes things a little more
++ * convenient when building without support for any BCJ filters.
++ */
++#ifdef XZ_DEC_BCJ
++
++struct xz_dec_bcj {
++ /* Type of the BCJ filter being used */
++ enum {
++ BCJ_X86 = 4, /* x86 or x86-64 */
++ BCJ_POWERPC = 5, /* Big endian only */
++ BCJ_IA64 = 6, /* Big or little endian */
++ BCJ_ARM = 7, /* Little endian only */
++ BCJ_ARMTHUMB = 8, /* Little endian only */
++ BCJ_SPARC = 9 /* Big or little endian */
++ } type;
++
++ /*
++ * Return value of the next filter in the chain. We need to preserve
++ * this information across calls, because we must not call the next
++ * filter anymore once it has returned XZ_STREAM_END.
++ */
++ enum xz_ret ret;
++
++ /* True if we are operating in single-call mode. */
++ bool_t single_call;
++
++ /*
++ * Absolute position relative to the beginning of the uncompressed
++ * data (in a single .xz Block). We care only about the lowest 32
++ * bits so this doesn't need to be uint64_t even with big files.
++ */
++ uint32_t pos;
++
++ /* x86 filter state */
++ uint32_t x86_prev_mask;
++
++ /* Temporary space to hold the variables from struct xz_buf */
++ uint8_t *out;
++ size_t out_pos;
++ size_t out_size;
++
++ struct {
++ /* Amount of already filtered data in the beginning of buf */
++ size_t filtered;
++
++ /* Total amount of data currently stored in buf */
++ size_t size;
++
++ /*
++ * Buffer to hold a mix of filtered and unfiltered data. This
++ * needs to be big enough to hold Alignment + 2 * Look-ahead:
++ *
++ * Type Alignment Look-ahead
++ * x86 1 4
++ * PowerPC 4 0
++ * IA-64 16 0
++ * ARM 4 0
++ * ARM-Thumb 2 2
++ * SPARC 4 0
++ */
++ uint8_t buf[16];
++ } temp;
++};
++
++#ifdef XZ_DEC_X86
++/*
++ * This is used to test the most significant byte of a memory address
++ * in an x86 instruction.
++ */
++static inline int INIT bcj_x86_test_msbyte(uint8_t b)
++{
++ return b == 0x00 || b == 0xFF;
++}
++
++static size_t INIT bcj_x86(struct xz_dec_bcj *s, uint8_t *buf, size_t size)
++{
++ static /*const*/ bool_t INITDATA mask_to_allowed_status[8]
++ = { true, true, true, false, true, false, false, false };
++
++ static /*const*/ uint8_t INITDATA mask_to_bit_num[8]
++ = { 0, 1, 2, 2, 3, 3, 3, 3 };
++
++ size_t i;
++ size_t prev_pos = (size_t)-1;
++ uint32_t prev_mask = s->x86_prev_mask;
++ uint32_t src;
++ uint32_t dest;
++ uint32_t j;
++ uint8_t b;
++
++ if (size <= 4)
++ return 0;
++
++ size -= 4;
++ for (i = 0; i < size; ++i) {
++ if ((buf[i] & 0xFE) != 0xE8)
++ continue;
++
++ prev_pos = i - prev_pos;
++ if (prev_pos > 3) {
++ prev_mask = 0;
++ } else {
++ prev_mask = (prev_mask << (prev_pos - 1)) & 7;
++ if (prev_mask != 0) {
++ b = buf[i + 4 - mask_to_bit_num[prev_mask]];
++ if (!mask_to_allowed_status[prev_mask]
++ || bcj_x86_test_msbyte(b)) {
++ prev_pos = i;
++ prev_mask = (prev_mask << 1) | 1;
++ continue;
++ }
++ }
++ }
++
++ prev_pos = i;
++
++ if (bcj_x86_test_msbyte(buf[i + 4])) {
++ src = get_unaligned_le32(buf + i + 1);
++ while (true) {
++ dest = src - (s->pos + (uint32_t)i + 5);
++ if (prev_mask == 0)
++ break;
++
++ j = mask_to_bit_num[prev_mask] * 8;
++ b = (uint8_t)(dest >> (24 - j));
++ if (!bcj_x86_test_msbyte(b))
++ break;
++
++ src = dest ^ (((uint32_t)1 << (32 - j)) - 1);
++ }
<<Diff was trimmed, longer than 597 lines>>
---- CVS-web:
http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/xen/xen.spec?r1=1.90&r2=1.91&f=u
More information about the pld-cvs-commit
mailing list