2008-07-13 Bean <bean123ch@gmail.com>

* Makefile.in (enable_lzo): New rule.

	* conf/i386-pc.rmk (grub_mkimage_SOURCES): New test with enable_lzo.

	* configure.ac (ENABLE_LZO): New option --enable-lzo.

	* boot/i386/pc/lnxboot.S: #include <config.h>.

	* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): Change
	its value accordding to the compression algorithm used, lzo or lzma.

	* util/i386/pc/grub-mkimage.c (compress_kernel): Use different
	compression algorithm according to configure macro.

	* kern/i386/pc/startup.S (codestart): Likewise.

	* kern/i386/pc/lzma_decode.S: New file.

	* include/grub/lib/LzFind.h: Likewise.

	* include/grub/lib/LzHash.h: Likewise.

	* include/grub/lib/LzmaDec.h: Likewise.

	* include/grub/lib/LzmaEnc.h: Likewise.

	* include/grub/lib/LzmaTypes.h: Likewise.

	* lib/LzFind.c: Likewise.

	* lib/LzmaDec.c: Likewise.

	* lib/LzmaEnc.c: Likewise.
This commit is contained in:
bean 2008-07-13 01:55:15 +00:00
parent 4ae821ac9a
commit aa24b516a2
20 changed files with 5747 additions and 20 deletions

View file

@ -1,3 +1,39 @@
2008-07-13 Bean <bean123ch@gmail.com>
* Makefile.in (enable_lzo): New rule.
* conf/i386-pc.rmk (grub_mkimage_SOURCES): New test with enable_lzo.
* configure.ac (ENABLE_LZO): New option --enable-lzo.
* boot/i386/pc/lnxboot.S: #include <config.h>.
* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): Change
its value accordding to the compression algorithm used, lzo or lzma.
* util/i386/pc/grub-mkimage.c (compress_kernel): Use different
compression algorithm according to configure macro.
* kern/i386/pc/startup.S (codestart): Likewise.
* kern/i386/pc/lzma_decode.S: New file.
* include/grub/lib/LzFind.h: Likewise.
* include/grub/lib/LzHash.h: Likewise.
* include/grub/lib/LzmaDec.h: Likewise.
* include/grub/lib/LzmaEnc.h: Likewise.
* include/grub/lib/LzmaTypes.h: Likewise.
* lib/LzFind.c: Likewise.
* lib/LzmaDec.c: Likewise.
* lib/LzmaEnc.c: Likewise.
2008-07-13 Bean <bean123ch@gmail.com> 2008-07-13 Bean <bean123ch@gmail.com>
* fs/ext2.c (EXT4_EXTENTS_FLAG): New macro. * fs/ext2.c (EXT4_EXTENTS_FLAG): New macro.

View file

@ -88,6 +88,7 @@ UNIFONT_HEX = @UNIFONT_HEX@
# Options. # Options.
enable_grub_emu = @enable_grub_emu@ enable_grub_emu = @enable_grub_emu@
enable_grub_fstest = @enable_grub_fstest@ enable_grub_fstest = @enable_grub_fstest@
enable_lzo = @enable_lzo@
### General variables. ### General variables.

View file

@ -17,6 +17,7 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <config.h>
#include <grub/boot.h> #include <grub/boot.h>
#include <grub/machine/boot.h> #include <grub/machine/boot.h>
#include <grub/machine/kernel.h> #include <grub/machine/kernel.h>

View file

@ -226,6 +226,7 @@ sbin_UTILITIES += grub-emu
endif endif
# For grub-mkimage. # For grub-mkimage.
ifeq ($(enable_lzo), yes)
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
util/resolve.c util/resolve.c
CLEANFILES += grub-mkimage grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o CLEANFILES += grub-mkimage grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o
@ -246,8 +247,38 @@ grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $< $(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
-include grub_mkimage-util_resolve.d -include grub_mkimage-util_resolve.d
grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR)
grub_mkimage_LDFLAGS = $(LIBLZO) grub_mkimage_LDFLAGS = $(LIBLZO)
else
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c
CLEANFILES += grub-mkimage grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o
MOSTLYCLEANFILES += grub_mkimage-util_i386_pc_grub_mkimage.d grub_mkimage-util_misc.d grub_mkimage-util_resolve.d grub_mkimage-lib_LzmaEnc.d grub_mkimage-lib_LzFind.d
grub-mkimage: $(grub_mkimage_DEPENDENCIES) grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o
$(CC) -o $@ grub_mkimage-util_i386_pc_grub_mkimage.o grub_mkimage-util_misc.o grub_mkimage-util_resolve.o grub_mkimage-lib_LzmaEnc.o grub_mkimage-lib_LzFind.o $(LDFLAGS) $(grub_mkimage_LDFLAGS)
grub_mkimage-util_i386_pc_grub_mkimage.o: util/i386/pc/grub-mkimage.c $(util/i386/pc/grub-mkimage.c_DEPENDENCIES)
$(CC) -Iutil/i386/pc -I$(srcdir)/util/i386/pc $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
-include grub_mkimage-util_i386_pc_grub_mkimage.d
grub_mkimage-util_misc.o: util/misc.c $(util/misc.c_DEPENDENCIES)
$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
-include grub_mkimage-util_misc.d
grub_mkimage-util_resolve.o: util/resolve.c $(util/resolve.c_DEPENDENCIES)
$(CC) -Iutil -I$(srcdir)/util $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
-include grub_mkimage-util_resolve.d
grub_mkimage-lib_LzmaEnc.o: lib/LzmaEnc.c $(lib/LzmaEnc.c_DEPENDENCIES)
$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
-include grub_mkimage-lib_LzmaEnc.d
grub_mkimage-lib_LzFind.o: lib/LzFind.c $(lib/LzFind.c_DEPENDENCIES)
$(CC) -Ilib -I$(srcdir)/lib $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(grub_mkimage_CFLAGS) -MD -c -o $@ $<
-include grub_mkimage-lib_LzFind.d
endif
grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR)
util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile
# For grub-setup. # For grub-setup.

View file

