Page MenuHomeFreeBSD

D58073.diff
No OneTemporary

D58073.diff

diff --git a/stand/defs.mk b/stand/defs.mk
--- a/stand/defs.mk
+++ b/stand/defs.mk
@@ -190,6 +190,11 @@
# ZSTD client cflags
ZSTD_CFLAGS=-I${SYSDIR}/contrib/zstd/lib
+# XZ flags
+XZ_DIR=${SRCTOP}/sys/contrib/xz-embedded
+XZ_CFLAGS=-DXZ_USE_CRC64 -I${XZ_DIR}/freebsd -I${XZ_DIR}/linux/include/linux
+
+
# The boot loader build uses dd status=none, where possible, for reproducible
# build output (since performance varies from run to run). Trouble is that
# option was recently (10.3) added to FreeBSD and is non-standard. Only use it
diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile
--- a/stand/efi/loader/Makefile
+++ b/stand/efi/loader/Makefile
@@ -47,7 +47,7 @@
CFLAGS.bootinfo.c += -I$(SRCTOP)/sys/teken
CFLAGS.bootinfo.c += -I${SRCTOP}/contrib/pnglite
-CFLAGS.decompress.c += ${ZLIB_CFLAGS} ${BZIP2_CFLAGS} ${ZSTD_CFLAGS}
+CFLAGS.decompress.c += ${ZLIB_CFLAGS} ${BZIP2_CFLAGS} ${ZSTD_CFLAGS} ${XZ_CFLAGS}
CFLAGS.framebuffer.c += -I$(SRCTOP)/sys/teken
CFLAGS.framebuffer.c += -I${SRCTOP}/contrib/pnglite
CFLAGS.main.c += -I$(SRCTOP)/sys/teken
diff --git a/stand/efi/loader/decompress.h b/stand/efi/loader/decompress.h
--- a/stand/efi/loader/decompress.h
+++ b/stand/efi/loader/decompress.h
@@ -6,7 +6,7 @@
#pragma once
-enum compression { none, zlib, bzip2, zstd };
+enum compression { none, zlib, bzip2, xz, zstd };
enum step_return { ok, done, err };
typedef struct decomp_state decomp_state;
diff --git a/stand/efi/loader/decompress.c b/stand/efi/loader/decompress.c
--- a/stand/efi/loader/decompress.c
+++ b/stand/efi/loader/decompress.c
@@ -11,7 +11,8 @@
#include <zlib.h>
#include <bzlib.h>
-#ifdef LOADER_ZFS_SUPPORT /* ZSTD only available with ZFS */
+#include <xz.h>
+#ifdef LOADER_ZFS_SUPPORT /* ZSTD and lzma only available with ZFS */
#include <zstd.h>
#endif
#include <sys/_param.h>
@@ -32,6 +33,7 @@
union {
z_stream zstrm;
bz_stream bzstrm;
+ struct xz_dec *xzstrm;
#ifdef LOADER_ZFS_SUPPORT
ZSTD_DStream *zstdstrm;
#endif
@@ -63,10 +65,10 @@
return (zstd);
}
if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) {
- printf("xz -- unsupproted\n");
- } else {
- printf("Not compressed\n");
+ printf("xz\n");
+ return (xz);
}
+ printf("Not compressed\n");
return (none);
}
@@ -220,7 +222,7 @@
if (ret == BZ_STREAM_END)
return (done);
- if (ret != Z_OK)
+ if (ret != BZ_OK)
return (err);
if (dctx->buf_cur < dctx->buf_end) /* Have output space */
return (ok);
@@ -247,6 +249,90 @@
free_buffer(dctx);
}
+/*
+ * XZ support
+ */
+static EFI_STATUS
+xz_init(decomp_state *dctx, uint8_t *first_buf, size_t buflen, size_t size_hint)
+{
+ /*
+ * Assume 4x compression, but start at 64MB
+ */
+ dctx->size = max(size_hint * 4, M(64));
+ EFI_STATUS status = alloc_buffer(dctx, dctx->size);
+ if (EFI_ERROR(status))
+ return (status);
+ xz_crc32_init();
+ xz_crc64_init();
+ dctx->xzstrm = xz_dec_init(XZ_DYNALLOC, (uint32_t)-1);
+ return (dctx->xzstrm != NULL ? EFI_SUCCESS : EFI_VOLUME_CORRUPTED);
+}
+
+
+static enum step_return
+xz_step(decomp_state *dctx, uint8_t *buf, size_t len, size_t offset)
+{
+ struct xz_dec *strm = dctx->xzstrm;
+ size_t outlen = dctx->buf_end - dctx->buf_cur;
+ struct xz_buf b = { .in = buf, .in_size = len, .in_pos = 0,
+ .out = dctx->buf_cur, .out_size = outlen, .out_pos = 0 };
+ int ret;
+
+ ret = xz_dec_run(strm, &b);
+ dctx->buf_cur += b.out_pos;
+
+ if (ret == XZ_STREAM_END)
+ return (done);
+ if (ret != XZ_OK) {
+ switch(ret) {
+ case XZ_MEM_ERROR:
+ printf("xz no memory ");
+ break;
+ case XZ_DATA_ERROR:
+ printf("xz file corrupted ");
+ break;
+ case XZ_FORMAT_ERROR:
+ printf("xz format not found ");
+ break;
+ case XZ_OPTIONS_ERROR:
+ printf("unsupported xz option ");
+ break;
+ case XZ_MEMLIMIT_ERROR:
+ printf("xz dictionary too small ");
+ break;
+ default:
+ printf("xz step error %d ", ret);
+ break;
+ }
+ printf(" len %d offset %d\n", (int)len, (int)offset);
+ return (err);
+ }
+ if (dctx->buf_cur < dctx->buf_end) /* Have output space */
+ return (ok);
+
+ /*
+ * We're out of space, grow the buffer and try again if there's buffer
+ * space. We try again recursively since we know that will usually go
+ * only 1 deep.
+ */
+ if (EFI_ERROR(grow_buffer(dctx)))
+ return (err);
+ if (b.in_pos == b.in_size)
+ return (ok);
+ size_t consumed = b.in_pos;
+ return (xz_step(dctx, buf + consumed, len - consumed, offset + consumed));
+}
+
+static void
+xz_fini(decomp_state *dctx, bool flush)
+{
+ xz_dec_end(dctx->xzstrm);
+ dctx->xzstrm = NULL;
+ if (!flush)
+ return;
+ free_buffer(dctx);
+}
+
/*
* ZSTD supprot
*/
@@ -373,6 +459,11 @@
dctx->step = bzip2_step;
dctx->fini = bzip2_fini;
break;
+ case xz:
+ dctx->init = xz_init;
+ dctx->step = xz_step;
+ dctx->fini = xz_fini;
+ break;
#ifdef LOADER_ZFS_SUPPORT
case zstd:
dctx->init = zstd_init;
diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile
--- a/stand/libsa/Makefile
+++ b/stand/libsa/Makefile
@@ -110,6 +110,13 @@
SRCS+= lz4.c
CFLAGS.lz4.c+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4
+# xz decompression
+.PATH: ${XZ_DIR}/linux/lib/xz
+.for i in xz_crc32.c xz_crc64.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c xz.c
+CFLAGS.${i}+=${XZ_CFLAGS}
+SRCS+= ${i}
+.endfor
+
# io routines
SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c mount.c \
fstat.c close.c lseek.c open.c read.c write.c readdir.c preload.c
diff --git a/sys/contrib/xz-embedded/freebsd/xz_config.h b/sys/contrib/xz-embedded/freebsd/xz_config.h
--- a/sys/contrib/xz-embedded/freebsd/xz_config.h
+++ b/sys/contrib/xz-embedded/freebsd/xz_config.h
@@ -27,10 +27,17 @@
#ifndef __FREEBSD_XZ_CONFIG_H__
#define __FREEBSD_XZ_CONFIG_H__
+#if defined(_KERNEL)
#include <sys/param.h>
#include <sys/endian.h>
#include <sys/types.h>
#include <sys/systm.h>
+#elif defined(_STANDALONE)
+#include "stand.h"
+#include <sys/param.h>
+#else
+/* nothing */
+#endif
#include <contrib/xz-embedded/linux/include/linux/xz.h>
#include "xz_malloc.h"
@@ -61,10 +68,6 @@
#define memeq(a, b, size) (memcmp((a), (b), (size)) == 0)
#define memzero(buf, size) bzero((buf), (size))
-#ifndef min
-# define min(x, y) MIN((x), (y))
-#endif
-
#define min_t(type, x, y) min((x), (y))
#define get_le32(ptr) le32toh(*(const uint32_t *)(ptr))

File Metadata

Mime Type
text/plain
Expires
Sun, Jul 12, 2:56 AM (10 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34966035
Default Alt Text
D58073.diff (6 KB)

Event Timeline