From 5c105d9f3fd086aff195d3849dcf847d6b0bd927 Mon Sep 17 00:00:00 2001 From: blogic Date: Fri, 5 Oct 2012 10:12:53 +0000 Subject: branch Attitude Adjustment git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@33625 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- tools/squashfs4/Makefile | 43 + tools/squashfs4/patches/100-portability.patch | 40 + .../patches/110-allow_static_liblzma.patch | 30 + tools/squashfs4/patches/120-cygwin_fixes.patch | 153 ++++ tools/squashfs4/patches/150-freebsd_fixes.patch | 10 + .../patches/160-expose_lzma_xz_options.patch | 929 +++++++++++++++++++++ ...0-add_support_for_LZMA_MAGIC_to_unsqashfs.patch | 72 ++ 7 files changed, 1277 insertions(+) create mode 100644 tools/squashfs4/Makefile create mode 100644 tools/squashfs4/patches/100-portability.patch create mode 100644 tools/squashfs4/patches/110-allow_static_liblzma.patch create mode 100644 tools/squashfs4/patches/120-cygwin_fixes.patch create mode 100644 tools/squashfs4/patches/150-freebsd_fixes.patch create mode 100644 tools/squashfs4/patches/160-expose_lzma_xz_options.patch create mode 100644 tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch (limited to 'tools/squashfs4') diff --git a/tools/squashfs4/Makefile b/tools/squashfs4/Makefile new file mode 100644 index 000000000..b838b46c5 --- /dev/null +++ b/tools/squashfs4/Makefile @@ -0,0 +1,43 @@ +# +# Copyright (C) 2009-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=squashfs4 +PKG_VERSION:=4.2 + +PKG_SOURCE:=squashfs$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/squashfs +PKG_MD5SUM:=1b7a781fb4cf8938842279bd3e8ee852 +PKG_CAT:=zcat + +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/squashfs$(PKG_VERSION) + +include $(INCLUDE_DIR)/host-build.mk + +define Host/Compile + $(MAKE) -C $(HOST_BUILD_DIR)/squashfs-tools \ + CC="$(HOSTCC)" \ + XZ_SUPPORT=1 \ + LZMA_XZ_SUPPORT=1 \ + XATTR_SUPPORT= \ + LZMA_LIB="$(STAGING_DIR_HOST)/lib/liblzma.a" \ + EXTRA_CFLAGS="-I$(STAGING_DIR_HOST)/include" \ + EXTRA_LDFLAGS="$(HOST_STATIC_LINKING)" \ + mksquashfs unsquashfs +endef + +define Host/Install + $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/mksquashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 + $(INSTALL_BIN) $(HOST_BUILD_DIR)/squashfs-tools/unsquashfs $(STAGING_DIR_HOST)/bin/unsquashfs4 +endef + +define Host/Clean + rm -f $(STAGING_DIR_HOST)/bin/mksquashfs4 + rm -f $(STAGING_DIR_HOST)/bin/unsquashfs4 +endef + +$(eval $(call HostBuild)) diff --git a/tools/squashfs4/patches/100-portability.patch b/tools/squashfs4/patches/100-portability.patch new file mode 100644 index 000000000..ac1349c7a --- /dev/null +++ b/tools/squashfs4/patches/100-portability.patch @@ -0,0 +1,40 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -60,6 +60,10 @@ + #include + #endif + ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 ++#endif ++ + #ifdef SQUASHFS_TRACE + #define TRACE(s, args...) \ + do { \ +--- a/squashfs-tools/unsquashfs.h ++++ b/squashfs-tools/unsquashfs.h +@@ -49,8 +49,14 @@ + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN + #define __LITTLE_ENDIAN LITTLE_ENDIAN ++#include + #else + #include ++#include ++#endif ++ ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 + #endif + + #include "squashfs_fs.h" +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -29,7 +29,6 @@ + #include "compressor.h" + #include "xattr.h" + +-#include + #include + + struct cache *fragment_cache, *data_cache; diff --git a/tools/squashfs4/patches/110-allow_static_liblzma.patch b/tools/squashfs4/patches/110-allow_static_liblzma.patch new file mode 100644 index 000000000..9a3a74418 --- /dev/null +++ b/tools/squashfs4/patches/110-allow_static_liblzma.patch @@ -0,0 +1,30 @@ +--- a/squashfs-tools/Makefile ++++ b/squashfs-tools/Makefile +@@ -129,7 +129,6 @@ ifeq ($(LZMA_XZ_SUPPORT),1) + CFLAGS += -DLZMA_SUPPORT + MKSQUASHFS_OBJS += lzma_xz_wrapper.o + UNSQUASHFS_OBJS += lzma_xz_wrapper.o +-LIBS += -llzma + COMPRESSORS += lzma + endif + +@@ -137,10 +136,18 @@ ifeq ($(XZ_SUPPORT),1) + CFLAGS += -DXZ_SUPPORT + MKSQUASHFS_OBJS += xz_wrapper.o + UNSQUASHFS_OBJS += xz_wrapper.o +-LIBS += -llzma + COMPRESSORS += xz + endif + ++ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),) ++ifneq ($(LZMA_LIB),) ++MKSQUASHFS_OBJS += $(LZMA_LIB) ++UNSQUASHFS_OBJS += $(LZMA_LIB) ++else ++LIBS += -llzma ++endif ++endif ++ + ifeq ($(LZO_SUPPORT),1) + CFLAGS += -DLZO_SUPPORT + ifdef LZO_DIR diff --git a/tools/squashfs4/patches/120-cygwin_fixes.patch b/tools/squashfs4/patches/120-cygwin_fixes.patch new file mode 100644 index 000000000..fa1dfba42 --- /dev/null +++ b/tools/squashfs4/patches/120-cygwin_fixes.patch @@ -0,0 +1,153 @@ +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -51,15 +51,22 @@ + #include + + #ifndef linux ++#ifndef __CYGWIN__ + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN + #define __LITTLE_ENDIAN LITTLE_ENDIAN + #include ++#endif /* __CYGWIN__ */ + #else + #include + #include + #endif + ++#ifdef __CYGWIN__ ++#include ++#define FNM_EXTMATCH (1 << 5) ++#endif ++ + #ifndef FNM_EXTMATCH + #define FNM_EXTMATCH 0 + #endif +@@ -844,6 +851,7 @@ void sigusr1_handler() + + void sigwinch_handler() + { ++#ifndef __CYGWIN__ + struct winsize winsize; + + if(ioctl(1, TIOCGWINSZ, &winsize) == -1) { +@@ -853,6 +861,9 @@ void sigwinch_handler() + columns = 80; + } else + columns = winsize.ws_col; ++#else ++ columns = 80; ++#endif + } + + +@@ -4066,6 +4077,9 @@ void initialise_threads(int readb_mbytes + + signal(SIGUSR1, sigusr1_handler); + ++#ifdef __CYGWIN__ ++ processors = atoi(getenv("NUMBER_OF_PROCESSORS")); ++#else + if(processors == -1) { + #ifndef linux + int mib[2]; +@@ -4087,6 +4101,7 @@ void initialise_threads(int readb_mbytes + processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif + } ++#endif /* __CYGWIN__ */ + + thread = malloc((2 + processors * 2) * sizeof(pthread_t)); + if(thread == NULL) +--- a/squashfs-tools/read_fs.c ++++ b/squashfs-tools/read_fs.c +@@ -33,9 +33,11 @@ + #include + + #ifndef linux ++#ifndef __CYGWIN__ + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN + #define __LITTLE_ENDIAN LITTLE_ENDIAN ++#endif + #else + #include + #endif +--- a/squashfs-tools/swap.c ++++ b/squashfs-tools/swap.c +@@ -20,9 +20,11 @@ + */ + + #ifndef linux ++#ifndef __CYGWIN__ + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN + #define __LITTLE_ENDIAN LITTLE_ENDIAN ++#endif + #else + #include + #endif +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -117,6 +117,7 @@ void update_progress_bar(); + + void sigwinch_handler() + { ++#ifndef __CYGWIN__ + struct winsize winsize; + + if(ioctl(1, TIOCGWINSZ, &winsize) == -1) { +@@ -126,6 +127,9 @@ void sigwinch_handler() + columns = 80; + } else + columns = winsize.ws_col; ++#else ++ columns = 80; ++#endif + } + + +@@ -1807,7 +1811,9 @@ void initialise_threads(int fragment_buf + if(sigprocmask(SIG_BLOCK, &sigmask, &old_mask) == -1) + EXIT_UNSQUASH("Failed to set signal mask in intialise_threads" + "\n"); +- ++#ifdef __CYGWIN__ ++ processors = atoi(getenv("NUMBER_OF_PROCESSORS")); ++#else + if(processors == -1) { + #ifndef linux + int mib[2]; +@@ -1829,6 +1835,7 @@ void initialise_threads(int fragment_buf + processors = sysconf(_SC_NPROCESSORS_ONLN); + #endif + } ++#endif /* __CYGWIN__ */ + + thread = malloc((3 + processors) * sizeof(pthread_t)); + if(thread == NULL) +--- a/squashfs-tools/unsquashfs.h ++++ b/squashfs-tools/unsquashfs.h +@@ -46,15 +46,22 @@ + #include + + #ifndef linux ++#ifndef __CYGWIN__ + #define __BYTE_ORDER BYTE_ORDER + #define __BIG_ENDIAN BIG_ENDIAN + #define __LITTLE_ENDIAN LITTLE_ENDIAN + #include ++#endif + #else + #include + #include + #endif + ++#ifdef __CYGWIN__ ++#include ++#define FNM_EXTMATCH (1 << 5) ++#endif ++ + #ifndef FNM_EXTMATCH + #define FNM_EXTMATCH 0 + #endif diff --git a/tools/squashfs4/patches/150-freebsd_fixes.patch b/tools/squashfs4/patches/150-freebsd_fixes.patch new file mode 100644 index 000000000..44d40a7d1 --- /dev/null +++ b/tools/squashfs4/patches/150-freebsd_fixes.patch @@ -0,0 +1,10 @@ +--- a/squashfs-tools/pseudo.c ++++ b/squashfs-tools/pseudo.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include "pseudo.h" + diff --git a/tools/squashfs4/patches/160-expose_lzma_xz_options.patch b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch new file mode 100644 index 000000000..d6063969d --- /dev/null +++ b/tools/squashfs4/patches/160-expose_lzma_xz_options.patch @@ -0,0 +1,929 @@ +--- /dev/null ++++ b/squashfs-tools/lzma_xz_options.h +@@ -0,0 +1,115 @@ ++#ifndef LZMA_XZ_OPTIONS_H ++#define LZMA_XZ_OPTIONS_H ++/* ++ * Copyright (c) 2011 ++ * Jonas Gorski ++ * ++ * This program 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 2, ++ * or (at your option) any later version. ++ * ++ * This program 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 this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * lzma_options.h ++ */ ++ ++#include ++ ++#ifndef linux ++#ifdef __FreeBSD__ ++#include ++#endif ++#define __BYTE_ORDER BYTE_ORDER ++#define __BIG_ENDIAN BIG_ENDIAN ++#define __LITTLE_ENDIAN LITTLE_ENDIAN ++#else ++#include ++#endif ++ ++ ++ ++struct lzma_opts { ++ uint32_t flags; ++#define LZMA_OPT_FLT_MASK 0xffff ++#define LZMA_OPT_PRE_OFF 16 ++#define LZMA_OPT_PRE_MASK (0xf << LZMA_OPT_PRE_OFF) ++#define LZMA_OPT_EXTREME 20 ++ uint16_t bit_opts; ++#define LZMA_OPT_LC_OFF 0 ++#define LZMA_OPT_LC_MASK (0x7 << LZMA_OPT_LC_OFF) ++#define LZMA_OPT_LP_OFF 3 ++#define LZMA_OPT_LP_MASK (0x7 << LZMA_OPT_LP_OFF) ++#define LZMA_OPT_PB_OFF 6 ++#define LZMA_OPT_PB_MASK (0x7 << LZMA_OPT_PB_OFF) ++ uint16_t fb; ++ uint32_t dict_size; ++}; ++ ++#if __BYTE_ORDER == __BIG_ENDIAN ++extern unsigned int inswap_le32(unsigned int); ++ ++#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) { \ ++ (s)->flags = inswap_le32((s)->flags); \ ++ (s)->bit_opts = inswap_le16((s)->bit_opts); \ ++ (s)->fb = inswap_le16((s)->fb); \ ++ (s)->dict_size = inswap_le32((s)->dict_size); \ ++} ++#else ++#define SQUASHFS_INSWAP_LZMA_COMP_OPTS(s) ++#endif ++ ++#define MEMLIMIT (32 * 1024 * 1024) ++ ++#define LZMA_OPT_LC_MIN 0 ++#define LZMA_OPT_LC_MAX 4 ++#define LZMA_OPT_LC_DEFAULT 3 ++ ++#define LZMA_OPT_LP_MIN 0 ++#define LZMA_OPT_LP_MAX 4 ++#define LZMA_OPT_LP_DEFAULT 0 ++ ++#define LZMA_OPT_PB_MIN 0 ++#define LZMA_OPT_PB_MAX 4 ++#define LZMA_OPT_PB_DEFAULT 2 ++ ++#define LZMA_OPT_FB_MIN 5 ++#define LZMA_OPT_FB_MAX 273 ++#define LZMA_OPT_FB_DEFAULT 64 ++ ++enum { ++ LZMA_OPT_LZMA = 1, ++ LZMA_OPT_XZ ++}; ++ ++struct lzma_xz_options { ++ int preset; ++ int extreme; ++ int lc; ++ int lp; ++ int pb; ++ int fb; ++ int dict_size; ++ int flags; ++}; ++ ++struct lzma_xz_options *lzma_xz_get_options(void); ++ ++int lzma_xz_options(char *argv[], int argc, int lzmaver); ++ ++int lzma_xz_options_post(int block_size, int lzmaver); ++ ++void *lzma_xz_dump_options(int block_size, int *size, int flags); ++ ++int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver); ++ ++void lzma_xz_usage(int lzmaver); ++ ++#endif +--- /dev/null ++++ b/squashfs-tools/lzma_xz_options.c +@@ -0,0 +1,365 @@ ++/* ++ * Copyright (c) 2011 ++ * Jonas Gorski ++ * ++ * This program 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 2, ++ * or (at your option) any later version. ++ * ++ * This program 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 this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * lzma_options.c ++ * ++ * Common options for LZMA1 and 2 compressors. Based on xz_wrapper.c ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "lzma_xz_options.h" ++ ++static const char const *lzmaver_str[] = { "", "lzma", "xz" }; ++ ++static struct lzma_xz_options options = { ++ .flags = 0, ++ .preset = 6, ++ .extreme = 0, ++ .lc = LZMA_OPT_LC_DEFAULT, ++ .lp = LZMA_OPT_LP_DEFAULT, ++ .pb = LZMA_OPT_PB_DEFAULT, ++ .fb = LZMA_OPT_FB_DEFAULT, ++ .dict_size = 0, ++}; ++ ++static float lzma_dict_percent = 0; ++ ++struct lzma_xz_options *lzma_xz_get_options(void) ++{ ++ return &options; ++} ++ ++ ++int lzma_xz_options(char *argv[], int argc, int lzmaver) ++{ ++ const char *comp_name = lzmaver_str[lzmaver]; ++ ++ if(strcmp(argv[0], "-Xpreset") == 0) { ++ int preset; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xpreset missing preset\n", comp_name); ++ goto failed; ++ } ++ ++ preset = atoi(argv[1]); ++ ++ if (preset < 0 || preset > 9) { ++ fprintf(stderr, "%s: -Xpreset invalid value\n", comp_name); ++ goto failed; ++ } ++ options.preset = preset; ++ return 1; ++ } else if(strcmp(argv[0], "-Xe") == 0) { ++ options.extreme = 1; ++ return 0; ++ } else if(strcmp(argv[0], "-Xlc") == 0) { ++ int lc; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xlc missing lc\n", comp_name); ++ goto failed; ++ } ++ ++ lc = atoi(argv[1]); ++ ++ if (lc < LZMA_OPT_LC_MIN || lc > LZMA_OPT_LC_MAX) { ++ fprintf(stderr, "%s: -Xlc invalid value\n", comp_name); ++ goto failed; ++ } ++ options.lc = lc; ++ return 1; ++ } else if(strcmp(argv[0], "-Xlp") == 0) { ++ int lp; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xlp missing lp\n", comp_name); ++ goto failed; ++ } ++ ++ lp = atoi(argv[1]); ++ ++ if (lp < LZMA_OPT_LP_MIN || lp > LZMA_OPT_LP_MAX) { ++ fprintf(stderr, "%s: -Xlp invalid value\n", comp_name); ++ goto failed; ++ } ++ options.lp = lp; ++ return 1; ++ } else if(strcmp(argv[0], "-Xpb") == 0) { ++ int pb; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xpb missing pb\n", comp_name); ++ goto failed; ++ } ++ ++ pb = atoi(argv[1]); ++ ++ if (pb < LZMA_OPT_PB_MIN || pb > LZMA_OPT_PB_MAX) { ++ fprintf(stderr, "%s: -Xbp invalid value\n", comp_name); ++ goto failed; ++ } ++ options.pb = pb; ++ return 1; ++ } else if(strcmp(argv[0], "-Xfb") == 0) { ++ int fb; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xfb missing fb\n", comp_name); ++ goto failed; ++ } ++ ++ fb = atoi(argv[1]); ++ ++ if (fb < LZMA_OPT_FB_MIN || fb > LZMA_OPT_FB_MAX) { ++ fprintf(stderr, "%s: -Xfb invalid value\n", comp_name); ++ goto failed; ++ } ++ options.fb = fb; ++ return 1; ++ } else if(strcmp(argv[0], "-Xdict-size") == 0) { ++ char *b; ++ float size; ++ ++ if(argc < 2) { ++ fprintf(stderr, "%s: -Xdict-size missing dict-size\n", comp_name); ++ goto failed; ++ } ++ ++ size = strtof(argv[1], &b); ++ if(*b == '%') { ++ if(size <= 0 || size > 100) { ++ fprintf(stderr, "%s: -Xdict-size percentage " ++ "should be 0 < dict-size <= 100\n", comp_name); ++ goto failed; ++ } ++ ++ lzma_dict_percent = size; ++ options.dict_size = 0; ++ } else { ++ if((float) ((int) size) != size) { ++ fprintf(stderr, "%s: -Xdict-size can't be " ++ "fractional unless a percentage of the" ++ " block size\n", comp_name); ++ goto failed; ++ } ++ ++ lzma_dict_percent = 0; ++ options.dict_size = (int) size; ++ ++ if(*b == 'k' || *b == 'K') ++ options.dict_size *= 1024; ++ else if(*b == 'm' || *b == 'M') ++ options.dict_size *= 1024 * 1024; ++ else if(*b != '\0') { ++ fprintf(stderr, "%s: -Xdict-size invalid " ++ "dict-size\n", comp_name); ++ goto failed; ++ } ++ } ++ ++ return 1; ++ } ++ ++ return -1; ++ ++failed: ++ return -2; ++ ++} ++ ++int lzma_xz_options_post(int block_size, int lzmaver) ++{ ++ const char *comp_name = lzmaver_str[lzmaver]; ++ /* ++ * if -Xdict-size has been specified use this to compute the datablock ++ * dictionary size ++ */ ++ if(options.dict_size || lzma_dict_percent) { ++ int dict_size_min = (lzmaver == 1 ? 4096 : 8192); ++ int n; ++ ++ if(options.dict_size) { ++ if(options.dict_size > block_size) { ++ fprintf(stderr, "%s: -Xdict-size is larger than" ++ " block_size\n", comp_name); ++ goto failed; ++ } ++ } else ++ options.dict_size = block_size * lzma_dict_percent / 100; ++ ++ if(options.dict_size < dict_size_min) { ++ fprintf(stderr, "%s: -Xdict-size should be %i bytes " ++ "or larger\n", comp_name, dict_size_min); ++ goto failed; ++ } ++ ++ /* ++ * dictionary_size must be storable in xz header as either ++ * 2^n or as 2^n+2^(n+1) ++ */ ++ n = ffs(options.dict_size) - 1; ++ if(options.dict_size != (1 << n) && ++ options.dict_size != ((1 << n) + (1 << (n + 1)))) { ++ fprintf(stderr, "%s: -Xdict-size is an unsupported " ++ "value, dict-size must be storable in %s " ++ "header\n", comp_name, comp_name); ++ fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " ++ "Example dict-sizes are 75%%, 50%%, 37.5%%, " ++ "25%%,\n"); ++ fprintf(stderr, "or 32K, 16K, 8K etc.\n"); ++ goto failed; ++ } ++ ++ } else ++ /* No -Xdict-size specified, use defaults */ ++ options.dict_size = block_size; ++ ++ return 0; ++ ++failed: ++ return -1; ++} ++ ++static struct lzma_opts lzma_comp_opts; ++ ++void *lzma_xz_dump_options(int block_size, int *size, int flags) ++{ ++ /* No need to store default options */ ++ if (options.preset == 6 && ++ options.extreme == 0 && ++ options.lc == LZMA_OPT_LC_DEFAULT && ++ options.lp == LZMA_OPT_LC_DEFAULT && ++ options.pb == LZMA_OPT_PB_DEFAULT && ++ options.fb == 0 && ++ options.dict_size == block_size && ++ flags == 0) ++ return NULL; ++ ++ *size = sizeof(struct lzma_opts); ++ ++ lzma_comp_opts.flags |= flags; ++ ++ if (options.extreme) ++ lzma_comp_opts.flags |= LZMA_OPT_EXTREME; ++ ++ lzma_comp_opts.flags |= ((options.preset << LZMA_OPT_PRE_OFF) & LZMA_OPT_PRE_MASK); ++ ++ lzma_comp_opts.bit_opts = ++ ((options.lc << LZMA_OPT_LC_OFF) & LZMA_OPT_LC_MASK) | ++ ((options.lp << LZMA_OPT_LP_OFF) & LZMA_OPT_LP_MASK) | ++ ((options.pb << LZMA_OPT_PB_OFF) & LZMA_OPT_PB_MASK); ++ lzma_comp_opts.fb = options.fb; ++ lzma_comp_opts.dict_size = options.dict_size; ++ ++ SQUASHFS_INSWAP_LZMA_COMP_OPTS(&lzma_comp_opts); ++ ++ return &lzma_comp_opts; ++} ++ ++int lzma_xz_extract_options(int block_size, void *buffer, int size, int lzmaver) ++{ ++ if (size == 0) { ++ /* default options */ ++ options.preset = 6; ++ options.extreme = 0; ++ options.lc = LZMA_OPT_LC_DEFAULT; ++ options.lp = LZMA_OPT_LC_DEFAULT; ++ options.pb = LZMA_OPT_PB_DEFAULT; ++ options.fb = LZMA_OPT_FB_DEFAULT; ++ options.dict_size = block_size; ++ options.flags = 0; ++ } else { ++ struct lzma_opts *comp_opts = buffer; ++ int n; ++ ++ if (size != sizeof(struct lzma_opts)) ++ goto failed; ++ ++ SQUASHFS_INSWAP_LZMA_COMP_OPTS(comp_opts); ++ ++ options.flags = comp_opts->flags & LZMA_OPT_FLT_MASK; ++ options.preset = (comp_opts->flags & LZMA_OPT_PRE_MASK) >> LZMA_OPT_PRE_OFF; ++ options.extreme = !!(comp_opts->flags & LZMA_OPT_EXTREME); ++ ++ options.lc = (comp_opts->bit_opts & LZMA_OPT_LC_MASK) >> LZMA_OPT_LC_OFF; ++ options.lp = (comp_opts->bit_opts & LZMA_OPT_LP_MASK) >> LZMA_OPT_LP_OFF; ++ options.pb = (comp_opts->bit_opts & LZMA_OPT_PB_MASK) >> LZMA_OPT_PB_OFF; ++ options.fb = comp_opts->fb; ++ options.dict_size = comp_opts->dict_size; ++ ++ /* check that the LZMA bit options are in range */ ++ if (options.lc < LZMA_OPT_LC_MIN || options.lc > LZMA_OPT_LC_MAX || ++ options.lp < LZMA_OPT_LP_MIN || options.lp > LZMA_OPT_LP_MAX || ++ options.pb < LZMA_OPT_PB_MIN || options.pb > LZMA_OPT_PB_MAX || ++ options.fb < LZMA_OPT_FB_MIN || options.fb > LZMA_OPT_FB_MAX) ++ goto failed; ++ ++ /* ++ * check that the dictionary size seems correct - the dictionary ++ * size should 2^n or 2^n+2^(n+1) ++ */ ++ n = ffs(options.dict_size) - 1; ++ if(options.dict_size != (1 << n) && ++ options.dict_size != ((1 << n) + (1 << (n + 1)))) ++ goto failed; ++ ++ } ++ ++ return 0; ++ ++failed: ++ fprintf(stderr, "%s: error reading stored compressor options from " ++ "filesystem!\n", lzmaver_str[lzmaver]); ++ return -1; ++} ++ ++void lzma_xz_usage(int lzmaver) ++{ ++ fprintf(stderr, "\t -Xpreset \n"); ++ fprintf(stderr, "\t\tcompression preset (0-9, default 6)\n"); ++ fprintf(stderr, "\t -Xe\n"); ++ fprintf(stderr, "\t\tTry to improve compression ratio by using more "); ++ fprintf(stderr, "CPU time.\n"); ++ fprintf(stderr, "\t -Xlc \n"); ++ fprintf(stderr, "\t\tNumber of literal context bits (0-4, default 3)\n"); ++ fprintf(stderr, "\t -Xlp \n"); ++ fprintf(stderr, "\t\tNumber of literal position bits (0-4, default 0)\n"); ++ fprintf(stderr, "\t -Xpb \n"); ++ fprintf(stderr, "\t\tNumber of position bits (0-4, default 2)\n"); ++ fprintf(stderr, "\t -Xnice \n"); ++ fprintf(stderr, "\t\tNice length of a match (5-273, default 64)\n"); ++ fprintf(stderr, "\t -Xdict-size \n"); ++ fprintf(stderr, "\t\tUse as the %s dictionary size. The", ++ lzmaver == LZMA_OPT_LZMA ? "LZMA" : "XZ"); ++ fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); ++ fprintf(stderr, " percentage of the block size, or as an\n\t\t"); ++ fprintf(stderr, "absolute value. The dictionary size must be less"); ++ fprintf(stderr, " than or equal\n\t\tto the block size and %d bytes", ++ lzmaver == LZMA_OPT_LZMA ? 4096 : 8192); ++ fprintf(stderr, " or larger. It must also be\n\t\tstorable in the lzma"); ++ fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); ++ fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); ++ fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); ++ ++} +--- a/squashfs-tools/lzma_xz_wrapper.c ++++ b/squashfs-tools/lzma_xz_wrapper.c +@@ -27,6 +27,7 @@ + + #include "squashfs_fs.h" + #include "compressor.h" ++#include "lzma_xz_options.h" + + #define LZMA_PROPS_SIZE 5 + #define LZMA_UNCOMP_SIZE 8 +@@ -38,13 +39,27 @@ + static int lzma_compress(void *dummy, void *dest, void *src, int size, + int block_size, int *error) + { ++ uint32_t preset; + unsigned char *d = (unsigned char *) dest; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); ++ + lzma_options_lzma opt; + lzma_stream strm = LZMA_STREAM_INIT; + int res; + +- lzma_lzma_preset(&opt, LZMA_OPTIONS); +- opt.dict_size = block_size; ++ preset = opts->preset; ++ ++ if (opts->extreme) ++ preset |= LZMA_PRESET_EXTREME; ++ ++ lzma_lzma_preset(&opt, opts->preset); ++ opt.lc = opts->lc; ++ opt.lp = opts->lp; ++ opt.pb = opts->pb; ++ if (opts->fb) ++ opt.nice_len = opts->fb; ++ ++ opt.dict_size = opts->dict_size; + + res = lzma_alone_encoder(&strm, &opt); + if(res != LZMA_OK) { +@@ -143,13 +158,45 @@ failed: + return -1; + } + ++static int lzma_options(char *argv[], int argc) ++{ ++ return lzma_xz_options(argv, argc, LZMA_OPT_LZMA); ++} ++ ++ ++static int lzma_options_post(int block_size) ++{ ++ return lzma_xz_options_post(block_size, LZMA_OPT_LZMA); ++} ++ ++ ++static void *lzma_dump_options(int block_size, int *size) ++{ ++ return lzma_xz_dump_options(block_size, size, 0); ++} ++ ++ ++static int lzma_extract_options(int block_size, void *buffer, int size) ++{ ++ return lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_LZMA); ++} ++ ++ ++void lzma_usage() ++{ ++ lzma_xz_usage(LZMA_OPT_LZMA); ++} ++ + + struct compressor lzma_comp_ops = { + .init = NULL, + .compress = lzma_compress, + .uncompress = lzma_uncompress, +- .options = NULL, +- .usage = NULL, ++ .options = lzma_options, ++ .options_post = lzma_options_post, ++ .dump_options = lzma_dump_options, ++ .extract_options = lzma_extract_options, ++ .usage = lzma_usage, + .id = LZMA_COMPRESSION, + .name = "lzma", + .supported = 1 +--- a/squashfs-tools/xz_wrapper.h ++++ b/squashfs-tools/xz_wrapper.h +@@ -24,25 +24,6 @@ + * + */ + +-#ifndef linux +-#define __BYTE_ORDER BYTE_ORDER +-#define __BIG_ENDIAN BIG_ENDIAN +-#define __LITTLE_ENDIAN LITTLE_ENDIAN +-#else +-#include +-#endif +- +-#if __BYTE_ORDER == __BIG_ENDIAN +-extern unsigned int inswap_le32(unsigned int); +- +-#define SQUASHFS_INSWAP_COMP_OPTS(s) { \ +- (s)->dictionary_size = inswap_le32((s)->dictionary_size); \ +- (s)->flags = inswap_le32((s)->flags); \ +-} +-#else +-#define SQUASHFS_INSWAP_COMP_OPTS(s) +-#endif +- + #define MEMLIMIT (32 * 1024 * 1024) + + struct bcj { +--- a/squashfs-tools/xz_wrapper.c ++++ b/squashfs-tools/xz_wrapper.c +@@ -30,6 +30,7 @@ + #include "squashfs_fs.h" + #include "xz_wrapper.h" + #include "compressor.h" ++#include "lzma_xz_options.h" + + static struct bcj bcj[] = { + { "x86", LZMA_FILTER_X86, 0 }, +@@ -41,22 +42,18 @@ static struct bcj bcj[] = { + { NULL, LZMA_VLI_UNKNOWN, 0 } + }; + +-static struct comp_opts comp_opts; +- + static int filter_count = 1; +-static int dictionary_size = 0; +-static float dictionary_percent = 0; + + + static int xz_options(char *argv[], int argc) + { +- int i; +- char *name; +- + if(strcmp(argv[0], "-Xbcj") == 0) { ++ int i; ++ char *name; ++ + if(argc < 2) { + fprintf(stderr, "xz: -Xbcj missing filter\n"); +- goto failed; ++ return -2; + } + + name = argv[1]; +@@ -76,190 +73,50 @@ static int xz_options(char *argv[], int + } + if(bcj[i].name == NULL) { + fprintf(stderr, "xz: -Xbcj unrecognised " +- "filter\n"); +- goto failed; +- } +- } +- +- return 1; +- } else if(strcmp(argv[0], "-Xdict-size") == 0) { +- char *b; +- float size; +- +- if(argc < 2) { +- fprintf(stderr, "xz: -Xdict-size missing dict-size\n"); +- goto failed; +- } +- +- size = strtof(argv[1], &b); +- if(*b == '%') { +- if(size <= 0 || size > 100) { +- fprintf(stderr, "xz: -Xdict-size percentage " +- "should be 0 < dict-size <= 100\n"); +- goto failed; +- } +- +- dictionary_percent = size; +- dictionary_size = 0; +- } else { +- if((float) ((int) size) != size) { +- fprintf(stderr, "xz: -Xdict-size can't be " +- "fractional unless a percentage of the" +- " block size\n"); +- goto failed; +- } +- +- dictionary_percent = 0; +- dictionary_size = (int) size; +- +- if(*b == 'k' || *b == 'K') +- dictionary_size *= 1024; +- else if(*b == 'm' || *b == 'M') +- dictionary_size *= 1024 * 1024; +- else if(*b != '\0') { +- fprintf(stderr, "xz: -Xdict-size invalid " +- "dict-size\n"); +- goto failed; ++ "filter\n"); ++ return -2; + } + } +- + return 1; ++ } else { ++ return lzma_xz_options(argv, argc, LZMA_OPT_XZ); + } +- +- return -1; +- +-failed: +- return -2; + } + + + static int xz_options_post(int block_size) + { +- /* +- * if -Xdict-size has been specified use this to compute the datablock +- * dictionary size +- */ +- if(dictionary_size || dictionary_percent) { +- int n; +- +- if(dictionary_size) { +- if(dictionary_size > block_size) { +- fprintf(stderr, "xz: -Xdict-size is larger than" +- " block_size\n"); +- goto failed; +- } +- } else +- dictionary_size = block_size * dictionary_percent / 100; +- +- if(dictionary_size < 8192) { +- fprintf(stderr, "xz: -Xdict-size should be 8192 bytes " +- "or larger\n"); +- goto failed; +- } +- +- /* +- * dictionary_size must be storable in xz header as either +- * 2^n or as 2^n+2^(n+1) +- */ +- n = ffs(dictionary_size) - 1; +- if(dictionary_size != (1 << n) && +- dictionary_size != ((1 << n) + (1 << (n + 1)))) { +- fprintf(stderr, "xz: -Xdict-size is an unsupported " +- "value, dict-size must be storable in xz " +- "header\n"); +- fprintf(stderr, "as either 2^n or as 2^n+2^(n+1). " +- "Example dict-sizes are 75%%, 50%%, 37.5%%, " +- "25%%,\n"); +- fprintf(stderr, "or 32K, 16K, 8K etc.\n"); +- goto failed; +- } +- +- } else +- /* No -Xdict-size specified, use defaults */ +- dictionary_size = block_size; +- +- return 0; +- +-failed: +- return -1; ++ return lzma_xz_options_post(block_size, LZMA_OPT_XZ); + } + + + static void *xz_dump_options(int block_size, int *size) + { +- int flags = 0, i; +- +- /* +- * don't store compressor specific options in file system if the +- * default options are being used - no compressor options in the +- * file system means the default options are always assumed +- * +- * Defaults are: +- * metadata dictionary size: SQUASHFS_METADATA_SIZE +- * datablock dictionary size: block_size +- * 1 filter +- */ +- if(dictionary_size == block_size && filter_count == 1) +- return NULL; ++ int i, flags = 0; + + for(i = 0; bcj[i].name; i++) + flags |= bcj[i].selected << i; + +- comp_opts.dictionary_size = dictionary_size; +- comp_opts.flags = flags; +- +- SQUASHFS_INSWAP_COMP_OPTS(&comp_opts); +- +- *size = sizeof(comp_opts); +- return &comp_opts; ++ return lzma_xz_dump_options(block_size, size, flags); + } + + + static int xz_extract_options(int block_size, void *buffer, int size) + { +- struct comp_opts *comp_opts = buffer; +- int flags, i, n; +- +- if(size == 0) { +- /* set defaults */ +- dictionary_size = block_size; +- flags = 0; +- } else { +- /* check passed comp opts struct is of the correct length */ +- if(size != sizeof(struct comp_opts)) +- goto failed; +- +- SQUASHFS_INSWAP_COMP_OPTS(comp_opts); +- +- dictionary_size = comp_opts->dictionary_size; +- flags = comp_opts->flags; +- +- /* +- * check that the dictionary size seems correct - the dictionary +- * size should 2^n or 2^n+2^(n+1) +- */ +- n = ffs(dictionary_size) - 1; +- if(dictionary_size != (1 << n) && +- dictionary_size != ((1 << n) + (1 << (n + 1)))) +- goto failed; +- } ++ int ret = lzma_xz_extract_options(block_size, buffer, size, LZMA_OPT_XZ); + +- filter_count = 1; +- for(i = 0; bcj[i].name; i++) { +- if((flags >> i) & 1) { +- bcj[i].selected = 1; +- filter_count ++; +- } else +- bcj[i].selected = 0; ++ if (!ret) { ++ int i; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); ++ for(i = 0; bcj[i].name; i++) { ++ if((opts->flags >> i) & 1) { ++ bcj[i].selected = 1; ++ filter_count ++; ++ } else ++ bcj[i].selected = 0; ++ } + } +- +- return 0; +- +-failed: +- fprintf(stderr, "xz: error reading stored compressor options from " +- "filesystem!\n"); +- +- return -1; ++ return ret; + } + + +@@ -268,6 +125,7 @@ static int xz_init(void **strm, int bloc + int i, j, filters = datablock ? filter_count : 1; + struct filter *filter = malloc(filters * sizeof(struct filter)); + struct xz_stream *stream; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); + + if(filter == NULL) + goto failed; +@@ -281,7 +139,7 @@ static int xz_init(void **strm, int bloc + + memset(filter, 0, filters * sizeof(struct filter)); + +- stream->dictionary_size = datablock ? dictionary_size : ++ stream->dictionary_size = datablock ? opts->dict_size : + SQUASHFS_METADATA_SIZE; + + filter[0].filter[0].id = LZMA_FILTER_LZMA2; +@@ -323,14 +181,25 @@ static int xz_compress(void *strm, void + lzma_ret res = 0; + struct xz_stream *stream = strm; + struct filter *selected = NULL; ++ struct lzma_xz_options *opts = lzma_xz_get_options(); + + stream->filter[0].buffer = dest; + + for(i = 0; i < stream->filters; i++) { ++ uint32_t preset = opts->preset; + struct filter *filter = &stream->filter[i]; + +- if(lzma_lzma_preset(&stream->opt, LZMA_PRESET_DEFAULT)) +- goto failed; ++ if (opts->extreme) ++ preset |= LZMA_PRESET_EXTREME; ++ ++ if(lzma_lzma_preset(&stream->opt, preset)) ++ goto failed; ++ ++ stream->opt.lc = opts->lc; ++ stream->opt.lp = opts->lp; ++ stream->opt.pb = opts->pb; ++ if (opts->fb) ++ stream->opt.nice_len = opts->fb; + + stream->opt.dict_size = stream->dictionary_size; + +@@ -384,22 +253,13 @@ static int xz_uncompress(void *dest, voi + + void xz_usage() + { ++ lzma_xz_usage(LZMA_OPT_XZ); + fprintf(stderr, "\t -Xbcj filter1,filter2,...,filterN\n"); + fprintf(stderr, "\t\tCompress using filter1,filter2,...,filterN in"); + fprintf(stderr, " turn\n\t\t(in addition to no filter), and choose"); + fprintf(stderr, " the best compression.\n"); + fprintf(stderr, "\t\tAvailable filters: x86, arm, armthumb,"); + fprintf(stderr, " powerpc, sparc, ia64\n"); +- fprintf(stderr, "\t -Xdict-size \n"); +- fprintf(stderr, "\t\tUse as the XZ dictionary size. The"); +- fprintf(stderr, " dictionary size\n\t\tcan be specified as a"); +- fprintf(stderr, " percentage of the block size, or as an\n\t\t"); +- fprintf(stderr, "absolute value. The dictionary size must be less"); +- fprintf(stderr, " than or equal\n\t\tto the block size and 8192 bytes"); +- fprintf(stderr, " or larger. It must also be\n\t\tstorable in the xz"); +- fprintf(stderr, " header as either 2^n or as 2^n+2^(n+1).\n\t\t"); +- fprintf(stderr, "Example dict-sizes are 75%%, 50%%, 37.5%%, 25%%, or"); +- fprintf(stderr, " 32K, 16K, 8K\n\t\tetc.\n"); + } + + +--- a/squashfs-tools/Makefile ++++ b/squashfs-tools/Makefile +@@ -140,6 +140,8 @@ COMPRESSORS += xz + endif + + ifneq ($(LZMA_XZ_SUPPORT)$(XZ_SUPPORT),) ++MKSQUASHFS_OBJS += lzma_xz_options.o ++UNSQUASHFS_OBJS += lzma_xz_options.o + ifneq ($(LZMA_LIB),) + MKSQUASHFS_OBJS += $(LZMA_LIB) + UNSQUASHFS_OBJS += $(LZMA_LIB) diff --git a/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch b/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch new file mode 100644 index 000000000..ad69b190e --- /dev/null +++ b/tools/squashfs4/patches/170-add_support_for_LZMA_MAGIC_to_unsqashfs.patch @@ -0,0 +1,72 @@ +--- a/squashfs-tools/squashfs_fs.h ++++ b/squashfs-tools/squashfs_fs.h +@@ -30,6 +30,13 @@ + #define SQUASHFS_MAGIC_SWAP 0x68737173 + #define SQUASHFS_START 0 + ++/* ++ * Squashfs + LZMA ++ */ ++ ++#define SQUASHFS_MAGIC_LZMA 0x71736873 ++#define SQUASHFS_MAGIC_LZMA_SWAP 0x73687371 ++ + /* size of metadata (inode and directory) blocks */ + #define SQUASHFS_METADATA_SIZE 8192 + #define SQUASHFS_METADATA_LOG 13 +--- a/squashfs-tools/unsquashfs.c ++++ b/squashfs-tools/unsquashfs.c +@@ -1463,10 +1463,12 @@ int read_super(char *source) + */ + read_fs_bytes(fd, SQUASHFS_START, sizeof(struct squashfs_super_block), + &sBlk_4); +- swap = sBlk_4.s_magic != SQUASHFS_MAGIC; ++ swap = (sBlk_4.s_magic != SQUASHFS_MAGIC && ++ sBlk_4.s_magic != SQUASHFS_MAGIC_LZMA); + SQUASHFS_INSWAP_SUPER_BLOCK(&sBlk_4); + +- if(sBlk_4.s_magic == SQUASHFS_MAGIC && sBlk_4.s_major == 4 && ++ if((sBlk_4.s_magic == SQUASHFS_MAGIC || ++ sBlk_4.s_magic == SQUASHFS_MAGIC_LZMA) && sBlk_4.s_major == 4 && + sBlk_4.s_minor == 0) { + s_ops.squashfs_opendir = squashfs_opendir_4; + s_ops.read_fragment = read_fragment_4; +@@ -1479,7 +1481,11 @@ int read_super(char *source) + /* + * Check the compression type + */ +- comp = lookup_compressor_id(sBlk.s.compression); ++ if (sBlk_4.s_magic == SQUASHFS_MAGIC_LZMA) ++ comp = lookup_compressor("lzma"); ++ else ++ comp = lookup_compressor_id(sBlk.s.compression); ++ + return TRUE; + } + +@@ -1494,8 +1500,10 @@ int read_super(char *source) + * Check it is a SQUASHFS superblock + */ + swap = 0; +- if(sBlk_3.s_magic != SQUASHFS_MAGIC) { +- if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP) { ++ if(sBlk_3.s_magic != SQUASHFS_MAGIC && ++ sBlk_3.s_magic != SQUASHFS_MAGIC_LZMA) { ++ if(sBlk_3.s_magic == SQUASHFS_MAGIC_SWAP || ++ sBlk_3.s_magic == SQUASHFS_MAGIC_LZMA_SWAP) { + squashfs_super_block_3 sblk; + ERROR("Reading a different endian SQUASHFS filesystem " + "on %s\n", source); +@@ -1573,7 +1581,11 @@ int read_super(char *source) + /* + * 1.x, 2.x and 3.x filesystems use gzip compression. + */ +- comp = lookup_compressor("gzip"); ++ if (sBlk.s.s_magic == SQUASHFS_MAGIC_LZMA) ++ comp = lookup_compressor("lzma"); ++ else ++ comp = lookup_compressor("gzip"); ++ + return TRUE; + + failed_mount: -- cgit v1.2.3