@ -72,10 +72,15 @@ sbin_UTILITIES += grub-emu
endif endif
# For grub-mkimage. # For grub-mkimage.
ifeq ($(enable_lzo), yes)
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \ grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
util/resolve.c util/resolve.c
grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR)
grub_mkimage_LDFLAGS = $(LIBLZO) grub_mkimage_LDFLAGS = $(LIBLZO)
else
grub_mkimage_SOURCES = util/i386/pc/grub-mkimage.c util/misc.c \
util/resolve.c lib/LzmaEnc.c lib/LzFind.c
endif
grub_mkimage_CFLAGS = -DGRUB_MEMORY_MACHINE_LINK_ADDR=$(GRUB_MEMORY_MACHINE_LINK_ADDR)
util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile util/i386/pc/grub-mkimage.c_DEPENDENCIES = Makefile
# For grub-setup. # For grub-setup.

View file

@ -13,6 +13,12 @@
/* Define it to \"data32\" or \"data32;\" to make GAS happy */ /* Define it to \"data32\" or \"data32;\" to make GAS happy */
#undef DATA32 #undef DATA32
/* Use lzma compression */
#undef ENABLE_LZMA
/* Use lzo compression */
#undef ENABLE_LZO
/* Define it to either end or _end */ /* Define it to either end or _end */
#undef END_SYMBOL #undef END_SYMBOL

24
configure vendored
View file

@ -686,6 +686,7 @@ CPP
GREP GREP
EGREP EGREP
LIBLZO LIBLZO
enable_lzo
TARGET_CC TARGET_CC
ac_ct_TARGET_CC ac_ct_TARGET_CC
OBJCOPY OBJCOPY
@ -1291,6 +1292,7 @@ Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-largefile omit support for large files --disable-largefile omit support for large files
--enable-lzo use lzo to compress kernel (default is lzma)
--enable-mm-debug include memory manager debugging --enable-mm-debug include memory manager debugging
--enable-grub-emu build and install the `grub-emu' debugging utility --enable-grub-emu build and install the `grub-emu' debugging utility
--enable-grub-fstest build and install the `grub-fstest' debugging --enable-grub-fstest build and install the `grub-fstest' debugging
@ -5299,8 +5301,19 @@ fi
# Check LZO when compiling for the i386-pc. # Check LZO when compiling for the i386-pc.
if test "$target_cpu"-"$platform" = i386-pc; then if test "$target_cpu"-"$platform" = i386-pc; then
# Check whether --enable-lzo was given.
if test "${enable_lzo+set}" = set; then
enableval=$enable_lzo;
fi
if [ x"$enable_lzo" = xyes ]; then
# There are three possibilities. LZO version 2 installed with the name # There are three possibilities. LZO version 2 installed with the name
# liblzo2, with the name liblzo, and LZO version 1. # liblzo2, with the name liblzo, and LZO version 1.
cat >>confdefs.h <<\_ACEOF
#define ENABLE_LZO 1
_ACEOF
{ echo "$as_me:$LINENO: checking for __lzo_init_v2 in -llzo2" >&5 { echo "$as_me:$LINENO: checking for __lzo_init_v2 in -llzo2" >&5
echo $ECHO_N "checking for __lzo_init_v2 in -llzo2... $ECHO_C" >&6; } echo $ECHO_N "checking for __lzo_init_v2 in -llzo2... $ECHO_C" >&6; }
if test "${ac_cv_lib_lzo2___lzo_init_v2+set}" = set; then if test "${ac_cv_lib_lzo2___lzo_init_v2+set}" = set; then
@ -5741,6 +5754,14 @@ fi
done done
else
cat >>confdefs.h <<\_ACEOF
#define ENABLE_LZMA 1
_ACEOF
fi
fi fi
# Check for functions. # Check for functions.
@ -8906,6 +8927,7 @@ CPP!$CPP$ac_delim
GREP!$GREP$ac_delim GREP!$GREP$ac_delim
EGREP!$EGREP$ac_delim EGREP!$EGREP$ac_delim
LIBLZO!$LIBLZO$ac_delim LIBLZO!$LIBLZO$ac_delim
enable_lzo!$enable_lzo$ac_delim
TARGET_CC!$TARGET_CC$ac_delim TARGET_CC!$TARGET_CC$ac_delim
ac_ct_TARGET_CC!$ac_ct_TARGET_CC$ac_delim ac_ct_TARGET_CC!$ac_ct_TARGET_CC$ac_delim
OBJCOPY!$OBJCOPY$ac_delim OBJCOPY!$OBJCOPY$ac_delim
@ -8922,7 +8944,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF _ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 85; then if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 86; then
break break
elif $ac_last_try; then elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View file

