Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162229473
D58073.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D58073.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D58073: loader.efi: Add xz decompression
Attached
Detach File
Event Timeline
Log In to Comment