lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <dda83e780705230750j43c9e89eh766fdaafb1d671f3@mail.gmail.com>
Date:	Wed, 23 May 2007 07:50:39 -0700
From:	"Bret Towe" <magnade@...il.com>
To:	"Nitin Gupta" <nitingupta910@...il.com>
Cc:	linux-kernel@...r.kernel.org,
	"Richard Purdie" <richard@...nedhand.com>, linux-mm-cc@...top.org
Subject: Re: [RFC] LZO de/compression support - take 3

On 5/23/07, Nitin Gupta <nitingupta910@...il.com> wrote:
> Hi,
>
> This contains LZO1X-1 compressor and LZO1X decompressor (safe and
> standard version).
> This includes changes suggested by various people - Thanks to all who
> reviewed previous patches for this LZO port.
>
> Changelog vs original LZO 2.02 code:
> - Chopped down huge parts of original code that were irrelevant fot this port
> - Use of standard data types
> - Use memcpy() instead of COPY4 macros used in orig. code
> - Various macros -> static inline functions
> - Code matches general kernel style
> - Various other cleanups suggested in reviews
>
> For now, tested on x86 only.

If you have a program to test this I can run it on an amd64 and a g4 ppc

> Signed-off-by: Nitin Gupta <nitingupta910@...il.com>
> ---
>
> diff --git a/Makefile b/Makefile
> index 34210af..88053ba 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -826,11 +826,18 @@ include/config/kernel.release:
> include/config/auto.conf FORCE
>  # Listed in dependency order
>  PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
>
> +# prepare4 does module specific things prior to compilation
> +prepare4:
> +ifneq ($(CONFIG_LZO1X),n)
> +       $(Q)ln -sf $(srctree)/lib/lzo1x/lzo1x_decompress.c \
> +               $(srctree)/lib/lzo1x/lzo1x_decompress_safe.c
> +endif
> +
>  # prepare3 is used to check if we are building in a separate output directory,
>  # and if so do:
>  # 1) Check that make has not been executed in the kernel src $(srctree)
>  # 2) Create the include2 directory, used for the second asm symlink
> -prepare3: include/config/kernel.release
> +prepare3: prepare4 include/config/kernel.release
>  ifneq ($(KBUILD_SRC),)
>         @echo '  Using $(srctree) as source for kernel'
>         $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
> diff --git a/include/linux/lzo1x.h b/include/linux/lzo1x.h
> new file mode 100755
> index 0000000..7c2f633
> --- /dev/null
> +++ b/include/linux/lzo1x.h
> @@ -0,0 +1,80 @@
> +/* lzo1x.h -- public interface of the LZO1X compression algorithm
> +
> +   This file is part of the LZO real-time data compression library.
> +
> +   Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
> +   All Rights Reserved.
> +
> +   The LZO library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License,
> +   version 2, as published by the Free Software Foundation.
> +
> +   The LZO library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with the LZO library; see the file COPYING.
> +   If not, write to the Free Software Foundation, Inc.,
> +   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> +
> +   Markus F.X.J. Oberhumer
> +   <markus@...rhumer.com>
> +   http://www.oberhumer.com/opensource/lzo/
> +
> +
> +   This file is modified version of lzo1x.h found in original LZO 2.02
> +   code. Some additional changes have also been made to make it work
> +   in kernel space.
> +
> +   Nitin Gupta
> +   <nitingupta910@...il.com>
> + */
> +
> +#ifndef __LZO1X_H
> +#define __LZO1X_H
> +
> +/* LZO return codes */
> +#define LZO_E_OK                       0
> +#define LZO_E_ERROR                    (-1)
> +#define LZO_E_OUT_OF_MEMORY            (-2)    /* [not used right now] */
> +#define LZO_E_NOT_COMPRESSIBLE         (-3)    /* [not used right now] */
> +#define LZO_E_INPUT_OVERRUN            (-4)
> +#define LZO_E_OUTPUT_OVERRUN           (-5)
> +#define LZO_E_LOOKBEHIND_OVERRUN       (-6)
> +#define LZO_E_EOF_NOT_FOUND            (-7)
> +#define LZO_E_INPUT_NOT_CONSUMED       (-8)
> +#define LZO_E_NOT_YET_IMPLEMENTED      (-9)    /* [not used right now] */
> +
> +/* Size of temp buffer (workmem) required by lzo1x_compress */
> +#define LZO1X_WORKMEM_SIZE     ((size_t) (16384L * sizeof(unsigned char *)))
> +
> +/*
> + * This required 'workmem' of size LZO1X_WORKMEM_SIZE
> + */
> +int lzo1x_compress(const unsigned char *src, size_t src_len,
> +               unsigned char *dst, size_t *dst_len,
> +               void *workmem);
> +
> +
> +/*
> + * This decompressor expects valid compressed data.
> + *
> + * If the compressed data gets corrupted somehow (e.g. transmission
> + * via an erroneous channel, disk errors, ...) it will probably crash
> + * your application because absolutely no additional checks are done.
> + */
> +int lzo1x_decompress(const unsigned char *src, size_t src_len,
> +               unsigned char *dst, size_t *dst_len);
> +
> +
> +/*
> + * The `safe' decompressor. Somewhat slower.
> + *
> + * This decompressor will catch all compressed data violations and
> + * return an error code in this case.
> + */
> +int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
> +               unsigned char *dst, size_t *dst_len);
> +#endif
> diff --git a/lib/Kconfig b/lib/Kconfig
> index 2e7ae6b..9d30b1f 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -64,6 +64,12 @@ config ZLIB_INFLATE
>  config ZLIB_DEFLATE
>         tristate
>
> +config LZO1X
> +       tristate "LZO1X Compression/Decompression"
> +       help
> +         Compression: LZO1X-1
> +         Decompression: LZO1X
> +
>  #
>  # Generic allocator support is selected if needed
>  #
> diff --git a/lib/Makefile b/lib/Makefile
> index c8c8e20..4dad99d 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
>  obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/
>  obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate/
>  obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
> +obj-$(CONFIG_LZO1X)        += lzo1x/
>
>  obj-$(CONFIG_TEXTSEARCH) += textsearch.o
>  obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
> diff --git a/lib/lzo1x/Makefile b/lib/lzo1x/Makefile
> new file mode 100644
> index 0000000..e036b42
> --- /dev/null
> +++ b/lib/lzo1x/Makefile
> @@ -0,0 +1,11 @@
> +#
> +# When compiling this module out of tree, do 'make prepare_lzo'
> +# before compiling as usual
> +#
> +obj-$(CONFIG_LZO1X) += lzo1x.o
> +CFLAGS_lzo1x_decompress_safe.o += -DLZO1X_DECOMPRESS_SAFE
> +lzo1x-objs := lzo1x_compress.o lzo1x_decompress.o lzo1x_decompress_safe.o
> +
> +prepare_lzo:
> +       @ln -sf lzo1x_decompress.c lzo1x_decompress_safe.c
> +
> diff --git a/lib/lzo1x/lzo1x_compress.c b/lib/lzo1x/lzo1x_compress.c
> new file mode 100755
> index 0000000..690c082
> --- /dev/null
> +++ b/lib/lzo1x/lzo1x_compress.c
> @@ -0,0 +1,256 @@
> +/* lzo1x_compress.c -- LZO1X-1 compression
> +
> +   This file is part of the LZO real-time data compression library.
> +
> +   Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
> +   All Rights Reserved.
> +
> +   The LZO library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License,
> +   version 2, as published by the Free Software Foundation.
> +
> +   The LZO library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with the LZO library; see the file COPYING.
> +   If not, write to the Free Software Foundation, Inc.,
> +   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> +
> +   Markus F.X.J. Oberhumer
> +   <markus@...rhumer.com>
> +   http://www.oberhumer.com/opensource/lzo/
> +
> +
> +   This file is derived from lzo1x_1.c and lzo1x_c.ch found in original
> +   LZO 2.02 code. Some additional changes have also been made to make
> +   it work in kernel space.
> +
> +   Nitin Gupta
> +   <nitingupta910@...il.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/compiler.h>
> +
> +#include "lzo1x_int.h"
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("LZO1X Compression");
> +
> +/* compress a block of data. */
> +static unsigned int
> +lzo1x_compress_worker(const unsigned char *in, size_t in_len,
> +                       unsigned char *out, size_t *out_len,
> +                       void *workmem)
> +{
> +       const unsigned char *ip;
> +       unsigned char *op;
> +       const unsigned char * const in_end = in + in_len;
> +       const unsigned char * const ip_end = in + in_len - M2_MAX_LEN - 5;
> +       const unsigned char *ii;
> +       const unsigned char ** const dict = (const unsigned char **)workmem;
> +
> +       op = out;
> +       ip = in;
> +       ii = ip;
> +
> +       ip += 4;
> +       for (;;) {
> +               const unsigned char *m_pos;
> +               size_t m_off;
> +               size_t m_len;
> +               size_t dindex;
> +
> +               dindex = DINDEX1(ip);
> +               m_pos = dict[dindex];
> +
> +               if ((m_pos < in) || (m_off = (size_t)(ip - m_pos)) <= 0
> +                                || m_off > M4_MAX_OFFSET)
> +                       goto literal;
> +
> +               if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
> +                       goto try_match;
> +
> +               dindex = DINDEX2(dindex);
> +               m_pos = dict[dindex];
> +
> +               if ((m_pos < in) || (m_off = (size_t)(ip - m_pos)) <= 0
> +                                || m_off > M4_MAX_OFFSET)
> +                       goto literal;
> +
> +               if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
> +                       goto try_match;
> +
> +               goto literal;
> +
> +try_match:
> +               if (*(const unsigned short *)m_pos ==
> +                               *(const unsigned short *)ip) {
> +                       if (likely(m_pos[2] == ip[2]))
> +                               goto match;
> +               }
> +
> +               /* a literal */
> +literal:
> +               dict[dindex] = ip;
> +               ++ip;
> +               if (unlikely(ip >= ip_end))
> +                       break;
> +               continue;
> +
> +               /* a match */
> +match:
> +               dict[dindex] = ip;
> +               /* store current literal run */
> +               if ((size_t)(ip - ii) > 0) {
> +                       size_t t = (size_t)(ip - ii);
> +                       if (t <= 3)
> +                               op[-2] |= (unsigned char)(t);
> +                       else if (t <= 18)
> +                               *op++ = (unsigned char)(t - 3);
> +                       else {
> +                               size_t tt = t - 18;
> +                               *op++ = 0;
> +                               while (tt > 255) {
> +                                       tt -= 255;
> +                                       *op++ = 0;
> +                               }
> +                               *op++ = (unsigned char)tt;
> +                       }
> +                       do *op++ = *ii++; while (--t > 0);
> +               }
> +
> +               /* code the match */
> +               ip += 3;
> +               if (m_pos[3] != *ip++ || m_pos[4] != *ip++ ||
> +                               m_pos[5] != *ip++ || m_pos[6] != *ip++ ||
> +                               m_pos[7] != *ip++ || m_pos[8] != *ip++) {
> +                       --ip;
> +                       m_len = (size_t)(ip - ii);
> +
> +                       if (m_off <= M2_MAX_OFFSET) {
> +                               m_off -= 1;
> +                               *op++ = (unsigned char)(((m_len - 1) << 5) |
> +                                       ((m_off & 7) << 2));
> +                               *op++ = (unsigned char)(m_off >> 3);
> +                       }
> +                       else if (m_off <= M3_MAX_OFFSET) {
> +                               m_off -= 1;
> +                               *op++ = (unsigned char)(M3_MARKER |
> +                                       (m_len - 2));
> +                               goto m3_m4_offset;
> +                       } else {
> +                               m_off -= 0x4000;
> +                               *op++ = (unsigned char)(M4_MARKER |
> +                                       ((m_off & 0x4000) >> 11) |
> +                                       (m_len - 2));
> +                               goto m3_m4_offset;
> +                       }
> +               } else {
> +                       const unsigned char *end = in_end;
> +                       const unsigned char *m = m_pos + M2_MAX_LEN + 1;
> +                       while (ip < end && *m == *ip)
> +                               m++, ip++;
> +                       m_len = (size_t)(ip - ii);
> +
> +                       if (m_off <= M3_MAX_OFFSET) {
> +                               m_off -= 1;
> +                               if (m_len <= 33)
> +                                       *op++ = (unsigned char)(M3_MARKER |
> +                                               (m_len - 2));
> +                               else {
> +                                       m_len -= 33;
> +                                       *op++ = M3_MARKER | 0;
> +                                       goto m3_m4_len;
> +                               }
> +                       } else {
> +                               m_off -= 0x4000;
> +                               if (m_len <= M4_MAX_LEN)
> +                                       *op++ = (unsigned char)(M4_MARKER |
> +                                               ((m_off & 0x4000) >> 11) |
> +                                               (m_len - 2));
> +                               else {
> +                                       m_len -= M4_MAX_LEN;
> +                                       *op++ = (unsigned char)(M4_MARKER |
> +                                               ((m_off & 0x4000) >> 11));
> +m3_m4_len:
> +                                       while (m_len > 255) {
> +                                               m_len -= 255;
> +                                               *op++ = 0;
> +                                       }
> +                                       *op++ = (unsigned char)(m_len);
> +                               }
> +                       }
> +
> +m3_m4_offset:
> +                       *op++ = (unsigned char)((m_off & 63) << 2);
> +                       *op++ = (unsigned char)(m_off >> 6);
> +               }
> +
> +               ii = ip;
> +               if (unlikely(ip >= ip_end))
> +                       break;
> +       }
> +
> +       *out_len = (size_t)(op - out);
> +       return (size_t)(in_end - ii);
> +}
> +
> +
> +/*
> + * This requires buffer (workmem) of size LZO1X_WORKMEM_SIZE
> + * (exported by lzo1x.h).
> + */
> +int
> +lzo1x_compress(const unsigned char *in, size_t  in_len,
> +               unsigned char *out, size_t *out_len,
> +               void *workmem)
> +{
> +       unsigned char *op = out;
> +       size_t t;
> +
> +       if (!workmem)
> +               return -EINVAL;
> +
> +       if (unlikely(in_len <= M2_MAX_LEN + 5))
> +               t = in_len;
> +       else {
> +               t = lzo1x_compress_worker(in, in_len, op, out_len, workmem);
> +               op += *out_len;
> +       }
> +
> +       if (t > 0) {
> +               const unsigned char *ii = in + in_len - t;
> +
> +               if (op == out && t <= 238)
> +                       *op++ = (unsigned char)(17 + t);
> +               else if (t <= 3)
> +                       op[-2] |= (unsigned char)(t);
> +               else if (t <= 18)
> +                       *op++ = (unsigned char)(t - 3);
> +               else {
> +                       size_t tt = t - 18;
> +                       *op++ = 0;
> +                       while (tt > 255) {
> +                               tt -= 255;
> +                               *op++ = 0;
> +                       }
> +                       *op++ = (unsigned char)tt;
> +               }
> +               memcpy(op, ii, t);
> +               op += t;
> +               ii += t;
> +       }
> +       *op++ = M4_MARKER | 1;
> +       *op++ = 0;
> +       *op++ = 0;
> +
> +       *out_len = (size_t)(op - out);
> +       return 0;
> +}
> +
> +EXPORT_SYMBOL(lzo1x_compress);
> diff --git a/lib/lzo1x/lzo1x_decompress.c b/lib/lzo1x/lzo1x_decompress.c
> new file mode 100755
> index 0000000..09fa1ca
> --- /dev/null
> +++ b/lib/lzo1x/lzo1x_decompress.c
> @@ -0,0 +1,224 @@
> +/* lzo1x_decompress.c -- LZO1X decompression
> +
> +   This file is part of the LZO real-time data compression library.
> +
> +   Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
> +   All Rights Reserved.
> +
> +   The LZO library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License,
> +   version 2, as published by the Free Software Foundation.
> +
> +   The LZO library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with the LZO library; see the file COPYING.
> +   If not, write to the Free Software Foundation, Inc.,
> +   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> +
> +   Markus F.X.J. Oberhumer
> +   <markus@...rhumer.com>
> +   http://www.oberhumer.com/opensource/lzo/
> +
> +
> +   This file is derived from lzo1x_d1.c and lzo1x_d.ch found in original
> +   LZO 2.02 code. Some additional changes have also been made to make
> +   it work in kernel space.
> +
> +   Nitin Gupta
> +   <nitingupta910@...il.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <asm/byteorder.h>
> +#include <linux/lzo1x.h>
> +
> +#include "lzo1x_int.h"
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("LZO1X Decompression");
> +
> +int
> +lzo1x_decompress(const unsigned char *in, size_t in_len,
> +                       unsigned char *out, size_t *out_len)
> +{
> +       size_t t;
> +       unsigned char *op = out;
> +       const unsigned char *ip = in, *m_pos;
> +       const unsigned char * const ip_end = in + in_len;
> +#if defined(HAVE_ANY_OP)
> +       unsigned char * const op_end = out + *out_len;
> +#endif
> +       *out_len = 0;
> +
> +       if (*ip > 17) {
> +               t = *ip++ - 17;
> +               if (t < 4)
> +                       goto match_next;
> +               NEED_OP(t);
> +               NEED_IP(t + 1);
> +               memcpy(op, ip, t);
> +               op += t;
> +               ip += t;
> +               goto first_literal_run;
> +       }
> +
> +       while (TEST_IP) {
> +               t = *ip++;
> +               if (t >= 16)
> +                       goto match;
> +               /* a literal run */
> +               if (t == 0) {
> +                       NEED_IP(1);
> +                       while (*ip == 0) {
> +                               t += 255;
> +                               ip++;
> +                               NEED_IP(1);
> +                       }
> +                       t += 15 + *ip++;
> +               }
> +               /* copy literals */
> +               NEED_OP(t + 3);
> +               NEED_IP(t + 4);
> +               memcpy(op, ip, t + 3);
> +               op += t + 3;
> +               ip += t + 3;
> +
> +first_literal_run:
> +               t = *ip++;
> +               if (t >= 16)
> +                       goto match;
> +               m_pos = op - (1 + M2_MAX_OFFSET);
> +               m_pos -= t >> 2;
> +               m_pos -= *ip++ << 2;
> +               TEST_LB(m_pos);
> +               NEED_OP(3);
> +               *op++ = *m_pos++;
> +               *op++ = *m_pos++;
> +               *op++ = *m_pos;
> +               goto match_done;
> +
> +               /* handle matches */
> +               do {
> +match:
> +                       if (t >= 64) {          /* a M2 match */
> +                               m_pos = op - 1;
> +                               m_pos -= (t >> 2) & 7;
> +                               m_pos -= *ip++ << 3;
> +                               t = (t >> 5) - 1;
> +                               TEST_LB(m_pos);
> +                               NEED_OP(t + 3 - 1);
> +                               goto copy_match;
> +                       } else if (t >= 32) {   /* a M3 match */
> +                               t &= 31;
> +                               if (t == 0) {
> +                                       NEED_IP(1);
> +                                       while (*ip == 0) {
> +                                               t += 255;
> +                                               ip++;
> +                                               NEED_IP(1);
> +                                       }
> +                                       t += 31 + *ip++;
> +                               }
> +                               m_pos = op - 1 - (cpu_to_le16(
> +                                       *(const unsigned short *)ip) >> 2);
> +                               ip += 2;
> +                       } else if (t >= 16) {   /* a M4 match */
> +                               m_pos = op;
> +                               m_pos -= (t & 8) << 11;
> +                               t &= 7;
> +                               if (t == 0) {
> +                                       NEED_IP(1);
> +                                       while (*ip == 0) {
> +                                               t += 255;
> +                                               ip++;
> +                                               NEED_IP(1);
> +                                       }
> +                                       t += 7 + *ip++;
> +                               }
> +                               m_pos -= cpu_to_le16(
> +                                       *(const unsigned short *)ip) >> 2;
> +                               ip += 2;
> +                               if (m_pos == op)
> +                                       goto eof_found;
> +                               m_pos -= 0x4000;
> +                       } else {                /* a M1 match */
> +                               m_pos = op - 1;
> +                               m_pos -= t >> 2;
> +                               m_pos -= *ip++ << 2;
> +                               TEST_LB(m_pos);
> +                               NEED_OP(2);
> +                               *op++ = *m_pos++;
> +                               *op++ = *m_pos;
> +                               goto match_done;
> +                       }
> +
> +                       /* copy match */
> +                       TEST_LB(m_pos);
> +                       NEED_OP(t + 3 - 1);
> +
> +copy_match:
> +                       if (op - m_pos >= BITS_PER_LONG / BITS_PER_BYTE) {
> +                               memcpy(op, m_pos, t + 2);
> +                               op += t + 2;
> +                               m_pos += t + 2;
> +                       } else {
> +                               *op = *m_pos;
> +                               *++op = *++m_pos;
> +                               do
> +                                       *++op = *++m_pos;
> +                               while (--t > 0);
> +                               op++;
> +                               m_pos++;
> +                       }
> +
> +match_done:
> +                       t = ip[-2] & 3;
> +                       if (t == 0)
> +                               break;
> +
> +                       /* copy literals */
> +match_next:
> +                       NEED_OP(t);
> +                       NEED_IP(t+1);
> +                       *op++ = *ip++;
> +                       if (t > 1) {
> +                               *op++ = *ip++;
> +                               if (t > 2)
> +                                       *op++ = *ip++;
> +                       }
> +                       t = *ip++;
> +               } while (TEST_IP);
> +       }
> +
> +#if defined(HAVE_TEST_IP)
> +    /* no EOF code was found */
> +    *out_len = (size_t)(op - out);
> +    return LZO_E_EOF_NOT_FOUND;
> +#endif
> +
> +eof_found:
> +       *out_len = (size_t)(op - out);
> +       return (ip == ip_end ? LZO_E_OK :
> +               (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
> +
> +#if defined(LZO1X_DECOMPRESS_SAFE)
> +input_overrun:
> +    *out_len = (size_t)(op - out);
> +    return LZO_E_INPUT_OVERRUN;
> +
> +output_overrun:
> +    *out_len = (size_t)(op - out);
> +    return LZO_E_OUTPUT_OVERRUN;
> +
> +lookbehind_overrun:
> +    *out_len = (size_t)(op - out);
> +    return LZO_E_LOOKBEHIND_OVERRUN;
> +#endif
> +}
> +
> +EXPORT_SYMBOL(lzo1x_decompress);
> diff --git a/lib/lzo1x/lzo1x_int.h b/lib/lzo1x/lzo1x_int.h
> new file mode 100755
> index 0000000..69e6d9b
> --- /dev/null
> +++ b/lib/lzo1x/lzo1x_int.h
> @@ -0,0 +1,122 @@
> +/* lzo1x_int.h -- to be used internally by LZO de/compression algorithms
> +
> +   This file is part of the LZO real-time data compression library.
> +
> +   Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
> +   All Rights Reserved.
> +
> +   The LZO library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU General Public License,
> +   version 2, as published by the Free Software Foundation.
> +
> +   The LZO library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with the LZO library; see the file COPYING.
> +   If not, write to the Free Software Foundation, Inc.,
> +   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> +
> +   Markus F.X.J. Oberhumer
> +   <markus@...rhumer.com>
> +   http://www.oberhumer.com/opensource/lzo/
> +
> +
> +   This file was derived from several header files found in original
> +   LZO 2.02 code. Some additional changes have also been made to make
> +   it work in kernel space.
> +
> +   Nitin Gupta
> +   <nitingupta910@...il.com>
> + */
> +
> +#ifndef __LZO1X_INT_H
> +#define __LZO1X_INT_H
> +
> +#include <linux/types.h>
> +
> +#define D_BITS         14
> +#define D_SIZE         (1u << D_BITS)
> +#define D_MASK         (D_SIZE - 1)
> +#define D_HIGH         ((D_MASK >> 1) + 1)
> +
> +static inline size_t DX2(const unsigned char *p, size_t s1, size_t s2)
> +{
> +       return (((((size_t)(p[2]) << s2) ^ p[1]) << s1) ^ p[0]);
> +}
> +
> +static inline size_t DX3(const unsigned char *p, size_t s1, size_t
> s2, size_t s3)
> +{
> +       return (DX2(p + 1, s2, s3) << s1) ^ p[0];
> +}
> +
> +static inline size_t DINDEX1(const unsigned char *p)
> +{
> +       return ((size_t)(0x21 * DX3(p, 5, 5, 6)) >> 5) & D_MASK;
> +}
> +
> +static inline size_t DINDEX2(size_t d)
> +{
> +       return (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f);
> +}
> +
> +/* LZO1X Specific constants */
> +#define M1_MAX_OFFSET  0x0400
> +#define M2_MAX_OFFSET  0x0800
> +#define M3_MAX_OFFSET  0x4000
> +#define M4_MAX_OFFSET  0xbfff
> +
> +#define M1_MIN_LEN     2
> +#define M1_MAX_LEN     2
> +#define M2_MIN_LEN     3
> +#define M2_MAX_LEN     8
> +#define M3_MIN_LEN     3
> +#define M3_MAX_LEN     33
> +#define M4_MIN_LEN     3
> +#define M4_MAX_LEN     9
> +
> +#define M1_MARKER      0
> +#define M2_MARKER      64
> +#define M3_MARKER      32
> +#define M4_MARKER      16
> +
> +/* LZO return codes */
> +#define LZO_E_OK                       0
> +#define LZO_E_ERROR                    (-1)
> +#define LZO_E_OUT_OF_MEMORY            (-2)    /* [not used right now] */
> +#define LZO_E_NOT_COMPRESSIBLE         (-3)    /* [not used right now] */
> +#define LZO_E_INPUT_OVERRUN            (-4)
> +#define LZO_E_OUTPUT_OVERRUN           (-5)
> +#define LZO_E_LOOKBEHIND_OVERRUN       (-6)
> +#define LZO_E_EOF_NOT_FOUND            (-7)
> +#define LZO_E_INPUT_NOT_CONSUMED       (-8)
> +#define LZO_E_NOT_YET_IMPLEMENTED      (-9)    /* [not used right now] */
> +
> +/* Macros for 'safe' decompression */
> +#ifdef LZO1X_DECOMPRESS_SAFE
> +
> +#define lzo1x_decompress lzo1x_decompress_safe
> +#define TEST_IP        (ip < ip_end)
> +#define NEED_IP(x) \
> +       if ((size_t)(ip_end - ip) < (size_t)(x)) goto input_overrun
> +#define NEED_OP(x) \
> +       if ((size_t)(op_end - op) < (size_t)(x)) goto output_overrun
> +#define TEST_LB(m_pos) \
> +       if (m_pos < out || m_pos >= op) goto lookbehind_overrun
> +#define HAVE_TEST_IP
> +#define HAVE_ANY_OP
> +
> +#else  /* !LZO1X_DECOMPRESS_SAFE */
> +
> +#define        TEST_IP         1
> +#define        TEST_LB(x)      ((void) 0)
> +#define        NEED_IP(x)      ((void) 0)
> +#define        NEED_OP(x)      ((void) 0)
> +#undef HAVE_TEST_IP
> +#undef HAVE_ANY_OP
> +
> +#endif /* LZO1X_DECOMPRESS_SAFE */
> +
> +#endif
>
>
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