@ -143,19 +143,28 @@ fi
# Check LZO when compiling for the i386-pc. # Check LZO when compiling for the i386-pc.
if test "$target_cpu"-"$platform" = i386-pc; then if test "$target_cpu"-"$platform" = i386-pc; then
AC_ARG_ENABLE([lzo],
[AS_HELP_STRING([--enable-lzo],
[use lzo to compress kernel (default is lzma)])])
[if [ x"$enable_lzo" = xyes ]; then
# There are three possibilities. LZO version 2 installed with the name # There are three possibilities. LZO version 2 installed with the name
# liblzo2, with the name liblzo, and LZO version 1. # liblzo2, with the name liblzo, and LZO version 1.]
AC_CHECK_LIB(lzo2, __lzo_init_v2, [LIBLZO="-llzo2"], AC_DEFINE([ENABLE_LZO], [1], [Use lzo compression])
AC_CHECK_LIB(lzo, __lzo_init_v2, [LIBLZO="-llzo"], AC_CHECK_LIB([lzo2], [__lzo_init_v2], [LIBLZO="-llzo2"],
AC_CHECK_LIB(lzo, __lzo_init2, [LIBLZO="-llzo"], [AC_CHECK_LIB([lzo], [__lzo_init_v2], [LIBLZO="-llzo"],
AC_MSG_ERROR([LZO library version 1.02 or later is required])))) [AC_CHECK_LIB([lzo], [__lzo_init2], [LIBLZO="-llzo"],
AC_SUBST(LIBLZO) [AC_MSG_ERROR([LZO library version 1.02 or later is required])])])])
LIBS="$LIBS $LIBLZO" AC_SUBST([LIBLZO])
AC_CHECK_FUNC(lzo1x_999_compress, , [LIBS="$LIBS $LIBLZO"]
AC_CHECK_FUNC([lzo1x_999_compress], ,
[AC_MSG_ERROR([LZO1X-999 must be enabled])]) [AC_MSG_ERROR([LZO1X-999 must be enabled])])
# LZO version 2 uses lzo/lzo1x.h, while LZO version 1 uses lzo1x.h. [# LZO version 2 uses lzo/lzo1x.h, while LZO version 1 uses lzo1x.h.]
AC_CHECK_HEADERS(lzo/lzo1x.h lzo1x.h) AC_CHECK_HEADERS([lzo/lzo1x.h lzo1x.h])
[else]
AC_DEFINE([ENABLE_LZMA], [1], [Use lzma compression])
[fi]
AC_SUBST([enable_lzo])
fi fi
# Check for functions. # Check for functions.

View file

@ -44,7 +44,11 @@
#define GRUB_KERNEL_MACHINE_DATA_END 0x50 #define GRUB_KERNEL_MACHINE_DATA_END 0x50
/* The size of the first region which won't be compressed. */ /* The size of the first region which won't be compressed. */
#if defined(ENABLE_LZO)
#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x450) #define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x450)
#elif defined(ENABLE_LZMA)
#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0)
#endif
#ifndef ASM_FILE #ifndef ASM_FILE

130
include/grub/lib/LzFind.h Normal file
View file

@ -0,0 +1,130 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#ifndef __LZFIND_H
#define __LZFIND_H
#include <grub/lib/LzmaTypes.h>
typedef UInt32 CLzRef;
typedef struct _CMatchFinder
{
Byte *buffer;
UInt32 pos;
UInt32 posLimit;
UInt32 streamPos;
UInt32 lenLimit;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
UInt32 hashMask;
UInt32 cutValue;
Byte *bufferBase;
ISeqInStream *stream;
int streamEndWasReached;
UInt32 blockSize;
UInt32 keepSizeBefore;
UInt32 keepSizeAfter;
UInt32 numHashBytes;
int directInput;
int btMode;
/* int skipModeBits; */
int bigHash;
UInt32 historySize;
UInt32 fixedHashSize;
UInt32 hashSizeSum;
UInt32 numSons;
SRes result;
UInt32 crc[256];
} CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
int MatchFinder_NeedMove(CMatchFinder *p);
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
void MatchFinder_MoveBlock(CMatchFinder *p);
void MatchFinder_ReadIfRequired(CMatchFinder *p);
void MatchFinder_Construct(CMatchFinder *p);
/* Conditions:
historySize <= 3 GB
keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
*/
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 maxLen);
/*
Conditions:
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
*/
typedef void (*Mf_Init_Func)(void *object);
typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct _IMatchFinder
{
Mf_Init_Func Init;
Mf_GetIndexByte_Func GetIndexByte;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;
Mf_Skip_Func Skip;
} IMatchFinder;
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
void MatchFinder_Init(CMatchFinder *p);
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
#endif

77
include/grub/lib/LzHash.h Normal file
View file

@ -0,0 +1,77 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#ifndef __LZHASH_H
#define __LZHASH_H
#define kHash2Size (1 << 10)
#define kHash3Size (1 << 16)
#define kHash4Size (1 << 20)
#define kFix3HashSize (kHash2Size)
#define kFix4HashSize (kHash2Size + kHash3Size)
#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
#define HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
#define HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
#define HASH5_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
hash4Value &= (kHash4Size - 1); }
/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
#define MT_HASH2_CALC \
hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
#define MT_HASH3_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
#define MT_HASH4_CALC { \
UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
hash2Value = temp & (kHash2Size - 1); \
hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
#endif

246
include/grub/lib/LzmaDec.h Normal file
View file

@ -0,0 +1,246 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#ifndef __LZMADEC_H
#define __LZMADEC_H
#include "Types.h"
/* #define _LZMA_PROB32 */
/* _LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
#ifdef _LZMA_PROB32
#define CLzmaProb UInt32
#else
#define CLzmaProb UInt16
#endif
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaProps
{
unsigned lc, lp, pb;
UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
CLzmaProps prop;
CLzmaProb *probs;
Byte *dic;
const Byte *buf;
UInt32 range, code;
SizeT dicPos;
SizeT dicBufSize;
UInt32 processedPos;
UInt32 checkDicSize;
unsigned state;
UInt32 reps[4];
unsigned remainLen;
int needFlush;
int needInitState;
UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Constr()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAlloc *alloc);
#endif

View file

@ -0,0 +1,95 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#ifndef __LZMAENC_H
#define __LZMAENC_H
#include "LzmaTypes.h"
#define LZMA_PROPS_SIZE 5
typedef struct _CLzmaEncProps
{
int level; /* 0 <= level <= 9 */
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
int algo; /* 0 - fast, 1 - normal, default = 1 */
int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */
} CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p);
void LzmaEncProps_Normalize(CLzmaEncProps *p);
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc_* functions can return the following exit codes:
Returns:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - Write callback error.
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
typedef void * CLzmaEncHandle;
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
/* ---------- One Call Interface ---------- */
/* LzmaEncode
Return code:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
#endif

View file

@ -0,0 +1,151 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#ifndef __7Z_TYPES_H
#define __7Z_TYPES_H
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifndef RINOK
#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
/* #define _SZ_NO_INT_64 */
/* define it if your compiler doesn't support 64-bit integers */
#ifdef _SZ_NO_INT_64
typedef long Int64;
typedef unsigned long UInt64;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
#endif
#endif
#ifdef _LZMA_NO_SYSTEM_SIZE_T
typedef UInt32 SizeT;
#else
#include <stddef.h>
typedef size_t SizeT;
#endif
typedef int Bool;
#define True 1
#define False 0
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_NO_INLINE __declspec(noinline)
#else
#define MY_NO_INLINE
#endif
#define MY_CDECL __cdecl
#define MY_STD_CALL __stdcall
#define MY_FAST_CALL MY_NO_INLINE __fastcall
#else
#define MY_CDECL
#define MY_STD_CALL
#define MY_FAST_CALL
#endif
/* The following interfaces use first parameter as pointer to structure */
typedef struct
{
SRes (*Read)(void *p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
} ISeqInStream;
typedef struct
{
size_t (*Write)(void *p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
} ISeqOutStream;
typedef struct
{
SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
} ICompressProgress;
typedef struct
{
void *(*Alloc)(void *p, size_t size);
void (*Free)(void *p, void *address); /* address can be 0 */
} ISzAlloc;
#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
#define IAlloc_Free(p, a) (p)->Free((p), a)
#endif

677
kern/i386/pc/lzma_decode.S Normal file
View file

@ -0,0 +1,677 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#define FIXED_PROPS
#define LZMA_BASE_SIZE 1846
#define LZMA_LIT_SIZE 768
#define LZMA_PROPERTIES_SIZE 5
#define kNumTopBits 24
#define kTopValue (1 << kNumTopBits)
#define kNumBitModelTotalBits 11
#define kBitModelTotal (1 << kNumBitModelTotalBits)
#define kNumMoveBits 5
#define kNumPosBitsMax 4
#define kNumPosStatesMax (1 << kNumPosBitsMax)
#define kLenNumLowBits 3
#define kLenNumLowSymbols (1 << kLenNumLowBits)
#define kLenNumMidBits 3
#define kLenNumMidSymbols (1 << kLenNumMidBits)
#define kLenNumHighBits 8
#define kLenNumHighSymbols (1 << kLenNumHighBits)
#define LenChoice 0
#define LenChoice2 (LenChoice + 1)
#define LenLow (LenChoice2 + 1)
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
#define kNumStates 12
#define kNumLitStates 7
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kNumPosSlotBits 6
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kAlignTableSize (1 << kNumAlignBits)
#define kMatchMinLen 2
#define IsMatch 0
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
#define IsRepG0 (IsRep + kNumStates)
#define IsRepG1 (IsRepG0 + kNumStates)
#define IsRepG2 (IsRepG1 + kNumStates)
#define IsRep0Long (IsRepG2 + kNumStates)
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
#define LenCoder (Align + kAlignTableSize)
#define RepLenCoder (LenCoder + kNumLenProbs)
#define Literal (RepLenCoder + kNumLenProbs)
#if 0
DbgOut:
pushf
pushl %ebp
pushl %edi
pushl %esi
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
call _DebugPrint
popl %eax
popl %ebx
popl %ecx
popl %edx
popl %esi
popl %edi
popl %ebp
popf
ret
/*
* int LzmaDecodeProperties(CLzmaProperties *propsRes,
* const unsigned char *propsData,
* int size);
*/
_LzmaDecodePropertiesA:
movb (%edx), %dl
xorl %ecx, %ecx
1:
cmpb $45, %dl
jb 2f
incl %ecx
subb $45, %dl
jmp 1b
2:
movl %ecx, 8(%eax) /* pb */
xorl %ecx, %ecx
1:
cmpb $9, %dl
jb 2f
incl %ecx
subb $9, %dl
2:
movl %ecx, 4(%eax) /* lp */
movb %dl, %cl
movl %ecx, (%eax) /* lc */
#endif
#ifndef ASM_FILE
xorl %eax, %eax
#endif
ret
#define out_size 8(%ebp)
#define now_pos -4(%ebp)
#define prev_byte -8(%ebp)
#define range -12(%ebp)
#define code -16(%ebp)
#define state -20(%ebp)
#define rep0 -24(%ebp)
#define rep1 -28(%ebp)
#define rep2 -32(%ebp)
#define rep3 -36(%ebp)
#ifdef FIXED_PROPS
#define FIXED_LC 3
#define FIXED_LP 0
#define FIXED_PB 2
#define POS_STATE_MASK ((1 << (FIXED_PB)) - 1)
#define LIT_POS_MASK ((1 << (FIXED_LP)) - 1)
#define LOCAL_SIZE 36
#else
#define lc (%ebx)
#define lp 4(%ebx)
#define pb 8(%ebx)
#define probs 12(%ebx)
#define pos_state_mask -40(%ebp)
#define lit_pos_mask -44(%ebp)
#define LOCAL_SIZE 44
#endif
RangeDecoderBitDecode:
#ifdef FIXED_PROPS
leal (%ebx, %eax, 4), %eax
#else
shll $2, %eax
addl probs, %eax
#endif
movl %eax, %ecx
movl (%ecx), %eax
movl range, %edx
shrl $kNumBitModelTotalBits, %edx
mull %edx
cmpl code, %eax
jbe 1f
movl %eax, range
movl $kBitModelTotal, %edx
subl (%ecx), %edx
shrl $kNumMoveBits, %edx
addl %edx, (%ecx)
clc
3:
pushf
cmpl $kTopValue, range
jnc 2f
shll $8, code
lodsb
movb %al, code
shll $8, range
2:
popf
ret
1:
subl %eax, range
subl %eax, code
movl (%ecx), %edx
shrl $kNumMoveBits, %edx
subl %edx, (%ecx)
stc
jmp 3b
RangeDecoderBitTreeDecode:
RangeDecoderReverseBitTreeDecode:
movzbl %cl, %ecx
xorl %edx, %edx
pushl %edx
incl %edx
pushl %edx
1:
pushl %eax
pushl %ecx
pushl %edx
addl %edx, %eax
call RangeDecoderBitDecode
popl %edx
popl %ecx
jnc 2f
movl 4(%esp), %eax
orl %eax, 8(%esp)
stc
2:
adcl %edx, %edx
popl %eax
shll $1, (%esp)
loop 1b
popl %ecx
subl %ecx, %edx /* RangeDecoderBitTreeDecode */
popl %ecx /* RangeDecoderReverseBitTreeDecode */
ret
LzmaLenDecode:
pushl %eax
addl $LenChoice, %eax
call RangeDecoderBitDecode
popl %eax
jc 1f
pushl $0
movb $kLenNumLowBits, %cl
addl $LenLow, %eax
2:
movl 12(%esp), %edx
shll %cl, %edx
addl %edx, %eax
3:
call RangeDecoderBitTreeDecode
popl %eax
addl %eax, %edx
ret
1:
pushl %eax
addl $LenChoice2, %eax
call RangeDecoderBitDecode
popl %eax
jc 1f
pushl $kLenNumLowSymbols
movb $kLenNumMidBits, %cl
addl $LenMid, %eax
jmp 2b
1:
pushl $(kLenNumLowSymbols + kLenNumMidSymbols)
addl $LenHigh, %eax
movb $kLenNumHighBits, %cl
jmp 3b
WriteByte:
movb %al, prev_byte
stosb
incl now_pos
ret
/*
* int LzmaDecode(CLzmaDecoderState *vs,
* const unsigned char *inStream,
* unsigned char *outStream,
* SizeT outSize);
*/
_LzmaDecodeA:
pushl %ebp
movl %esp, %ebp
subl $LOCAL_SIZE, %esp
#ifndef ASM_FILE
pushl %esi
pushl %edi
pushl %ebx
movl %eax, %ebx
movl %edx, %esi
pushl %ecx
#else
pushl %edi
#endif
cld
#ifdef FIXED_PROPS
movl %ebx, %edi
movl $(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx
#else
movl $LZMA_LIT_SIZE, %eax
movb lc, %cl
addb lp, %cl
shll %cl, %eax
addl $Literal, %eax
movl %eax, %ecx
movl probs, %edi
#endif
movl $(kBitModelTotal >> 1), %eax
rep
stosl
popl %edi
xorl %eax, %eax
movl %eax, now_pos
movl %eax, prev_byte
movl %eax, state
incl %eax
movl %eax, rep0
movl %eax, rep1
movl %eax, rep2
movl %eax, rep3
#ifndef FIXED_PROPS
movl %eax, %edx
movb pb, %cl
shll %cl, %edx
decl %edx
movl %edx, pos_state_mask
movl %eax, %edx
movb lp, %cl
shll %cl, %edx
decl %edx
movl %edx, lit_pos_mask;
#endif
/* RangeDecoderInit */
negl %eax
movl %eax, range
incl %eax
movb $5, %cl
1:
shll $8, %eax
lodsb
loop 1b
movl %eax, code
lzma_decode_loop:
movl now_pos, %eax
cmpl out_size, %eax
jb 1f
#ifndef ASM_FILE
xorl %eax, %eax
popl %ebx
popl %edi
popl %esi
#endif
movl %ebp, %esp
popl %ebp
ret
1:
#ifdef FIXED_PROPS
andl $POS_STATE_MASK, %eax
#else
andl pos_state_mask, %eax
#endif
pushl %eax /* posState */
movl state, %edx
shll $kNumPosBitsMax, %edx
addl %edx, %eax
pushl %eax /* (state << kNumPosBitsMax) + posState */
call RangeDecoderBitDecode
jc 1f
movl now_pos, %eax
#ifdef FIXED_PROPS
andl $LIT_POS_MASK, %eax
shll $FIXED_LC, %eax
movl prev_byte, %edx
shrl $(8 - FIXED_LC), %edx
#else
andl lit_pos_mask, %eax
movb lc, %cl
shll %cl, %eax
negb %cl
addb $8, %cl
movl prev_byte, %edx
shrl %cl, %edx
#endif
addl %edx, %eax
movl $LZMA_LIT_SIZE, %edx
mull %edx
addl $Literal, %eax
pushl %eax
incl %edx /* edx = 1 */
movl rep0, %eax
negl %eax
pushl (%edi, %eax) /* matchByte */
cmpb $kNumLitStates, state
jb 5f
/* LzmaLiteralDecodeMatch */
3:
cmpl $0x100, %edx
jae 4f
xorl %eax, %eax
shlb $1, (%esp)
adcl %eax, %eax
pushl %eax
pushl %edx
shll $8, %eax
leal 0x100(%edx, %eax), %eax
addl 12(%esp), %eax
call RangeDecoderBitDecode
setc %al
popl %edx
adcl %edx, %edx
popl %ecx
cmpb %cl, %al
jz 3b
5:
/* LzmaLiteralDecode */
cmpl $0x100, %edx
jae 4f
pushl %edx
movl %edx, %eax
addl 8(%esp), %eax
call RangeDecoderBitDecode
popl %edx
adcl %edx, %edx
jmp 5b
4:
addl $16, %esp
movb %dl, %al
call WriteByte
movb state, %al
cmpb $4, %al
jae 2f
xorb %al, %al
jmp 3f
2:
subb $3, %al
cmpb $7, %al
jb 3f
subb $3, %al
3:
movb %al, state
jmp lzma_decode_loop
1:
movl state, %eax
addl $IsRep, %eax
call RangeDecoderBitDecode
jnc 1f
movl state, %eax
addl $IsRepG0, %eax
call RangeDecoderBitDecode
jc 10f
movl (%esp), %eax
addl $IsRep0Long, %eax
call RangeDecoderBitDecode
jc 20f
cmpb $7, state
movb $9, state
jb 100f
addb $2, state
100:
movl $1, %ecx
3:
movl rep0, %edx
negl %edx
4:
movb (%edi, %edx), %al
call WriteByte
loop 4b
popl %eax
popl %eax
jmp lzma_decode_loop
10:
movl state, %eax
addl $IsRepG1, %eax
call RangeDecoderBitDecode
movl rep1, %edx
jnc 100f
movl state, %eax
addl $IsRepG2, %eax
call RangeDecoderBitDecode
movl rep2, %edx
jnc 1000f
movl rep2, %edx
xchgl rep3, %edx
1000:
pushl rep1
popl rep2
100:
xchg rep0, %edx
movl %edx, rep1
20:
movl $RepLenCoder, %eax
call LzmaLenDecode
cmpb $7, state
movb $8, state
jb 100f
addb $3, state
100:
jmp 2f
1:
movl rep0, %eax
xchgl rep1, %eax
xchgl rep2, %eax
movl %eax, rep3
cmpb $7, state
movb $7, state
jb 10f
addb $3, state
10:
movl $LenCoder, %eax
call LzmaLenDecode
pushl %edx
movl $(kNumLenToPosStates - 1), %eax
cmpl %eax, %edx
jbe 100f
movl %eax, %edx
100:
movb $kNumPosSlotBits, %cl
shll %cl, %edx
leal PosSlot(%edx), %eax
call RangeDecoderBitTreeDecode
movl %edx, rep0
cmpl $kStartPosModelIndex, %edx
jb 100f
movl %edx, %ecx
shrl $1, %ecx
decl %ecx
movzbl %dl, %eax
andb $1, %al
orb $2, %al
shll %cl, %eax
movl %eax, rep0
cmpl $kEndPosModelIndex, %edx
jae 200f
movl rep0, %eax
addl $(SpecPos - 1), %eax
subl %edx, %eax
jmp 300f
200:
subb $kNumAlignBits, %cl
/* RangeDecoderDecodeDirectBits */
xorl %edx, %edx
1000:
shrl $1, range
shll $1, %edx
movl range, %eax
cmpl %eax, code
jb 2000f
subl %eax, code
orb $1, %dl
2000:
cmpl $kTopValue, %eax
jae 3000f
shll $8, range
shll $8, code
lodsb
movb %al, code
3000:
loop 1000b
movb $kNumAlignBits, %cl
shll %cl, %edx
addl %edx, rep0
movl $Align, %eax
300:
call RangeDecoderReverseBitTreeDecode
addl %ecx, rep0
100:
incl rep0
popl %edx
2:
addl $kMatchMinLen, %edx
movl %edx, %ecx
jmp 3b

View file

@ -200,6 +200,7 @@ codestart:
incl %eax incl %eax
call EXT_C(grub_gate_a20) call EXT_C(grub_gate_a20)
#if defined(ENABLE_LZO)
/* decompress the compressed part and put the result at 1MB */ /* decompress the compressed part and put the result at 1MB */
movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %esi movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %esi
movl $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %edi movl $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %edi
@ -213,6 +214,23 @@ codestart:
/* copy back the decompressed part */ /* copy back the decompressed part */
movl %eax, %ecx movl %eax, %ecx
cld cld
#elif defined(ENABLE_LZMA)
movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
movl $(START_SYMBOL + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi
pushl %edi
pushl %esi
movl EXT_C(grub_kernel_image_size), %ecx
addl EXT_C(grub_total_module_size), %ecx
addl EXT_C(grub_memdisk_image_size), %ecx
subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
pushl %ecx
leal (%edi, %ecx), %ebx
call _LzmaDecodeA
popl %ecx
popl %edi
popl %esi
#endif
rep rep
movsb movsb
@ -476,7 +494,11 @@ gate_a20_check_state:
popl %ebx popl %ebx
ret ret
#if defined(ENABLE_LZO)
#include "lzo1x.S" #include "lzo1x.S"
#elif defined(ENABLE_LZMA)
#include "lzma_decode.S"
#endif
/* /*
* The code beyond this point is compressed. Assert that the uncompressed * The code beyond this point is compressed. Assert that the uncompressed

774
lib/LzFind.c Normal file
View file

@ -0,0 +1,774 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (c) 1999-2008 Igor Pavlov
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This code was taken from LZMA SDK 4.58 beta, and was slightly modified
* to adapt it to GRUB's requirement.
*
* See <http://www.7-zip.org>, for more information about LZMA.
*/
#include <string.h>
#include <grub/lib/LzFind.h>
#include <grub/lib/LzHash.h>
#define kEmptyHashValue 0
#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
#define kNormalizeMask (~(kNormalizeStepMin - 1))
#define kMaxHistorySize ((UInt32)3 << 30)
#define kStartMaxLen 3
static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
{
if (!p->directInput)
{
alloc->Free(alloc, p->bufferBase);
p->bufferBase = 0;
}
}
/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
{
UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
if (p->directInput)
{
p->blockSize = blockSize;
return 1;
}
if (p->bufferBase == 0 || p->blockSize != blockSize)
{
LzInWindow_Free(p, alloc);
p->blockSize = blockSize;
p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
}
return (p->bufferBase != 0);
}
Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
{
p->posLimit -= subValue;
p->pos -= subValue;
p->streamPos -= subValue;
}
static void MatchFinder_ReadBlock(CMatchFinder *p)
{
if (p->streamEndWasReached || p->result != SZ_OK)
return;
for (;;)
{
Byte *dest = p->buffer + (p->streamPos - p->pos);
size_t size = (p->bufferBase + p->blockSize - dest);
if (size == 0)
return;
p->result = p->stream->Read(p->stream, dest, &size);
if (p->result != SZ_OK)
return;
if (size == 0)
{
p->streamEndWasReached = 1;
return;
}
p->streamPos += (UInt32)size;
if (p->streamPos - p->pos > p->keepSizeAfter)
return;
}
}
void MatchFinder_MoveBlock(CMatchFinder *p)
{
memmove(p->bufferBase,
p->buffer - p->keepSizeBefore,
(size_t)(p->streamPos - p->pos + p->keepSizeBefore));
p->buffer = p->bufferBase + p->keepSizeBefore;
}
int MatchFinder_NeedMove(CMatchFinder *p)
{
/* if (p->streamEndWasReached) return 0; */
return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
}
void MatchFinder_ReadIfRequired(CMatchFinder *p)
{
if (p->streamEndWasReached)
return;
if (p->keepSizeAfter >= p->streamPos - p->pos)
MatchFinder_ReadBlock(p);
}
static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
{
if (MatchFinder_NeedMove(p))
MatchFinder_MoveBlock(p);
MatchFinder_ReadBlock(p);
}
static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
{
p->cutValue = 32;
p->btMode = 1;
p->numHashBytes = 4;
/* p->skipModeBits = 0; */
p->directInput = 0;
p->bigHash = 0;
}
#define kCrcPoly 0xEDB88320
void MatchFinder_Construct(CMatchFinder *p)
{
UInt32 i;
p->bufferBase = 0;
p->directInput = 0;
p->hash = 0;
MatchFinder_SetDefaultSettings(p);
for (i = 0; i < 256; i++)
{
UInt32 r = i;
int j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
p->crc[i] = r;
}
}
static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->hash);
p->hash = 0;
}
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
{
MatchFinder_FreeThisClassMemory(p, alloc);
LzInWindow_Free(p, alloc);
}
static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
{
size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
if (sizeInBytes / sizeof(CLzRef) != num)
return 0;
return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
}
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAlloc *alloc)
{
UInt32 sizeReserv;
if (historySize > kMaxHistorySize)
{
MatchFinder_Free(p, alloc);
return 0;
}
sizeReserv = historySize >> 1;
if (historySize > ((UInt32)2 << 30))
sizeReserv = historySize >> 2;
sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
/* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
if (LzInWindow_Create(p, sizeReserv, alloc))
{
UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
UInt32 hs;
p->matchMaxLen = matchMaxLen;
{
p->fixedHashSize = 0;
if (p->numHashBytes == 2)
hs = (1 << 16) - 1;
else
{
hs = historySize - 1;
hs |= (hs >> 1);
hs |= (hs >> 2);
hs |= (hs >> 4);
hs |= (hs >> 8);
hs >>= 1;
/* hs >>= p->skipModeBits; */
hs |= 0xFFFF; /* don't change it! It's required for Deflate */
if (hs > (1 << 24))
{
if (p->numHashBytes == 3)
hs = (1 << 24) - 1;
else
hs >>= 1;
}
}
p->hashMask = hs;
hs++;
if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
hs += p->fixedHashSize;
}
{
UInt32 prevSize = p->hashSizeSum + p->numSons;
UInt32 newSize;
p->historySize = historySize;
p->hashSizeSum = hs;
p->cyclicBufferSize = newCyclicBufferSize;
p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
newSize = p->hashSizeSum + p->numSons;
if (p->hash != 0 && prevSize == newSize)
return 1;
MatchFinder_FreeThisClassMemory(p, alloc);
p->hash = AllocRefs(newSize, alloc);
if (p->hash != 0)
{
p->son = p->hash + p->hashSizeSum;
return 1;
}
}
}
MatchFinder_Free(p, alloc);
return 0;
}
static void MatchFinder_SetLimits(CMatchFinder *p)
{
UInt32 limit = kMaxValForNormalize - p->pos;
UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
if (limit2 < limit)
limit = limit2;
limit2 = p->streamPos - p->pos;
if (limit2 <= p->keepSizeAfter)
{
if (limit2 > 0)
limit2 = 1;
}
else
limit2 -= p->keepSizeAfter;
if (limit2 < limit)
limit = limit2;
{
UInt32 lenLimit = p->streamPos - p->pos;
if (lenLimit > p->matchMaxLen)
lenLimit = p->matchMaxLen;
p->lenLimit = lenLimit;
}
p->posLimit = p->pos + limit;
}
void MatchFinder_Init(CMatchFinder *p)
{
UInt32 i;
for(i = 0; i < p->hashSizeSum; i++)
p->hash[i] = kEmptyHashValue;
p->cyclicBufferPos = 0;
p->buffer = p->bufferBase;
p->pos = p->streamPos = p->cyclicBufferSize;
p->result = SZ_OK;
p->streamEndWasReached = 0;
MatchFinder_ReadBlock(p);
MatchFinder_SetLimits(p);
}
static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
{
return (p->pos - p->historySize - 1) & kNormalizeMask;
}
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
{
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt32 value = items[i];
if (value <= subValue)
value = kEmptyHashValue;
else
value -= subValue;
items[i] = value;
}
}
static void MatchFinder_Normalize(CMatchFinder *p)
{
UInt32 subValue = MatchFinder_GetSubValue(p);
MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
MatchFinder_ReduceOffsets(p, subValue);
}
static void MatchFinder_CheckLimits(CMatchFinder *p)
{
if (p->pos == kMaxValForNormalize)
MatchFinder_Normalize(p);
if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
MatchFinder_CheckAndMoveAndRead(p);
if (p->cyclicBufferPos == p->cyclicBufferSize)
p->cyclicBufferPos = 0;
MatchFinder_SetLimits(p);
}
static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
UInt32 *distances, UInt32 maxLen)
{
son[_cyclicBufferPos] = curMatch;
for (;;)
{
UInt32 delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
return distances;
{
const Byte *pb = cur - delta;
curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
if (pb[maxLen] == cur[maxLen] && *pb == *cur)
{
UInt32 len = 0;
while(++len != lenLimit)
if (pb[len] != cur[len])
break;
if (maxLen < len)
{
*distances++ = maxLen = len;
*distances++ = delta - 1;
if (len == lenLimit)
return distances;
}
}
}
}
}
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
UInt32 *distances, UInt32 maxLen)
{
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
UInt32 len0 = 0, len1 = 0;
for (;;)
{
UInt32 delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
{
*ptr0 = *ptr1 = kEmptyHashValue;
return distances;
}
{
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta;
UInt32 len = (len0 < len1 ? len0 : len1);
if (pb[len] == cur[len])
{
if (++len != lenLimit && pb[len] == cur[len])
while(++len != lenLimit)
if (pb[len] != cur[len])
break;
if (maxLen < len)
{
*distances++ = maxLen = len;
*distances++ = delta - 1;
if (len == lenLimit)
{
*ptr1 = pair[0];
*ptr0 = pair[1];
return distances;
}
}
}
if (pb[len] < cur[len])
{
*ptr1 = curMatch;
ptr1 = pair + 1;
curMatch = *ptr1;
len1 = len;
}
else
{
*ptr0 = curMatch;
ptr0 = pair;
curMatch = *ptr0;
len0 = len;
}
}
}
}
static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
{
CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
UInt32 len0 = 0, len1 = 0;
for (;;)
{
UInt32 delta = pos - curMatch;
if (cutValue-- == 0 || delta >= _cyclicBufferSize)
{
*ptr0 = *ptr1 = kEmptyHashValue;
return;
}
{
CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
const Byte *pb = cur - delta;
UInt32 len = (len0 < len1 ? len0 : len1);
if (pb[len] == cur[len])
{
while(++len != lenLimit)
if (pb[len] != cur[len])
break;
{
if (len == lenLimit)
{
*ptr1 = pair[0];
*ptr0 = pair[1];
return;
}
}
}
if (pb[len] < cur[len])
{
*ptr1 = curMatch;
ptr1 = pair + 1;
curMatch = *ptr1;
len1 = len;
}
else
{
*ptr0 = curMatch;
ptr0 = pair;
curMatch = *ptr0;
len0 = len;
}
}
}
}
#define MOVE_POS \
++p->cyclicBufferPos; \
p->buffer++; \
if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
#define MOVE_POS_RET MOVE_POS return offset;
static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
#define GET_MATCHES_HEADER2(minLen, ret_op) \
UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
cur = p->buffer;
#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
#define GET_MATCHES_FOOTER(offset, maxLen) \
offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
distances + offset, maxLen) - distances); MOVE_POS_RET;
#define SKIP_FOOTER \
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 1)
}
UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = 0;
GET_MATCHES_FOOTER(offset, 2)
}
static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 hash2Value, delta2, maxLen, offset;
GET_MATCHES_HEADER(3)
HASH3_CALC;
delta2 = p->pos - p->hash[hash2Value];
curMatch = p->hash[kFix3HashSize + hashValue];
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
maxLen = 2;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[0] = maxLen;
distances[1] = delta2 - 1;
offset = 2;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
MOVE_POS_RET;
}
}
GET_MATCHES_FOOTER(offset, maxLen)
}
static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
GET_MATCHES_HEADER(4)
HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
maxLen = 1;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
offset = 2;
}
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
{
maxLen = 3;
distances[offset + 1] = delta3 - 1;
offset += 2;
delta2 = delta3;
}
if (offset != 0)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
MOVE_POS_RET;
}
}
if (maxLen < 3)
maxLen = 3;
GET_MATCHES_FOOTER(offset, maxLen)
}
static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
GET_MATCHES_HEADER(4)
HASH4_CALC;
delta2 = p->pos - p->hash[ hash2Value];
delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
maxLen = 1;
offset = 0;
if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
{
distances[0] = maxLen = 2;
distances[1] = delta2 - 1;
offset = 2;
}
if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
{
maxLen = 3;
distances[offset + 1] = delta3 - 1;
offset += 2;
delta2 = delta3;
}
if (offset != 0)
{
for (; maxLen != lenLimit; maxLen++)
if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
break;
distances[offset - 2] = maxLen;
if (maxLen == lenLimit)
{
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS_RET;
}
}
if (maxLen < 3)
maxLen = 3;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances + offset, maxLen) - (distances));
MOVE_POS_RET
}
UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
{
UInt32 offset;
GET_MATCHES_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
distances, 2) - (distances));
MOVE_POS_RET
}
static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
SKIP_HEADER(2)
HASH2_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 hash2Value;
SKIP_HEADER(3)
HASH3_CALC;
curMatch = p->hash[kFix3HashSize + hashValue];
p->hash[hash2Value] =
p->hash[kFix3HashSize + hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 hash2Value, hash3Value;
SKIP_HEADER(4)
HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] = p->pos;
p->hash[kFix4HashSize + hashValue] = p->pos;
SKIP_FOOTER
}
while (--num != 0);
}
static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
UInt32 hash2Value, hash3Value;
SKIP_HEADER(4)
HASH4_CALC;
curMatch = p->hash[kFix4HashSize + hashValue];
p->hash[ hash2Value] =
p->hash[kFix3HashSize + hash3Value] =
p->hash[kFix4HashSize + hashValue] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
{
do
{
SKIP_HEADER(3)
HASH_ZIP_CALC;
curMatch = p->hash[hashValue];
p->hash[hashValue] = p->pos;
p->son[p->cyclicBufferPos] = curMatch;
MOVE_POS
}
while (--num != 0);
}
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
{
vTable->Init = (Mf_Init_Func)MatchFinder_Init;
vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
if (!p->btMode)
{
vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
}
else if (p->numHashBytes == 2)
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
}
else if (p->numHashBytes == 3)
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
}
else
{
vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
}
}

1035
lib/LzmaDec.c Normal file

File diff suppressed because it is too large Load diff

2353
lib/LzmaEnc.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -36,12 +36,22 @@
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include <getopt.h> #include <getopt.h>
#if defined(ENABLE_LZO)
#if defined(HAVE_LZO_LZO1X_H) #if defined(HAVE_LZO_LZO1X_H)
# include <lzo/lzo1x.h> # include <lzo/lzo1x.h>
#elif defined(HAVE_LZO1X_H) #elif defined(HAVE_LZO1X_H)
# include <lzo1x.h> # include <lzo1x.h>
#endif #endif
#elif defined(ENABLE_LZMA)
#include <grub/lib/LzmaEnc.h>
#endif
#if defined(ENABLE_LZO)
static void static void
compress_kernel (char *kernel_img, size_t kernel_size, compress_kernel (char *kernel_img, size_t kernel_size,
char **core_img, size_t *core_size) char **core_img, size_t *core_size)
@ -76,6 +86,48 @@ compress_kernel (char *kernel_img, size_t kernel_size,
*core_size = (size_t) size + GRUB_KERNEL_MACHINE_RAW_SIZE; *core_size = (size_t) size + GRUB_KERNEL_MACHINE_RAW_SIZE;
} }
#elif defined(ENABLE_LZMA)
static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); }
static void SzFree(void *p, void *address) { p = p; free(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
static void
compress_kernel (char *kernel_img, size_t kernel_size,
char **core_img, size_t *core_size)
{
CLzmaEncProps props;
unsigned char out_props[5];
size_t out_props_size = 5;
LzmaEncProps_Init(&props);
props.dictSize = 1 << 16;
props.lc = 3;
props.lp = 0;
props.pb = 2;
props.numThreads = 1;
grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE)
grub_util_error ("the core image is too small");
*core_img = xmalloc (kernel_size);
memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE);
*core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE;
if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE,
core_size,
(unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE,
kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE,
&props, out_props, &out_props_size,
0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
grub_util_error ("cannot compress the kernel image");
*core_size += GRUB_KERNEL_MACHINE_RAW_SIZE;
}
#endif
static void static void
generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path) generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path)
{ {